changeset 234:3c2f7afc4931 Implementation_of_communication

NetworkJungleBulletinBoard bug fix
author tatsuki
date Sun, 24 Jan 2016 16:25:49 +0900
parents 036c64abd618
children faa9fa06ead1
files src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/bbs/NetworkJungleBulletinBoard.java
diffstat 1 files changed, 583 insertions(+), 600 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/bbs/NetworkJungleBulletinBoard.java	Sun Jan 24 11:11:28 2016 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/bbs/NetworkJungleBulletinBoard.java	Sun Jan 24 16:25:49 2016 +0900
@@ -36,671 +36,654 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 public class NetworkJungleBulletinBoard implements NetworkBulletinBoard {
-  protected final Jungle jungle;
-  private final NetworkJournal journal;
-  private final String LOG_DIR;
-  private Boolean persistentFlag;
-  private AtomicInteger requestCounter;
-  private long renewTime;
-
-  private NetworkJungleBulletinBoard(String _uuid, NetworkJournal _journal) {
-    journal = _journal;
-    jungle = new NetworkDefaultJungle(journal, _uuid, new DefaultTreeEditor(new DefaultTraverser()));
-    BulletinBoardJungleManager.setJungle(jungle);
-    persistentFlag = false;
-    requestCounter = BulletinBoardJungleManager.getRequestCounter();
-    LOG_DIR = "./log";
-    renewTime = 0;
-  }
-
-  public NetworkJungleBulletinBoard(String _uuid) {
-    this(_uuid, new AliceJournal());
-    jungle.createNewTree("boards");
-  }
+    protected final Jungle jungle;
+    private final NetworkJournal journal;
+    private final String LOG_DIR;
+    private Boolean persistentFlag;
+    private AtomicInteger requestCounter;
+    private long renewTime;
 
-  public static NetworkBulletinBoard NewPersistentJungle(String _uuid) {
-    NetworkJungleBulletinBoard board = new NetworkJungleBulletinBoard(_uuid, new PersistentJournal());
-    board.persistentFlag = true;
-    return board;
-  }
-
-  public void init() {
-    if (!persistentFlag) {
-      return;
+    private NetworkJungleBulletinBoard(String _uuid, NetworkJournal _journal) {
+        journal = _journal;
+        jungle = new NetworkDefaultJungle(journal, _uuid, new DefaultTreeEditor(new DefaultTraverser()));
+        BulletinBoardJungleManager.setJungle(jungle);
+        persistentFlag = false;
+        requestCounter = BulletinBoardJungleManager.getRequestCounter();
+        LOG_DIR = "./log";
+        renewTime = 0;
     }
-    checkAndCreateLogDirectory();
-    try {
-      commitLogRecover();
-    } catch (IOException e) {
-      e.printStackTrace();
-    }
-  }
-
-  public void checkAndCreateLogDirectory() {
-    File logFile = new File(LOG_DIR);
-    if (!logFile.exists()) {
-      logFile.mkdir();
-      return;
-    }
-    if (logFile.isFile()) {
-      logFile.delete();
-      logFile.mkdir();
-    }
-  }
 
-  public void commitLogRecover() throws IOException {
-    File[] logFiles = new File(LOG_DIR).listFiles();
-    for (File logFile : logFiles) {
-      commitLogRecover(logFile);
-      logFile.delete();
+    public NetworkJungleBulletinBoard(String _uuid) {
+        this(_uuid, new AliceJournal());
+        jungle.createNewTree("boards");
     }
-    if (jungle.getTreeByName("boards") == null) {
-      jungle.createNewTree("boards");
+
+    public static NetworkBulletinBoard NewPersistentJungle(String _uuid) {
+        NetworkJungleBulletinBoard board = new NetworkJungleBulletinBoard(_uuid, new PersistentJournal());
+        board.persistentFlag = true;
+        return board;
     }
-  }
 
-  private void commitLogRecover(File logFile) throws IOException {
-    journal.setInputFile(logFile);
-    ChangeListReader reader = journal.getReader();
-    if (reader == null)
-      return;
-    for (ChangeList chList : reader) {
-      String treeName = chList.getTreeName();
-      JungleTree tree = jungle.getTreeByName(treeName);
-      if (tree == null) {
-        tree = jungle.createNewTree(treeName);
-      }
-      JungleTreeEditor editor = tree.getLocalTreeEditor();
-      Either<Error, JungleTreeEditor> either = JungleUpdater.edit(editor, chList);
-      editor = either.b();
-      if (either.isA()) {
-        throw new IOException("Failed commit log recovery");
-      }
-      editor.success();
-    }
-  }
-
-  public Iterable<String> getBoards() {
-    JungleTree tree = jungle.getTreeByName("boards");
-    TreeNode node = tree.getRootNode();
-    Children chs = node.getChildren();
-
-    IterableConverter.Converter<String, TreeNode> converter = new IterableConverter.Converter<String, TreeNode>() {
-      public String conv(TreeNode _b) {
-        ByteBuffer e = _b.getAttributes().get("name");
-        System.out.println(new String(e.array()));
-        return new String(e.array());
-      }
-    };
-
-    return new IterableConverter<String, TreeNode>(chs, converter);
-  }
-
-  public long getRenewTime(String _boardName) {
-    return renewTime;
-  }
-
-  public void createBoards(final String _name, final String _author, final String _initMessage, final String _editKey) {
-    requestCounter.incrementAndGet();
-    if (null == jungle.createNewTree(_name)) {
-      throw new IllegalStateException();
+    public void init() {
+        if (!persistentFlag) {
+            return;
+        }
+        checkAndCreateLogDirectory();
+        try {
+            commitLogRecover();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
     }
 
-    JungleTree tree = jungle.getTreeByName("boards");
-    JungleTreeEditor editor = tree.getTreeEditor();
-    DefaultNodePath root = new DefaultNodePath();
-    Either<Error, JungleTreeEditor> either = editor.addNewChildAt(root, 0);
-    if (either.isA()) {
-      throw new IllegalStateException();
+    public void checkAndCreateLogDirectory() {
+        File logFile = new File(LOG_DIR);
+        if (!logFile.exists()) {
+            logFile.mkdir();
+            return;
+        }
+        if (logFile.isFile()) {
+            logFile.delete();
+            logFile.mkdir();
+        }
     }
-    editor = either.b();
+
+    public void commitLogRecover() throws IOException {
+        File[] logFiles = new File(LOG_DIR).listFiles();
+        for (File logFile : logFiles) {
+            commitLogRecover(logFile);
+            logFile.delete();
+        }
+        if (jungle.getTreeByName("boards") == null) {
+            jungle.createNewTree("boards");
+        }
+    }
 
-    either = editor.putAttribute(root.add(0), "name", ByteBuffer.wrap(_name.getBytes()));
-    if (either.isA()) {
-      throw new IllegalStateException();
+    private void commitLogRecover(File logFile) throws IOException {
+        journal.setInputFile(logFile);
+        ChangeListReader reader = journal.getReader();
+        if (reader == null)
+            return;
+        for (ChangeList chList : reader) {
+            String treeName = chList.getTreeName();
+            JungleTree tree = jungle.getTreeByName(treeName);
+            if (tree == null) {
+                tree = jungle.createNewTree(treeName);
+            }
+            JungleTreeEditor editor = tree.getLocalTreeEditor();
+            Either<Error, JungleTreeEditor> either = JungleUpdater.edit(editor, chList);
+            editor = either.b();
+            if (either.isA()) {
+                throw new IOException("Failed commit log recovery");
+            }
+            editor.success();
+        }
     }
-    editor = either.b();
-    final long timestamp = System.currentTimeMillis();
-    ByteBuffer tBuffer = ByteBuffer.allocate(16);
-    tBuffer.putLong(timestamp);
-    either = editor.putAttribute(root.add(0), "timestamp", tBuffer);
-    if (either.isA()) {
-      throw new IllegalStateException();
+
+    public Iterable<String> getBoards() {
+        JungleTree tree = jungle.getTreeByName("boards");
+        TreeNode node = tree.getRootNode();
+        Children chs = node.getChildren();
+
+        IterableConverter.Converter<String, TreeNode> converter = new IterableConverter.Converter<String, TreeNode>() {
+            public String conv(TreeNode _b) {
+                ByteBuffer e = _b.getAttributes().get("name");
+                System.out.println(new String(e.array()));
+                return new String(e.array());
+            }
+        };
+
+        return new IterableConverter<String, TreeNode>(chs, converter);
     }
-    either = either.b().success();
-    if (either.isA()) {
-      throw new IllegalStateException();
+
+    public long getRenewTime(String _boardName) {
+        return renewTime;
     }
 
-    tree = jungle.getTreeByName(_name);
-    editor = tree.getTreeEditor();
-    either = editor.addNewChildAt(root, 0);
-    if (either.isA()) {
-      throw new IllegalStateException();
-    }
-    editor = either.b();
-
-    NodeEditor e = new NodeEditor() {
-      ByteBuffer tBuffer2 = ByteBuffer.allocate(16);
-
-      public Either<Error, LoggingNode> edit(TreeNode node) {
-        LoggingNode logNode = wrap(node, new DefaultOperationLog());
-        logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b();
-        logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_initMessage.getBytes())).b();
-        logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b();
-        tBuffer2.putLong(timestamp);
-        logNode = logNode.getAttributes().put("timestamp", tBuffer2).b();
-        return DefaultEither.newB(logNode);
-      }
-
-      @Override
-      public LoggingNode wrap(TreeNode node, OperationLog op) {
-        return new LoggingNode(node, op);
-      }
-    };
-
-    either = editor.edit(root.add(0), e);
-    if (either.isA()) {
-      throw new IllegalStateException();
-    }
-    either.b().success();
-
-  }
-
-  public void createFolder(final String _board, final String _author, final String _message, final String _editKey,
-      String _nodeNum) {
-    JungleTree tree = jungle.getTreeByName(_board);
-    if (tree == null) {
-      throw new IllegalStateException();
-    }
-
-    DefaultNodePath path = new DefaultNodePath();
-    try {
-      for (int count = 0; _nodeNum.substring(count, count + 1) != null; count++) {
-        if (!_nodeNum.substring(count, count + 1).equals("/"))
-          path = path.add(Integer.parseInt(_nodeNum.substring(count, count + 1)));
-      }
-    } catch (Exception _e) {
-    }
-    requestCounter.incrementAndGet();
-    Either<Error, JungleTreeEditor> either;
-    final long timestamp = System.currentTimeMillis();
-    final ByteBuffer tBuffer = ByteBuffer.allocate(16);
-    tBuffer.putLong(timestamp);
-
-    do {
-      TreeNode node = tree.getRootNode();
-      DefaultTraverser traverser = new DefaultTraverser();
-      DefaultEvaluator evaluator = new DefaultEvaluator(path);
-      Either<Error, Traversal> ret = traverser.traverse(node, evaluator);
-      if (ret.isA()) {
-        Assert.fail();
-      }
-
-      Traversal traversal = ret.b();
-      TreeNode target = traversal.destination();
-      int size = target.getChildren().size();
-      JungleTreeEditor editor = tree.getTreeEditor();
-      either = editor.addNewChildAt(path, size);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-
-      NodeEditor e = new NodeEditor() {
-
-        public Either<Error, LoggingNode> edit(TreeNode node) {
-          LoggingNode logNode = wrap(node, new DefaultOperationLog());
-          logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b();
-          logNode = logNode.getAttributes().put("timestamp", tBuffer).b();
-          return DefaultEither.newB(logNode);
+    public void createBoards(final String _name, final String _author, final String _initMessage, final String _editKey) {
+        requestCounter.incrementAndGet();
+        if (null == jungle.createNewTree(_name)) {
+            throw new IllegalStateException();
         }
 
-        @Override
-        public LoggingNode wrap(TreeNode node, OperationLog op) {
-          return new LoggingNode(node, op);
+        JungleTree tree = jungle.getTreeByName("boards");
+        JungleTreeEditor editor = tree.getTreeEditor();
+        DefaultNodePath root = new DefaultNodePath();
+        Either<Error, JungleTreeEditor> either = editor.addNewChildAt(root, 0);
+        if (either.isA()) {
+            throw new IllegalStateException();
+        }
+        editor = either.b();
+
+        either = editor.putAttribute(root.add(0), "name", ByteBuffer.wrap(_name.getBytes()));
+        if (either.isA()) {
+            throw new IllegalStateException();
+        }
+        editor = either.b();
+        final long timestamp = System.currentTimeMillis();
+        ByteBuffer tBuffer = ByteBuffer.allocate(16);
+        tBuffer.putLong(timestamp);
+        either = editor.putAttribute(root.add(0), "timestamp", tBuffer);
+        if (either.isA()) {
+            throw new IllegalStateException();
+        }
+        either = either.b().success();
+        if (either.isA()) {
+            throw new IllegalStateException();
         }
 
-      };
-      path = path.add(size);
-      either = editor.edit(path, e);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-      either = editor.success();
-    } while (either.isA());
+        tree = jungle.getTreeByName(_name);
+        editor = tree.getTreeEditor();
+        either = editor.addNewChildAt(root, 0);
+        if (either.isA()) {
+            throw new IllegalStateException();
+        }
+        editor = either.b();
+
+        NodeEditor e = new NodeEditor() {
+            ByteBuffer tBuffer2 = ByteBuffer.allocate(16);
 
-  }
+            public Either<Error, LoggingNode> edit(TreeNode node) {
+                LoggingNode logNode = wrap(node, new DefaultOperationLog());
+                logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b();
+                logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_initMessage.getBytes())).b();
+                logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b();
+                tBuffer2.putLong(timestamp);
+                logNode = logNode.getAttributes().put("timestamp", tBuffer2).b();
+                return DefaultEither.newB(logNode);
+            }
 
-  public void createBoardMessage(final String _board, final String _author, final String _message, final String _editKey) {
-    requestCounter.incrementAndGet();
-    JungleTree tree = jungle.getTreeByName(_board);
-    if (tree == null) {
-      throw new IllegalStateException();
+            @Override
+            public LoggingNode wrap(TreeNode node, OperationLog op) {
+                return new LoggingNode(node, op);
+            }
+        };
+
+        either = editor.edit(root.add(0), e);
+        if (either.isA()) {
+            throw new IllegalStateException();
+        }
+        either.b().success();
+
     }
 
-    Either<Error, JungleTreeEditor> either;
-    final long timestamp = System.currentTimeMillis();
-    final ByteBuffer tBuffer = ByteBuffer.allocate(16);
-    tBuffer.putLong(timestamp);
-    do {
-
-      TreeNode node = tree.getRootNode();
-      int size = node.getChildren().size();
-      DefaultNodePath path = new DefaultNodePath();
+    public void createFolder(final String _board, final String _author, final String _message, final String _editKey,
+                             String _path) {
+        JungleTree tree = jungle.getTreeByName(_board);
+        if (tree == null) {
+            throw new IllegalStateException();
+        }
 
-      JungleTreeEditor editor = tree.getTreeEditor();
-      either = editor.addNewChildAt(path, size);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-
-      NodeEditor e = new NodeEditor() {
-        public Either<Error, LoggingNode> edit(TreeNode node) {
-          LoggingNode logNode = wrap(node, new DefaultOperationLog());
-          logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b();
-          logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b();
-          logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b();
-          logNode = logNode.getAttributes().put("timestamp", tBuffer).b();
-          return DefaultEither.newB(logNode);
+        DefaultNodePath path = new DefaultNodePath();
+        String[] nums = _path.split(",");
+        for (String num : nums) {
+            if (!num.equals("-1"))
+                path = path.add(Integer.parseInt(num));
         }
 
-        @Override
-        public LoggingNode wrap(TreeNode node, OperationLog op) {
-          return new LoggingNode(node, op);
-        }
-      };
-      path = path.add(size);
-      either = editor.edit(path, e);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-      either = editor.success();
-    } while (either.isA());
+        requestCounter.incrementAndGet();
+        Either<Error, JungleTreeEditor> either;
+        final long timestamp = System.currentTimeMillis();
+        final ByteBuffer tBuffer = ByteBuffer.allocate(16);
+        tBuffer.putLong(timestamp);
 
-  }
+        do {
+            TreeNode node = tree.getRootNode();
+            DefaultTraverser traverser = new DefaultTraverser();
+            DefaultEvaluator evaluator = new DefaultEvaluator(path);
+            Either<Error, Traversal> ret = traverser.traverse(node, evaluator);
+            if (ret.isA()) {
+                Assert.fail();
+            }
+
+            Traversal traversal = ret.b();
+            TreeNode target = traversal.destination();
+            int size = target.getChildren().size();
+            JungleTreeEditor editor = tree.getTreeEditor();
+            either = editor.addNewChildAt(path, size);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+
+            NodeEditor e = new NodeEditor() {
 
-  public void editMessage(String _board, String _nodeNum, final String _author, final String _message,
-      final String _editKey) {
-    requestCounter.incrementAndGet();
-    final long timestamp = System.currentTimeMillis();
-    final ByteBuffer tBuffer = ByteBuffer.allocate(16);
-    tBuffer.putLong(timestamp);
-    JungleTree tree = jungle.getTreeByName(_board);
-    Either<Error, JungleTreeEditor> either = null;
+                public Either<Error, LoggingNode> edit(TreeNode node) {
+                    LoggingNode logNode = wrap(node, new DefaultOperationLog());
+                    logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b();
+                    logNode = logNode.getAttributes().put("timestamp", tBuffer).b();
+                    return DefaultEither.newB(logNode);
+                }
+
+                @Override
+                public LoggingNode wrap(TreeNode node, OperationLog op) {
+                    return new LoggingNode(node, op);
+                }
 
-    do {
-      DefaultNodePath path = new DefaultNodePath();
-      try {
-        for (int count = 0; _nodeNum.substring(count, count + 1) != null; count++) {
-          if (!_nodeNum.substring(count, count + 1).equals("/"))
-            path = path.add(Integer.parseInt(_nodeNum.substring(count, count + 1)));
-        }
-      } catch (Exception _e) {
-      }
-      JungleTreeEditor editor = tree.getTreeEditor();
-      NodeEditor e = new NodeEditor() {
-        public Either<Error, LoggingNode> edit(TreeNode node) {
-          LoggingNode logNode = wrap(node, new DefaultOperationLog());
-          System.out.println(new String(node.getAttributes().get("mes").array()));
-          logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b();
-          logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b();
-          logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b();
-          logNode = logNode.getAttributes().put("timestamp", tBuffer).b();
-          System.out.println(new String(node.getAttributes().get("mes").array()));
-          return DefaultEither.newB(logNode);
+            };
+            path = path.add(size);
+            either = editor.edit(path, e);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+            either = editor.success();
+        } while (either.isA());
+
+    }
+
+    public void createBoardMessage(final String _board, final String _author, final String _message, final String _editKey) {
+        requestCounter.incrementAndGet();
+        JungleTree tree = jungle.getTreeByName(_board);
+        if (tree == null) {
+            throw new IllegalStateException();
         }
 
-        @Override
-        public LoggingNode wrap(TreeNode node, OperationLog op) {
-          return new LoggingNode(node, op);
-        }
-      };
-      either = editor.edit(path, e);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-      either = editor.success();
-    } while (either.isA());
-    renewTime = timestamp;
-  }
+        Either<Error, JungleTreeEditor> either;
+        final long timestamp = System.currentTimeMillis();
+        final ByteBuffer tBuffer = ByteBuffer.allocate(16);
+        tBuffer.putLong(timestamp);
+        do {
+
+            TreeNode node = tree.getRootNode();
+            int size = node.getChildren().size();
+            DefaultNodePath path = new DefaultNodePath();
+
+            JungleTreeEditor editor = tree.getTreeEditor();
+            either = editor.addNewChildAt(path, size);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+
+            NodeEditor e = new NodeEditor() {
+                public Either<Error, LoggingNode> edit(TreeNode node) {
+                    LoggingNode logNode = wrap(node, new DefaultOperationLog());
+                    logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b();
+                    logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b();
+                    logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b();
+                    logNode = logNode.getAttributes().put("timestamp", tBuffer).b();
+                    return DefaultEither.newB(logNode);
+                }
+
+                @Override
+                public LoggingNode wrap(TreeNode node, OperationLog op) {
+                    return new LoggingNode(node, op);
+                }
+            };
+            path = path.add(size);
+            either = editor.edit(path, e);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+            either = editor.success();
+        } while (either.isA());
+
+    }
 
-  public void createAttribute(String _board, String _uuid, final String _author, final String _message,
-      final String _editKey) {
-    requestCounter.incrementAndGet();
-    final long timestamp = System.currentTimeMillis();
-    final ByteBuffer tBuffer = ByteBuffer.allocate(16);
-    tBuffer.putLong(timestamp);
-    JungleTree tree = jungle.getTreeByName(_board);
-    Either<Error, JungleTreeEditor> either = null;
-    DefaultNodePath path = new DefaultNodePath();
-    do {
-      try {
-        for (int count = 0; _uuid.substring(count, count + 1) != null; count++) {
-          if (!_uuid.substring(count, count + 1).equals("/"))
-            path = path.add(Integer.parseInt(_uuid.substring(count, count + 1)));
+    public void editMessage(String _board, String _path, final String _author, final String _message,
+                            final String _editKey) {
+        requestCounter.incrementAndGet();
+        final long timestamp = System.currentTimeMillis();
+        final ByteBuffer tBuffer = ByteBuffer.allocate(16);
+        tBuffer.putLong(timestamp);
+        JungleTree tree = jungle.getTreeByName(_board);
+        Either<Error, JungleTreeEditor> either = null;
+        DefaultNodePath path = new DefaultNodePath();
+        String[] nums = _path.split(",");
+        for (String num : nums) {
+            if (!num.equals("-1"))
+                path = path.add(Integer.parseInt(num));
         }
-      } catch (Exception _e) {
-      }
+        do {
 
-      JungleTreeEditor editor = tree.getTreeEditor();
-      NodeEditor e = new NodeEditor() {
-        String str;
+            JungleTreeEditor editor = tree.getTreeEditor();
+            NodeEditor e = new NodeEditor() {
+                public Either<Error, LoggingNode> edit(TreeNode node) {
+                    LoggingNode logNode = wrap(node, new DefaultOperationLog());
+                    System.out.println(new String(node.getAttributes().get("mes").array()));
+                    logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b();
+                    logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b();
+                    logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b();
+                    logNode = logNode.getAttributes().put("timestamp", tBuffer).b();
+                    System.out.println(new String(node.getAttributes().get("mes").array()));
+                    return DefaultEither.newB(logNode);
+                }
 
-        public Either<Error, LoggingNode> edit(TreeNode node) {
-          LoggingNode logNode = wrap(node, new DefaultOperationLog());
-          str = "0";
-          int count = 0;
-          for (; logNode.getAttributes().get("mes" + String.valueOf(count)) != null; count++) {
-          }
-          str = String.valueOf(count);
-          logNode = logNode.getAttributes().put("mes" + str, ByteBuffer.wrap(_message.getBytes())).b();
-          logNode = logNode.getAttributes().put("timestamp" + str, tBuffer).b();
-          return DefaultEither.newB(logNode);
+                @Override
+                public LoggingNode wrap(TreeNode node, OperationLog op) {
+                    return new LoggingNode(node, op);
+                }
+            };
+            either = editor.edit(path, e);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+            either = editor.success();
+        } while (either.isA());
+        renewTime = timestamp;
+    }
+
+    public void createAttribute(String _board, String _path, final String _author, final String _message,
+                                final String _editKey) {
+        requestCounter.incrementAndGet();
+        final long timestamp = System.currentTimeMillis();
+        final ByteBuffer tBuffer = ByteBuffer.allocate(16);
+        tBuffer.putLong(timestamp);
+        JungleTree tree = jungle.getTreeByName(_board);
+        Either<Error, JungleTreeEditor> either = null;
+        DefaultNodePath path = new DefaultNodePath();
+        String[] nums = _path.split(",");
+        for (String num : nums) {
+            if (!num.equals("-1"))
+                path = path.add(Integer.parseInt(num));
         }
 
-        @Override
-        public LoggingNode wrap(TreeNode node, OperationLog op) {
-          return new LoggingNode(node, op);
-        }
-      };
-      either = editor.edit(path, e);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-      either = editor.success();
-    } while (either.isA());
-  }
+        do {
+            JungleTreeEditor editor = tree.getTreeEditor();
+            NodeEditor e = new NodeEditor() {
+                String str;
+
+                public Either<Error, LoggingNode> edit(TreeNode node) {
+                    LoggingNode logNode = wrap(node, new DefaultOperationLog());
+                    str = "0";
+                    int count = 0;
+                    for (; logNode.getAttributes().get("mes" + String.valueOf(count)) != null; count++) {
+                    }
+                    str = String.valueOf(count);
+                    logNode = logNode.getAttributes().put("mes" + str, ByteBuffer.wrap(_message.getBytes())).b();
+                    logNode = logNode.getAttributes().put("timestamp" + str, tBuffer).b();
+                    return DefaultEither.newB(logNode);
+                }
 
-  public void editAttribute(String boardName, String _path, final String id, final String _message) {
-    requestCounter.incrementAndGet();
-    final long timestamp = System.currentTimeMillis();
-    final ByteBuffer tBuffer = ByteBuffer.allocate(16);
-    tBuffer.putLong(timestamp);
-    JungleTree tree = jungle.getTreeByName(boardName);
-    Either<Error, JungleTreeEditor> either = null;
-    DefaultNodePath path = new DefaultNodePath();
-    do {
-      try {
-        for (int count = 0; _path.substring(count, count + 1) != null; count++) {
-          if (!_path.substring(count, count + 1).equals("/"))
-            path = path.add(Integer.parseInt(_path.substring(count, count + 1)));
-        }
-      } catch (Exception _e) {
-      }
+                @Override
+                public LoggingNode wrap(TreeNode node, OperationLog op) {
+                    return new LoggingNode(node, op);
+                }
+            };
+            either = editor.edit(path, e);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+            either = editor.success();
+        } while (either.isA());
+    }
 
-      JungleTreeEditor editor = tree.getTreeEditor();
-      NodeEditor e = new NodeEditor() {
-        public Either<Error, LoggingNode> edit(TreeNode node) {
-          LoggingNode logNode = wrap(node, new DefaultOperationLog());
-          // EnableNodeWrapper<T> node = _e.getWrap();
-          logNode = logNode.getAttributes().put("mes" + id, ByteBuffer.wrap(_message.getBytes())).b();
-          logNode = logNode.getAttributes().put("timestamp" + id, tBuffer).b();
-          return DefaultEither.newB(logNode);
+    public void editAttribute(String _bname, String _path, final String id, final String _message) {
+        requestCounter.incrementAndGet();
+        final long timestamp = System.currentTimeMillis();
+        final ByteBuffer tBuffer = ByteBuffer.allocate(16);
+        tBuffer.putLong(timestamp);
+        JungleTree tree = jungle.getTreeByName(_bname);
+        Either<Error, JungleTreeEditor> either = null;
+        DefaultNodePath path = new DefaultNodePath();
+        String[] nums = _path.split(",");
+        for (String num : nums) {
+            if (!num.equals("-1"))
+                path = path.add(Integer.parseInt(num));
         }
 
-        @Override
-        public LoggingNode wrap(TreeNode node, OperationLog op) {
-          return new LoggingNode(node, op);
-        }
-      };
-      either = editor.edit(path, e);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-      either = editor.success();
-    } while (either.isA());
-  }
-
-  public void deleteNode(String _board, String _path, String _id) {
-    requestCounter.incrementAndGet();
-    int id = Integer.parseInt(_id);
-    final long timestamp = System.currentTimeMillis();
-    final ByteBuffer tBuffer = ByteBuffer.allocate(16);
-    tBuffer.putLong(timestamp);
-    JungleTree tree = jungle.getTreeByName(_board);
-    Either<Error, JungleTreeEditor> either = null;
-    DefaultNodePath path = new DefaultNodePath();
-    do {
-      try {
-        for (int count = 0; _path.substring(count, count + 1) != null; count++) {
-          if (!_path.substring(count, count + 1).equals("/"))
-            path = path.add(Integer.parseInt(_path.substring(count, count + 1)));
-        }
-      } catch (Exception _e) {
-      }
-
-      JungleTreeEditor editor = tree.getTreeEditor();
+        do {
+            JungleTreeEditor editor = tree.getTreeEditor();
+            NodeEditor e = new NodeEditor() {
+                public Either<Error, LoggingNode> edit(TreeNode node) {
+                    LoggingNode logNode = wrap(node, new DefaultOperationLog());
+                    logNode = logNode.getAttributes().put("mes" + id, ByteBuffer.wrap(_message.getBytes())).b();
+                    logNode = logNode.getAttributes().put("timestamp" + id, tBuffer).b();
+                    return DefaultEither.newB(logNode);
+                }
 
-      either = editor.deleteChildAt(path, id);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-      either = editor.success();
-    } while (either.isA());
-
-  }
+                @Override
+                public LoggingNode wrap(TreeNode node, OperationLog op) {
+                    return new LoggingNode(node, op);
+                }
+            };
+            either = editor.edit(path, e);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+            either = editor.success();
+        } while (either.isA());
+    }
 
-  public void deleteAttribute(String _board, String _path, final String id) {
-    requestCounter.incrementAndGet();
-    final long timestamp = System.currentTimeMillis();
-    final ByteBuffer tBuffer = ByteBuffer.allocate(16);
-    tBuffer.putLong(timestamp);
-    JungleTree tree = jungle.getTreeByName(_board);
-    Either<Error, JungleTreeEditor> either = null;
-    DefaultNodePath path = new DefaultNodePath();
-    do {
-      try {
-        for (int count = 0; _path.substring(count, count + 1) != null; count++) {
-          if (!_path.substring(count, count + 1).equals("/"))
-            path = path.add(Integer.parseInt(_path.substring(count, count + 1)));
-        }
-      } catch (Exception _e) {
-        System.out.println("屑");
-      }
-
-      JungleTreeEditor editor = tree.getTreeEditor();
-      NodeEditor e = new NodeEditor() {
-        public Either<Error, LoggingNode> edit(TreeNode node) {
-          LoggingNode logNode = wrap(node, new DefaultOperationLog());
-          logNode = logNode.getAttributes().delete("mes" + id).b();
-          logNode = logNode.getAttributes().delete("timestamp" + id).b();
-          int count = Integer.parseInt(id);
-          for (; logNode.getAttributes().get("mes" + String.valueOf(count + 1)) != null;) {
-            logNode = logNode.getAttributes()
-                .put("mes" + count, node.getAttributes().get("mes" + String.valueOf(count + 1))).b();
-            logNode = logNode.getAttributes().put("timestamp" + count, tBuffer).b();
-            count++;
-          }
-          if (count != Integer.parseInt(id)) {
-            logNode = logNode.getAttributes().delete("timestamp" + count).b();
-            logNode = logNode.getAttributes().delete("mes" + count).b();
-          }
-
-          return DefaultEither.newB(logNode);
+    public void deleteNode(String _board, String _path, String _id) {
+        requestCounter.incrementAndGet();
+        int id = Integer.parseInt(_id);
+        final long timestamp = System.currentTimeMillis();
+        final ByteBuffer tBuffer = ByteBuffer.allocate(16);
+        tBuffer.putLong(timestamp);
+        JungleTree tree = jungle.getTreeByName(_board);
+        Either<Error, JungleTreeEditor> either = null;
+        DefaultNodePath path = new DefaultNodePath();
+        String[] nums = _path.split(",");
+        for (String num : nums) {
+            if (!num.equals("-1"))
+                path = path.add(Integer.parseInt(num));
         }
 
-        @Override
-        public LoggingNode wrap(TreeNode node, OperationLog op) {
-          return new LoggingNode(node, op);
-        }
-      };
-      either = editor.edit(path, e);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-      either = editor.success();
-    } while (either.isA());
-  }
+        do {
+            JungleTreeEditor editor = tree.getTreeEditor();
+
+            either = editor.deleteChildAt(path, id);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+            either = editor.success();
+        } while (either.isA());
+
+    }
 
-  public void editMatrixMessage(String _board, String _uuid, final String _author, final String _message,
-      final String _editKey) {
-    requestCounter.incrementAndGet();
-    final long timestamp = System.currentTimeMillis();
-    final ByteBuffer tBuffer = ByteBuffer.allocate(16);
-    tBuffer.putLong(timestamp);
-    JungleTree tree = jungle.getTreeByName(_board);
-    Either<Error, JungleTreeEditor> either = null;
-    do {
-      DefaultNodePath path = new DefaultNodePath();
-      path = path.add(Integer.parseInt(_uuid));
-
-      JungleTreeEditor editor = tree.getTreeEditor();
-      NodeEditor e = new NodeEditor() {
-        public Either<Error, LoggingNode> edit(TreeNode node) {
-          LoggingNode logNode = wrap(node, new DefaultOperationLog());
-          logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b();
-          logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b();
-          logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b();
-          logNode = logNode.getAttributes().put("timestamp", tBuffer).b();
-          return DefaultEither.newB(logNode);
+    public void deleteAttribute(String _board, String _path, final String id) {
+        requestCounter.incrementAndGet();
+        final long timestamp = System.currentTimeMillis();
+        final ByteBuffer tBuffer = ByteBuffer.allocate(16);
+        tBuffer.putLong(timestamp);
+        JungleTree tree = jungle.getTreeByName(_board);
+        Either<Error, JungleTreeEditor> either = null;
+        DefaultNodePath path = new DefaultNodePath();
+        String[] nums = _path.split(",");
+        for (String num : nums) {
+            if (!num.equals("-1"))
+                path = path.add(Integer.parseInt(num));
         }
 
-        @Override
-        public LoggingNode wrap(TreeNode node, OperationLog op) {
-          return new LoggingNode(node, op);
-        }
-      };
-      either = editor.edit(path, e);
-      if (either.isA()) {
-        throw new IllegalStateException();
-      }
-      editor = either.b();
-      either = editor.success();
-    } while (either.isA());
-    renewTime = timestamp;
-  }
+        do {
+            JungleTreeEditor editor = tree.getTreeEditor();
+            NodeEditor e = new NodeEditor() {
+                public Either<Error, LoggingNode> edit(TreeNode node) {
+                    LoggingNode logNode = wrap(node, new DefaultOperationLog());
+                    logNode = logNode.getAttributes().delete("mes" + id).b();
+                    logNode = logNode.getAttributes().delete("timestamp" + id).b();
+                    int count = Integer.parseInt(id);
+                    for (; logNode.getAttributes().get("mes" + String.valueOf(count + 1)) != null; ) {
+                        logNode = logNode.getAttributes()
+                                .put("mes" + count, node.getAttributes().get("mes" + String.valueOf(count + 1))).b();
+                        logNode = logNode.getAttributes().put("timestamp" + count, tBuffer).b();
+                        count++;
+                    }
+                    if (count != Integer.parseInt(id)) {
+                        logNode = logNode.getAttributes().delete("timestamp" + count).b();
+                        logNode = logNode.getAttributes().delete("mes" + count).b();
+                    }
 
-  public Iterable<BoardMessage> getFolder(String _boardName, String _nodeNum) {
+                    return DefaultEither.newB(logNode);
+                }
+
+                @Override
+                public LoggingNode wrap(TreeNode node, OperationLog op) {
+                    return new LoggingNode(node, op);
+                }
+            };
+            either = editor.edit(path, e);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+            either = editor.success();
+        } while (either.isA());
+    }
 
-    DefaultNodePath path = new DefaultNodePath();
-    try {
-      for (int count = 0; _nodeNum.substring(count, count + 1) != null; count++) {
-        if (!_nodeNum.substring(count, count + 1).equals("/"))
-          path = path.add(Integer.parseInt(_nodeNum.substring(count, count + 1)));
-      }
-    } catch (Exception _e) {
-    }
-    requestCounter.incrementAndGet();
-    JungleTree tree = jungle.getTreeByName(_boardName);
-    TreeNode node = tree.getRootNode();
+    public void editMatrixMessage(String _board, String _uuid, final String _author, final String _message,
+                                  final String _editKey) {
+        requestCounter.incrementAndGet();
+        final long timestamp = System.currentTimeMillis();
+        final ByteBuffer tBuffer = ByteBuffer.allocate(16);
+        tBuffer.putLong(timestamp);
+        JungleTree tree = jungle.getTreeByName(_board);
+        Either<Error, JungleTreeEditor> either = null;
+        do {
+            DefaultNodePath path = new DefaultNodePath();
+            path = path.add(Integer.parseInt(_uuid));
 
-    DefaultTraverser traverser = new DefaultTraverser();
-    // TraversableNodeWrapper<Node> traversable = new
-    // TraversableNodeWrapper<Node>(node);
-    DefaultEvaluator evaluator = new DefaultEvaluator(path);
-    Either<Error, Traversal> ret = traverser.traverse(node, evaluator);
-    if (ret.isA()) {
-      Assert.fail();
+            JungleTreeEditor editor = tree.getTreeEditor();
+            NodeEditor e = new NodeEditor() {
+                public Either<Error, LoggingNode> edit(TreeNode node) {
+                    LoggingNode logNode = wrap(node, new DefaultOperationLog());
+                    logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b();
+                    logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b();
+                    logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b();
+                    logNode = logNode.getAttributes().put("timestamp", tBuffer).b();
+                    return DefaultEither.newB(logNode);
+                }
+
+                @Override
+                public LoggingNode wrap(TreeNode node, OperationLog op) {
+                    return new LoggingNode(node, op);
+                }
+            };
+            either = editor.edit(path, e);
+            if (either.isA()) {
+                throw new IllegalStateException();
+            }
+            editor = either.b();
+            either = editor.success();
+        } while (either.isA());
+        renewTime = timestamp;
     }
 
-    Traversal traversal = ret.b();
-    TreeNode target = traversal.destination();
-    Children chs = target.getChildren();
+    public Iterable<BoardMessage> getFolder(String _boardName, String _nodeNum) {
+        DefaultNodePath path = new DefaultNodePath();
+        System.out.println(_nodeNum.substring(0, 1));
+        String[] nums = _nodeNum.split(",");
+        for (String num : nums) {
+            if (!num.equals("-1"))
+                path = path.add(Integer.parseInt(num));
+        }
+        JungleTree tree = jungle.getTreeByName(_boardName);
+        TreeNode node = tree.getRootNode();
+        requestCounter.incrementAndGet();
 
-    final AtomicInteger counter = new AtomicInteger(0);
-    IterableConverter.Converter<BoardMessage, TreeNode> converter = new IterableConverter.Converter<BoardMessage, TreeNode>() {
-      public BoardMessage conv(TreeNode _b) {
-        String uuid = Integer.toString(counter.get());
-        String message = new String(_b.getAttributes().get("mes").array());
-        counter.incrementAndGet();
-        return new BoardMessageImpl(null, message, uuid);
-      }
-    };
-    return new IterableConverter<BoardMessage, TreeNode>(chs, converter);
-  }
+        DefaultTraverser traverser = new DefaultTraverser();
+        DefaultEvaluator evaluator = new DefaultEvaluator(path);
+        Either<Error, Traversal> ret = traverser.traverse(node, evaluator);
+        if (ret.isA()) {
+            Assert.fail();
+        }
+
+        Traversal traversal = ret.b();
+        TreeNode target = traversal.destination();
+        Children chs = target.getChildren();
 
-  public boolean compare(TreeNode compareNode, String compareAttribute) {
-    String labName = compareNode.getAttributes().getString("mes");
-    if (labName.equals(compareAttribute))
-      return true;
-
-    int loopCount = 0;
-    for (loopCount = 0; compareNode.getAttributes().getString("mes" + loopCount) != null; loopCount++) {
-      labName = compareNode.getAttributes().getString("mes" + loopCount);
-      if (labName.equals(compareAttribute))
-        return true;
+        final AtomicInteger counter = new AtomicInteger(0);
+        IterableConverter.Converter<BoardMessage, TreeNode> converter = new IterableConverter.Converter<BoardMessage, TreeNode>() {
+            public BoardMessage conv(TreeNode _b) {
+                String uuid = Integer.toString(counter.get());
+                String message = new String(_b.getAttributes().get("mes").array());
+                counter.incrementAndGet();
+                return new BoardMessageImpl(null, message, uuid);
+            }
+        };
+        return new IterableConverter<BoardMessage, TreeNode>(chs, converter);
     }
 
-    return false;
-  }
-
-  public int getRequestNum() {
-    return requestCounter.get();
-  }
+    public boolean compare(TreeNode compareNode, String compareAttribute) {
+        String labName = compareNode.getAttributes().getString("mes");
+        if (labName.equals(compareAttribute))
+            return true;
 
-  private static class BoardMessageImpl implements BoardMessage {
-    private final String author;
-    private final String message;
-    private final String uuid;
+        for (int loopCount = 0; compareNode.getAttributes().getString("mes" + loopCount) != null; loopCount++) {
+            labName = compareNode.getAttributes().getString("mes" + loopCount);
+            if (labName.equals(compareAttribute))
+                return true;
+        }
 
-    public BoardMessageImpl(String _author, String _message, String _uuid) {
-      author = _author;
-      message = _message;
-      uuid = _uuid;
+        return false;
     }
 
-    public String getAuthor() {
-      return author;
+    public int getRequestNum() {
+        return requestCounter.get();
     }
 
-    public String getMessage() {
-      return message;
-    }
+    private static class BoardMessageImpl implements BoardMessage {
+        private final String author;
+        private final String message;
+        private final String uuid;
+
+        public BoardMessageImpl(String _author, String _message, String _uuid) {
+            author = _author;
+            message = _message;
+            uuid = _uuid;
+        }
 
-    public String getUUID() {
-      return uuid;
+        public String getAuthor() {
+            return author;
+        }
+
+        public String getMessage() {
+            return message;
+        }
+
+        public String getUUID() {
+            return uuid;
+        }
+
     }
 
-  }
-
-  public String sanitize(String str) {
-    if (str == null) {
-      return str;
-    }
-    str = str.replaceAll("&", "&amp;");
-    str = str.replaceAll("<", "&lt;");
-    str = str.replaceAll(">", "&gt;");
-    str = str.replaceAll("\"", "&quot;");
-    str = str.replaceAll("'", "&#39;");
-    return str;
-  }
-
-  @Override
-  public GetAttributeImp getAttribute(String _bname, String _nodeNum, String revisionStr) {
-
-    DefaultNodePath path = new DefaultNodePath();
-    try {
-      for (int count = 0; _nodeNum.substring(count, count + 1) != null; count++) {
-        if (!_nodeNum.substring(count, count + 1).equals("/"))
-          path = path.add(Integer.parseInt(_nodeNum.substring(count, count + 1)));
-      }
-    } catch (Exception _e) {
-    }
-    JungleTree tree = jungle.getTreeByName(_bname);
-    System.out.println(tree.revision());
-    Long revision = Long.parseLong(revisionStr);
-    JungleTree oldTree = tree.getOldTree(revision).b();
-    System.out.println(oldTree.revision());
-    TreeNode node = oldTree.getRootNode();
-
-    DefaultTraverser traverser = new DefaultTraverser();
-    DefaultEvaluator evaluator = new DefaultEvaluator(path);
-    Either<Error, Traversal> ret = traverser.traverse(node, evaluator);
-    if (ret.isA()) {
-      Assert.fail();
+    public String sanitize(String str) {
+        if (str == null) {
+            return str;
+        }
+        str = str.replaceAll("&", "&amp;");
+        str = str.replaceAll("<", "&lt;");
+        str = str.replaceAll(">", "&gt;");
+        str = str.replaceAll("\"", "&quot;");
+        str = str.replaceAll("'", "&#39;");
+        return str;
     }
 
-    Traversal traversal = ret.b();
-    TreeNode target = traversal.destination();
-    return new GetAttributeImp(target);
-  }
+    @Override
+    public GetAttributeImp getAttribute(String _bname, String _path, String revisionStr) {
+        DefaultNodePath path = new DefaultNodePath();
+        String[] nums = _path.split(",");
+        for (String num : nums) {
+            if (!num.equals("-1"))
+                path = path.add(Integer.parseInt(num));
+        }
+
+        JungleTree tree = jungle.getTreeByName(_bname);
+        TreeNode node;
+        if (revisionStr.equals("-1")) {
+            node = tree.getRootNode();
+        } else {
+            Long revision = Long.parseLong(revisionStr);
+            JungleTree oldTree = tree.getOldTree(revision).b();
+            node = oldTree.getRootNode();
+        }
+
+        DefaultTraverser traverser = new DefaultTraverser();
+        DefaultEvaluator evaluator = new DefaultEvaluator(path);
+        Either<Error, Traversal> ret = traverser.traverse(node, evaluator);
+        if (ret.isA()) {
+            Assert.fail();
+        }
+
+        Traversal traversal = ret.b();
+        TreeNode target = traversal.destination();
+        return new GetAttributeImp(target);
+    }
 }