0
|
1 package jp.ac.u_ryukyu.ie.cr.jungle.store.impl;
|
|
2
|
|
3
|
|
4 import jp.ac.u_ryukyu.ie.cr.jungle.store.NodePath;
|
|
5 import jp.ac.u_ryukyu.ie.cr.jungle.store.TreeEditor;
|
|
6 import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.logger.LoggingNode;
|
|
7 import jp.ac.u_ryukyu.ie.cr.jungle.store.trasnformer.NodeEditor;
|
|
8 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultEvaluator;
|
|
9 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.Direction;
|
|
10 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.Traversal;
|
|
11 import jp.ac.u_ryukyu.ie.cr.jungle.traverser.Traverser;
|
|
12 import jp.ac.u_ryukyu.ie.cr.jungle.util.Error;
|
|
13 import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
|
|
14 import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
|
|
15 import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
|
|
16
|
|
17 public class DefaultTreeEditor implements TreeEditor
|
|
18 {
|
|
19 private final Traverser traverser;
|
|
20 public DefaultTreeEditor(Traverser traverser)
|
|
21 {
|
|
22 this.traverser = traverser;
|
|
23 }
|
|
24
|
|
25 @Override
|
|
26 public Either<Error,LoggingNode> edit(TreeNode root,NodePath path,NodeEditor editor)
|
|
27 {
|
|
28 DefaultEvaluator e = new DefaultEvaluator(path);
|
|
29 Either<jp.ac.u_ryukyu.ie.cr.jungle.util.Error, Traversal> either = traverser.traverse(root,e);
|
|
30
|
|
31 if(either.isA()){
|
|
32 return DefaultEither.newA(either.a());
|
|
33 }
|
|
34 Traversal t = either.b();
|
|
35 return clone(t,editor);
|
|
36 }
|
|
37
|
|
38 private Either<Error,LoggingNode> clone(Traversal t,NodeEditor editor)
|
|
39 {
|
|
40 // copying nodes from bottom to root
|
|
41
|
|
42 List<Direction<TreeNode>> path = new List<>();
|
|
43 for(Direction<TreeNode> direction : t){
|
|
44 path = path.addLast(direction);
|
|
45 }
|
|
46
|
|
47 // target
|
|
48 Direction<TreeNode> targetDirection = path.head();
|
|
49 TreeNode target = targetDirection.getTarget();
|
|
50 Either<Error,LoggingNode> either = editor.edit(target);
|
|
51 if(either.isA()){
|
|
52 return DefaultEither.newA(either.a());
|
|
53 }
|
|
54
|
|
55 LoggingNode newWrap = either.b();
|
|
56
|
|
57 // top
|
|
58 int pos = targetDirection.getPosition();
|
|
59 TreeNode child = newWrap.getWrap();
|
|
60
|
|
61
|
|
62 for(Direction<TreeNode> parentDirection : path.deleteHead()){
|
|
63
|
|
64 TreeNodeChildren chs = parentDirection.getTarget().getChildren();
|
|
65
|
|
66 Either<Error,TreeNode> ret = chs.replaceNode(pos,child);
|
|
67 if(ret.isA()){
|
|
68 return DefaultEither.newA(ret.a());
|
|
69 }
|
|
70
|
|
71 child = ret.b();
|
|
72 pos = parentDirection.getPosition();
|
|
73 }
|
|
74
|
|
75 TreeNode newRoot = child;
|
|
76 LoggingNode logNode = editor.wrap(newRoot,newWrap.getOperationLog());
|
|
77 return DefaultEither.newB(logNode);
|
|
78 }
|
|
79
|
|
80 } |