1 package org.simantics.interop.test;
3 import java.util.ArrayList;
4 import java.util.Collection;
6 import java.util.Map.Entry;
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;
17 public class GraphChanges {
21 private List<Statement> deletions;
22 private List<Statement> additions;
23 private List<Modification> modifications;
25 private BijectionMap<Resource, Resource> comparable;
27 public static class Modification {
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;
42 hashCode = leftSub.hashCode() + rightSub.hashCode();
44 hashCode += leftStm.hashCode();
46 hashCode += rightStm.hashCode();
49 public boolean isLeftAsserted() {
50 return !leftSub.equals(leftStm.getSubject());
53 public boolean isRightAsserted() {
54 return !rightSub.equals(rightStm.getSubject());
57 public Resource getLeftSub() {
61 public void setLeftSub(Resource leftSub) {
62 this.leftSub = leftSub;
65 public Resource getRightSub() {
69 public void setRightSub(Resource rightSub) {
70 this.rightSub = rightSub;
73 public Statement getLeftStm() {
77 public void setLeftStm(Statement leftStm) {
78 this.leftStm = leftStm;
81 public Statement getRightStm() {
85 public void setRightStm(Statement rightStm) {
86 this.rightStm = rightStm;
89 public Resource getPredicate() {
91 return leftStm.getPredicate();
92 return rightStm.getPredicate();
96 public boolean equals(Object obj) {
97 if (obj.getClass() != this.getClass())
99 Modification other = (Modification)obj;
100 if (!leftSub.equals(other.leftSub))
102 if (!rightSub.equals(other.rightSub))
104 if (leftStm != null) {
105 if (!leftStm.equals(other.leftStm))
107 } else if (other.leftStm != null)
109 if (rightStm != null) {
110 if (!rightStm.equals(other.rightStm))
112 } else if (other.rightStm != null)
118 public int hashCode() {
124 public GraphChanges(Resource r1, Resource r2, List<Statement> deletions, List<Statement> additions,
125 List<Modification> modifications, BijectionMap<Resource, Resource> comparable) {
129 this.deletions = deletions;
130 this.additions = additions;
131 this.modifications = modifications;
132 this.comparable = comparable;
135 public Resource getResource1() {
139 public Resource getResource2() {
143 public List<Statement> getAdditions() {
147 public List<Statement> getDeletions() {
151 public List<Modification> getModifications() {
152 return modifications;
155 public BijectionMap<Resource, Resource> getComparable() {
159 public String toString(ReadGraph graph) throws DatabaseException {
160 StringBuilder sb = new StringBuilder();
162 for (Statement stm : deletions) {
163 sb.append(toString(graph, stm));
167 for (Statement stm : additions) {
168 sb.append(toString(graph, stm));
172 for (Modification mod :modifications) {
173 sb.append(toString(graph, mod));
176 return sb.toString();
179 public static String toString(ReadGraph graph, Statement stm) throws DatabaseException{
180 return NameUtils.getSafeName(graph, stm.getSubject()) + " "+
181 NameUtils.getSafeName(graph, stm.getPredicate()) + " " +
182 NameUtils.getSafeName(graph, stm.getObject()) + " (" +
183 stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject();
186 public static String toString(ReadGraph graph, Modification mod) throws DatabaseException{
187 StringBuilder sb = new StringBuilder();
189 Statement stm = mod.getLeftStm();
191 sb.append(NameUtils.getSafeName(graph, mod.getLeftSub()) + " "+
192 NameUtils.getSafeName(graph, stm.getPredicate()) + " " +
193 truncate(NameUtils.getSafeName(graph, stm.getObject())) + " (" +
194 mod.getLeftSub() + " " + stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")\n");
196 sb.append(NameUtils.getSafeName(graph, mod.getLeftSub()) + " "+ mod.getLeftSub() + " N/A\n");
200 Statement stm = mod.getRightStm();
202 sb.append(NameUtils.getSafeName(graph, mod.getRightSub()) + " "+
203 NameUtils.getSafeName(graph, stm.getPredicate()) + " " +
204 truncate(NameUtils.getSafeName(graph, stm.getObject())) + " (" +
205 mod.getRightSub() + " " + stm.getSubject() + " " +stm.getPredicate() + " " + stm.getObject() + ")");
207 sb.append(NameUtils.getSafeName(graph, mod.getRightSub()) + " "+ mod.getRightSub() + " N/A");
211 return sb.toString();
214 public static String truncate(String s) {
215 if (s.length() < 100)
217 return s.substring(0, 100)+"...";
220 public String comparableToString(ReadGraph graph) throws DatabaseException {
221 StringBuilder sb = new StringBuilder();
222 sb.append("Comparable:\n");
223 for (Entry<Resource, Resource> entry : comparable.getEntries()) {
224 sb.append(NameUtils.getSafeName(graph, entry.getKey()) + " "+
225 NameUtils.getSafeName(graph, entry.getValue()) + " (" +
226 entry.getKey() + " " +entry.getValue() + ")\n");
229 return sb.toString();
233 * Adapts GraphChanges between A1 and B to A2 and B, when A2 is copy of A1.
234 * @param changes changes between A1 and B
235 * @param bijection changes between A1 and A2. Expected to be a bijection, so no additions or removals.
237 * @throws DatabaseException
239 public static GraphChanges adapt(Session session, GraphChanges changes, GraphChanges bijection) throws DatabaseException{
240 if (!changes.getResource1().equals(bijection.getResource1()))
241 throw new DatabaseException("Left side model must be the same");
242 //if (bijection.getDeletions().size() > 0 || bijection.getAdditions().size() > 0)
243 // throw new DatabaseException("Bijection change is not a bijection, it contains additions and/or removals");
244 BijectionMap<Resource, Resource> comparable = new BijectionMap<Resource, Resource>();
245 for (Entry<Resource, Resource> entry : changes.comparable.getEntries()) {
246 if (entry.getKey().equals(entry.getValue())) {
247 comparable.map(entry.getKey(), entry.getValue());
249 Resource nl = bijection.getComparable().getRight(entry.getKey());
251 // Matching literal resources are not included in bijection map.
252 // TODO : should we check that the resource is literal?
253 // throw new DatabaseException("Did not find matching resource from bijection for " + entry.getKey());
256 comparable.map(nl, entry.getValue());
259 List<Statement> deletions = new ArrayList<Statement>(changes.getDeletions().size()); // Removals must be adapted from A1 to A2.
260 List<Statement> additions = new ArrayList<Statement>(changes.getAdditions()); // Additions can be copied, since they are statements in B.
261 session.syncRequest(new ReadRequest() {
264 public void run(ReadGraph graph) throws DatabaseException {
265 for (Statement del : changes.getDeletions()) {
266 Resource s1 = del.getSubject();
267 Resource s2 = bijection.getComparable().getRight(s1);
268 Resource p1 = del.getPredicate();
269 Resource p2 = bijection.getComparable().getRight(p1);
272 Resource o1 = del.getObject();
273 Resource o2 = bijection.getComparable().getRight(o1);
275 if (s2 == null || p2 == null || o2 == null) {
276 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
278 Statement stm2 = null;
279 for (Statement s : graph.getStatements(s2, p2)) {
280 if (s.getObject().equals(o2)) {
286 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+"), but it is not in DB!");
294 List<Modification> modifications = new ArrayList<GraphChanges.Modification>(changes.getModifications().size());
296 session.syncRequest(new ReadRequest() {
299 public void run(ReadGraph graph) throws DatabaseException {
300 for (Modification mod : changes.getModifications()) {
301 Statement del = mod.leftStm;
302 Resource sub1 = mod.getLeftSub();
303 Resource sub2 = bijection.getComparable().getRight(sub1);
305 throw new DatabaseException("Did not find matching resource from bijection for " + sub1);
307 Resource s1 = del.getSubject();
308 Resource s2 = bijection.getComparable().getRight(s1);
309 Resource p1 = del.getPredicate();
310 Resource p2 = bijection.getComparable().getRight(p1);
313 Resource o1 = del.getObject();
314 Resource o2 = bijection.getComparable().getRight(o1);
315 if (mod.isLeftAsserted()) {
322 if (s2 == null || p2 == null) {
323 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
325 Collection<Statement> stms = graph.getStatements(s2, p2);
326 Statement stm2 = null;
328 // Matching literal resources are not included in bijection map.
329 if (stms.size() == 1) {
330 stm2 = stms.iterator().next();
332 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
335 for (Statement s : stms) {
336 if (s.getObject().equals(o2)) {
343 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+"), but it is not in DB!");
345 Modification mod2 = new Modification(sub2, mod.rightSub, stm2, mod.rightStm);
346 modifications.add(mod2);
352 return new GraphChanges(bijection.r2, changes.r2, deletions, additions, modifications, comparable);