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