]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateTree.java
a558f84462cf5e8cfe6548f761afa0c85cdb00fe
[simantics/interop.git] / org.simantics.interop.update / src / org / simantics / interop / update / model / UpdateTree.java
1 package  org.simantics.interop.update.model;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import org.simantics.db.ReadGraph;
7 import org.simantics.db.Resource;
8 import org.simantics.db.Session;
9 import org.simantics.db.common.request.ResourceRead;
10 import org.simantics.db.exception.DatabaseException;
11 import org.simantics.db.request.Read;
12 import org.simantics.interop.test.GraphChanges;
13
14
15 public class UpdateTree {
16         
17         private UpdateNode rootNode;
18         private Map<Resource,UpdateNode> nodes;
19         private GraphChanges changes;
20         private UpdateOperations updateOps;
21         
22         
23         public UpdateTree(ReadGraph g, GraphChanges changes, UpdateOperations updateOps) throws DatabaseException {
24                 this.changes = changes;
25                 this.nodes = new HashMap<Resource, UpdateNode>();
26                 this.rootNode = createNode(g, UpdateStatus.EXIST, changes.getResource1());
27                 nodes.put(changes.getResource1(), rootNode);
28                 nodes.put(changes.getResource2(), rootNode);
29                 this.updateOps = updateOps;
30                 this.updateOps.populate(g);
31                 populate(g);
32         }
33         
34         public UpdateTree(Session session, GraphChanges changes, UpdateOperations updateOps) throws DatabaseException {
35                 this.changes = changes;
36                 this.nodes = new HashMap<Resource, UpdateNode>();
37                 this.rootNode = session.syncRequest(new NodeRequest(UpdateStatus.EXIST, changes.getResource1()));
38                 nodes.put(changes.getResource1(), rootNode);
39                 nodes.put(changes.getResource2(), rootNode);
40                 this.updateOps = updateOps;
41                 this.updateOps.populate(session);
42                 populate(session);
43         }
44         
45         private class NodeRequest extends ResourceRead<UpdateNode> {
46                 UpdateStatus status;
47                 public NodeRequest(UpdateStatus status, Resource r) {
48                         super(r);
49                         this.status = status;
50                 }
51                 @Override
52                 public UpdateNode perform(ReadGraph graph) throws DatabaseException {
53                         return createNode(graph, status, resource);
54                 }
55         }
56         
57         public UpdateOperations getUpdateOps() {
58                 return updateOps;
59         }
60         
61         public UpdateNode getRootNode() {
62                 return rootNode;
63         }
64         
65         public GraphChanges getChanges() {
66                 return changes;
67         }
68         
69         protected UpdateNode createNode(ReadGraph g, UpdateStatus status, Resource r) throws DatabaseException {
70                 return new UpdateNode(g,status, r);
71         }
72         
73         protected UpdateNode createNode(ReadGraph g, UpdateStatus status, UpdateOp op) throws DatabaseException{
74                 return new UpdateNode(g,status, op);
75         }
76         
77         private UpdateNode createNode(ReadGraph g, Resource r1, Resource r2) throws DatabaseException {
78                 UpdateNode node = null;
79                 if (r1 != null && r2 != null) {
80                     UpdateOp op = updateOps.getUpdateOp(r1);
81                     if (op == null)
82                         op = updateOps.getUpdateOp(r2);
83             if (op == null)                     
84                 node = createNode(g, UpdateStatus.EXIST, r1);
85             else
86                 node = createNode(g, UpdateStatus.EXIST, op);
87                         nodes.put(r1, node);
88                         nodes.put(r2, node);
89                 } else if (r1 != null) {
90                         node = createNode(g,UpdateStatus.DELETED ,updateOps.getUpdateOp(r1));
91                         nodes.put(r1, node);
92                 } else if (r2 != null) {
93                         node = createNode(g,UpdateStatus.NEW, updateOps.getUpdateOp(r2));
94                         nodes.put(r2, node);
95                 }
96                 return node;
97         }
98         
99         public UpdateNode addNode(ReadGraph g, Resource r1, Resource r2) throws DatabaseException {
100                 if (nodes.containsKey(r1))
101                         return nodes.get(r1);
102                 if (nodes.containsKey(r2))
103                         return nodes.get(r2);
104                 
105                 UpdateNode node = createNode(g, r1, r2);
106                 connectParent(g,node);
107                 return node;
108         }
109         
110         public UpdateNode getNode(Resource r) {
111                 return nodes.get(r);
112         }
113         
114         protected boolean connectParent(ReadGraph g, UpdateNode node) throws DatabaseException {
115                 UpdateNode parent = null;
116                 while (true) {
117                         Resource parentResource = node.getParentResource(g);
118                         parent = nodes.get(parentResource);
119                         if (parent == null) {
120                                 parent = getOrCreate(g, parentResource);
121                                 if (parent == null)
122                                         return false;
123                                 //parent.setStatus(Status.CONTAINS);
124                                 parent.addChild(node);
125                                 node = parent;
126                                 parent = null;
127                         } else {
128                                 parent.addChild(node);
129                                 return true;
130                         }
131                         
132                 }
133         }
134         
135         protected UpdateNode getOrCreate(ReadGraph g, Resource parentResource) throws DatabaseException {
136                 UpdateNode parent = nodes.get(parentResource);
137                 if (parent == null) {
138                         if (changes.getComparable().containsLeft(parentResource)) {
139                                 parent = createNode(g, parentResource, changes.getComparable().getRight(parentResource));
140                         } else if (changes.getComparable().containsRight(parentResource)) {
141                                 parent = createNode(g, changes.getComparable().getLeft(parentResource) ,parentResource);
142                         } else {
143                                 return null;
144                         }
145                         //parent.setStatus(Status.CONTAINS
146                 } 
147                 return parent;
148         }
149         
150         
151         
152         protected boolean handleCustom(ReadGraph g, UpdateOp op) throws DatabaseException {
153                 return false;
154         }
155         
156         protected void populate(ReadGraph g) throws DatabaseException{
157
158                 for (UpdateOp op : updateOps.getOperations()) {
159                         populate(g, op);
160                 }
161                 
162         }
163         
164         protected void populate(ReadGraph g, UpdateOp op) throws DatabaseException{
165                 if (!handleCustom(g, op)) {
166                         if (op.isAdd()) {
167                                 addNode(g, null,op.getResource());
168                         } else if (op.isDelete()){
169                                 addNode(g, op.getResource(), null);
170                         } else if (op.isChange()) {
171                                 Resource o = op.getResource();
172                             Resource l = getChanges().getComparable().containsLeft(o) ? o :getChanges().getComparable().getLeft(o);
173                             Resource r = getChanges().getComparable().containsRight(o) ? o :getChanges().getComparable().getRight(o);
174                             addNode(g, l, r);
175                         }
176                 }
177         }
178         
179         protected void populate(Session session) throws DatabaseException{
180                 int i = 0;
181                 while (i < updateOps.getOperations().size()) {
182                         i = session.syncRequest(new PopulateRead(i));
183                 }
184         }
185         
186         protected class PopulateRead implements Read<Integer> {
187                 int s;
188                 public PopulateRead(int s) {
189                         this.s = s;
190                 }
191                 
192                 public Integer perform(ReadGraph graph) throws DatabaseException {
193                         int l = s + 100;
194                         if (l > updateOps.getOperations().size())
195                                 l = updateOps.getOperations().size();
196                         for (int i = s; i < l; i++) {
197                                 UpdateOp op = updateOps.getOperations().get(i);
198                                 populate(graph, op);
199                         }
200                         return l;
201                 }
202         }
203
204 }