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