Mercurial > hg > Members > kazuma > jungle-ormapper
diff src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/impl/DefaultTreeEditor.java @ 0:44465893e8b8
first Commit
author | Kazuma |
---|---|
date | Wed, 30 Nov 2016 01:47:55 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/store/impl/DefaultTreeEditor.java Wed Nov 30 01:47:55 2016 +0900 @@ -0,0 +1,80 @@ +package jp.ac.u_ryukyu.ie.cr.jungle.store.impl; + + +import jp.ac.u_ryukyu.ie.cr.jungle.store.NodePath; +import jp.ac.u_ryukyu.ie.cr.jungle.store.TreeEditor; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.logger.LoggingNode; +import jp.ac.u_ryukyu.ie.cr.jungle.store.trasnformer.NodeEditor; +import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultEvaluator; +import jp.ac.u_ryukyu.ie.cr.jungle.traverser.Direction; +import jp.ac.u_ryukyu.ie.cr.jungle.traverser.Traversal; +import jp.ac.u_ryukyu.ie.cr.jungle.traverser.Traverser; +import jp.ac.u_ryukyu.ie.cr.jungle.util.Error; +import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List; +import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither; +import jp.ac.u_ryukyu.ie.cr.jungle.util.Either; + +public class DefaultTreeEditor implements TreeEditor +{ + private final Traverser traverser; + public DefaultTreeEditor(Traverser traverser) + { + this.traverser = traverser; + } + + @Override + public Either<Error,LoggingNode> edit(TreeNode root,NodePath path,NodeEditor editor) + { + DefaultEvaluator e = new DefaultEvaluator(path); + Either<jp.ac.u_ryukyu.ie.cr.jungle.util.Error, Traversal> either = traverser.traverse(root,e); + + if(either.isA()){ + return DefaultEither.newA(either.a()); + } + Traversal t = either.b(); + return clone(t,editor); + } + + private Either<Error,LoggingNode> clone(Traversal t,NodeEditor editor) + { + // copying nodes from bottom to root + + List<Direction<TreeNode>> path = new List<>(); + for(Direction<TreeNode> direction : t){ + path = path.addLast(direction); + } + + // target + Direction<TreeNode> targetDirection = path.head(); + TreeNode target = targetDirection.getTarget(); + Either<Error,LoggingNode> either = editor.edit(target); + if(either.isA()){ + return DefaultEither.newA(either.a()); + } + + LoggingNode newWrap = either.b(); + + // top + int pos = targetDirection.getPosition(); + TreeNode child = newWrap.getWrap(); + + + for(Direction<TreeNode> parentDirection : path.deleteHead()){ + + TreeNodeChildren chs = parentDirection.getTarget().getChildren(); + + Either<Error,TreeNode> ret = chs.replaceNode(pos,child); + if(ret.isA()){ + return DefaultEither.newA(ret.a()); + } + + child = ret.b(); + pos = parentDirection.getPosition(); + } + + TreeNode newRoot = child; + LoggingNode logNode = editor.wrap(newRoot,newWrap.getOperationLog()); + return DefaultEither.newB(logNode); + } + +} \ No newline at end of file