]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop/src/org/simantics/interop/test/GraphChanges.java
3fe74177a2b93bcc71f09e90656b8ffc09858d74
[simantics/interop.git] / org.simantics.interop / src / org / simantics / interop / test / GraphChanges.java
1 package org.simantics.interop.test;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.List;
6 import java.util.Map.Entry;
7
8 import org.simantics.db.ReadGraph;
9 import org.simantics.db.Resource;
10 import org.simantics.db.Session;
11 import org.simantics.db.Statement;
12 import org.simantics.db.common.request.ReadRequest;
13 import org.simantics.db.common.utils.NameUtils;
14 import org.simantics.db.exception.DatabaseException;
15 import org.simantics.utils.datastructures.BijectionMap;
16
17 public class GraphChanges {
18         
19         private Resource r1;
20         private Resource r2;
21         private List<Statement> deletions;
22         private List<Statement> additions;
23         private List<Modification> modifications;
24         
25         private BijectionMap<Resource, Resource> comparable;
26         
27         public static class Modification {
28                 Resource leftSub;
29                 Resource rightSub;
30                 Statement leftStm;
31                 Statement rightStm;
32
33                 
34                 int hashCode;
35                 
36                 public Modification(Resource leftSub, Resource rightSub, Statement leftStm, Statement rightStm) {
37                         this.leftSub = leftSub;
38                         this.rightSub = rightSub;
39                         this.leftStm = leftStm;
40                         this.rightStm = rightStm;
41                         
42                         if (leftSub.getResourceId() < 0)
43                                 System.out.println();
44                         
45                         hashCode = leftSub.hashCode() + rightSub.hashCode();
46                         if (leftStm != null)
47                                 hashCode += leftStm.hashCode();
48                         if (rightStm != null)
49                                 hashCode += rightStm.hashCode();
50                 }
51
52                 public boolean isLeftAsserted() {
53                         return !leftSub.equals(leftStm.getSubject());
54                 }
55                 
56                 public boolean isRightAsserted() {
57                         return !rightSub.equals(rightStm.getSubject());
58                 }
59
60                 public Resource getLeftSub() {
61                         return leftSub;
62                 }
63
64                 public void setLeftSub(Resource leftSub) {
65                         this.leftSub = leftSub;
66                 }
67
68                 public Resource getRightSub() {
69                         return rightSub;
70                 }
71
72                 public void setRightSub(Resource rightSub) {
73                         this.rightSub = rightSub;
74                 }
75
76                 public Statement getLeftStm() {
77                         return leftStm;
78                 }
79
80                 public void setLeftStm(Statement leftStm) {
81                         this.leftStm = leftStm;
82                 }
83
84                 public Statement getRightStm() {
85                         return rightStm;
86                 }
87
88                 public void setRightStm(Statement rightStm) {
89                         this.rightStm = rightStm;
90                 }
91                 
92                 public Resource getPredicate() {
93                     if (leftStm != null)
94                         return leftStm.getPredicate();
95                     return rightStm.getPredicate();
96                 }
97                 
98                 @Override
99                 public boolean equals(Object obj) {
100                         if (obj.getClass() != this.getClass())
101                                 return false;
102                         Modification other = (Modification)obj;
103                         if (!leftSub.equals(other.leftSub))
104                                 return false;
105                         if (!rightSub.equals(other.rightSub))
106                                 return false;
107                         if (leftStm != null) {
108                                 if (!leftStm.equals(other.leftStm))
109                                         return false;
110                         } else if (other.leftStm != null)
111                                 return false;
112                         if (rightStm != null) {
113                                 if (!rightStm.equals(other.rightStm))
114                                         return false;
115                         } else if (other.rightStm != null)
116                                 return false;
117                         return true;
118                 }
119                 
120                 @Override
121                 public int hashCode() {
122                         return hashCode;
123                 }
124
125         }
126         
127         public GraphChanges(Resource r1, Resource r2, List<Statement> deletions, List<Statement> additions,
128                         List<Modification> modifications, BijectionMap<Resource, Resource> comparable) {
129                 super();
130                 this.r1 = r1;
131                 this.r2 = r2;
132                 this.deletions = deletions;
133                 this.additions = additions;
134                 this.modifications = modifications;
135                 this.comparable = comparable;
136         }
137         
138         public Resource getResource1() {
139                 return r1;
140         }
141         
142         public Resource getResource2() {
143                 return r2;
144         }
145         
146         public List<Statement> getAdditions() {
147                 return additions;
148         }
149         
150         public List<Statement> getDeletions() {
151                 return deletions;
152         }
153         
154         public List<Modification> getModifications() {
155                 return modifications;
156         }
157         
158         public BijectionMap<Resource, Resource> getComparable() {
159                 return comparable;
160         }
161         
162         public String toString(ReadGraph graph) throws DatabaseException {
163                 StringBuilder sb = new StringBuilder();
164                 sb.append("Del:\n");
165                 for (Statement stm : deletions) {
166                         sb.append(toString(graph, stm));
167                         sb.append("\n");
168         }
169                 sb.append("Add:\n");
170                 for (Statement stm : additions) {
171                         sb.append(toString(graph, stm));
172                         sb.append("\n");
173         }
174                 sb.append("Mod:\n");
175                 for (Modification mod :modifications) {
176                         sb.append(toString(graph, mod));
177                         sb.append("\n");
178         }
179                 return sb.toString();
180         }
181         
182         public static String toString(ReadGraph graph, Statement stm) throws DatabaseException{
183                 return NameUtils.getSafeName(graph, stm.getSubject()) + " "+
184                                    NameUtils.getSafeName(graph, stm.getPredicate()) + " " +
185                            NameUtils.getSafeName(graph, stm.getObject()) + " (" +
186                            stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject();
187         }
188         
189         public static String toString(ReadGraph graph, Modification mod) throws DatabaseException{
190                 StringBuilder sb = new StringBuilder();
191                 {
192                         Statement stm = mod.getLeftStm();
193                         if (stm != null) {
194                                 sb.append(NameUtils.getSafeName(graph, mod.getLeftSub()) + " "+
195                                                    NameUtils.getSafeName(graph, stm.getPredicate()) + " " +
196                                                    truncate(NameUtils.getSafeName(graph, stm.getObject())) + " (" +
197                                                    mod.getLeftSub() + " " + stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n");
198                         } else {
199                                 sb.append(NameUtils.getSafeName(graph, mod.getLeftSub()) + " "+  mod.getLeftSub() + " N/A\n");
200                         }
201                 }
202                 {
203                         Statement stm = mod.getRightStm();
204                         if (stm != null) {
205                                 sb.append(NameUtils.getSafeName(graph, mod.getRightSub()) + " "+
206                                                    NameUtils.getSafeName(graph, stm.getPredicate()) + " " +
207                                                    truncate(NameUtils.getSafeName(graph, stm.getObject())) + " (" +
208                                                    mod.getRightSub() + " " + stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")");
209                         } else {
210                                 sb.append(NameUtils.getSafeName(graph, mod.getRightSub()) + " "+  mod.getRightSub() + " N/A");
211                         }
212                         
213                 }
214                 return sb.toString();
215         }
216         
217         public static String truncate(String s) {
218                 if (s.length() < 100)
219                         return s;
220                 return s.substring(0, 100)+"...";
221         }
222         
223         public String comparableToString(ReadGraph graph) throws DatabaseException {
224                 StringBuilder sb = new StringBuilder();
225                 sb.append("Comparable:\n");
226                 for (Entry<Resource, Resource> entry : comparable.getEntries()) {
227                         sb.append(NameUtils.getSafeName(graph, entry.getKey()) + " "+
228                                            NameUtils.getSafeName(graph, entry.getValue()) + " (" +
229                                            entry.getKey() + " " +entry.getValue() + ")\n");
230                         
231                 }
232                 return sb.toString();
233         }
234         
235         /**
236          * Adapts GraphChanges between A1 and B to A2 and B, when A2 is copy of A1.
237          * @param changes changes between A1 and B
238          * @param bijection changes between A1 and A2. Expected to be a bijection, so no additions or removals.
239          * @return
240          * @throws DatabaseException
241          */
242         public static GraphChanges adapt(Session session, GraphChanges changes, GraphChanges bijection) throws DatabaseException{
243                 if (!changes.getResource1().equals(bijection.getResource1()))
244                         throw new DatabaseException("Left side model must be the same");
245                 //if (bijection.getDeletions().size() > 0 || bijection.getAdditions().size() > 0)
246                 //      throw new DatabaseException("Bijection change is not a bijection, it contains additions and/or removals");
247                 BijectionMap<Resource, Resource> comparable = new BijectionMap<Resource, Resource>();
248                 for (Entry<Resource, Resource> entry : changes.comparable.getEntries()) {
249                         if (entry.getKey().equals(entry.getValue())) {
250                                 comparable.map(entry.getKey(), entry.getValue());
251                         } else {
252                                 Resource nl = bijection.getComparable().getRight(entry.getKey());
253                                 if (nl == null) {
254                                         // Matching literal resources are not included in bijection map.
255                                         // TODO : should we check that the resource is literal?
256                                         // throw new DatabaseException("Did not find matching resource from bijection for " + entry.getKey());
257                                         continue;
258                                 }
259                                 comparable.map(nl, entry.getValue());
260                         }
261                 }
262                 List<Statement> deletions = new ArrayList<Statement>(changes.getDeletions().size()); // Removals must be adapted from A1 to A2.
263                 List<Statement> additions = new ArrayList<Statement>(changes.getAdditions()); // Additions can be copied, since they are statements in B.
264                 session.syncRequest(new ReadRequest() {
265                         
266                         @Override
267                         public void run(ReadGraph graph) throws DatabaseException {
268                                 for (Statement del : changes.getDeletions()) {
269                                         Resource s1 = del.getSubject();
270                                         Resource s2 = bijection.getComparable().getRight(s1);
271                                         Resource p1 = del.getPredicate();
272                                         Resource p2 = bijection.getComparable().getRight(p1);
273                                         if (p2 == null)
274                                                 p2 = p1;
275                                         Resource o1 = del.getObject();
276                                         Resource o2 = bijection.getComparable().getRight(o1);
277                                         
278                                         if (s2 == null || p2 == null || o2 == null) {
279                                                 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
280                                         }
281                                         Statement stm2 = null;
282                                         for (Statement s : graph.getStatements(s2, p2)) {
283                                                 if (s.getObject().equals(o2)) {
284                                                         stm2 = s;
285                                                         break;
286                                                 }
287                                         }
288                                         if (stm2 == null) {
289                                                 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+"), but it is not in DB!");
290                                         }
291                                         deletions.add(stm2);
292                                 }
293                                 
294                         }
295                 });
296                 
297                 List<Modification> modifications = new ArrayList<GraphChanges.Modification>(changes.getModifications().size());
298                 
299                 session.syncRequest(new ReadRequest() {
300                         
301                         @Override
302                         public void run(ReadGraph graph) throws DatabaseException {
303                                 for (Modification mod : changes.getModifications()) {
304                                         Statement del = mod.leftStm;
305                                         Resource sub1 = mod.getLeftSub();
306                                         Resource sub2 = bijection.getComparable().getRight(sub1);
307                                         if (sub2 == null) {
308                                                 throw new DatabaseException("Did not find matching resource from bijection for " + sub1);
309                                         }
310                                         Resource s1 = del.getSubject();
311                                         Resource s2 = bijection.getComparable().getRight(s1);
312                                         Resource p1 = del.getPredicate();
313                                         Resource p2 = bijection.getComparable().getRight(p1);
314                                         if (p2 == null)
315                                                 p2 = p1;
316                                         Resource o1 = del.getObject();
317                                         Resource o2 = bijection.getComparable().getRight(o1);
318                                         if (mod.isLeftAsserted()) {
319                                                 if (s2 == null)
320                                                         s2 = s1;
321                                                 if (o2 == null)
322                                                         o2 = o1;
323                                         } 
324                                         
325                                         if (s2 == null || p2 == null) {
326                                                 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
327                                         }
328                                         Collection<Statement> stms = graph.getStatements(s2, p2);
329                                         Statement stm2 = null;
330                                         if (o2 == null) {
331                                                 // Matching literal resources are not included in bijection map.
332                                                 if (stms.size() == 1) {
333                                                          stm2 = stms.iterator().next();
334                                                 } else {
335                                                          throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
336                                                 }
337                                         } else {
338                                                 for (Statement s : stms) {
339                                                         if (s.getObject().equals(o2)) {
340                                                                 stm2 = s;
341                                                                 break;
342                                                         }
343                                                 }
344                                         }
345                                         if (stm2 == null) {
346                                                 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+"), but it is not in DB!");
347                                         }
348                                         Modification mod2 = new Modification(sub2, mod.rightSub, stm2, mod.rightStm);
349                                         modifications.add(mod2);
350                                 }
351                                 
352                         }
353                 });
354                 
355                 return new GraphChanges(bijection.r2, changes.r2, deletions, additions, modifications, comparable);
356         }
357
358 }