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 if (leftSub.getResourceId() < 0)
45 hashCode = leftSub.hashCode() + rightSub.hashCode();
47 hashCode += leftStm.hashCode();
49 hashCode += rightStm.hashCode();
52 public boolean isLeftAsserted() {
53 return !leftSub.equals(leftStm.getSubject());
56 public boolean isRightAsserted() {
57 return !rightSub.equals(rightStm.getSubject());
60 public Resource getLeftSub() {
64 public void setLeftSub(Resource leftSub) {
65 this.leftSub = leftSub;
68 public Resource getRightSub() {
72 public void setRightSub(Resource rightSub) {
73 this.rightSub = rightSub;
76 public Statement getLeftStm() {
80 public void setLeftStm(Statement leftStm) {
81 this.leftStm = leftStm;
84 public Statement getRightStm() {
88 public void setRightStm(Statement rightStm) {
89 this.rightStm = rightStm;
92 public Resource getPredicate() {
94 return leftStm.getPredicate();
95 return rightStm.getPredicate();
99 public boolean equals(Object obj) {
100 if (obj.getClass() != this.getClass())
102 Modification other = (Modification)obj;
103 if (!leftSub.equals(other.leftSub))
105 if (!rightSub.equals(other.rightSub))
107 if (leftStm != null) {
108 if (!leftStm.equals(other.leftStm))
110 } else if (other.leftStm != null)
112 if (rightStm != null) {
113 if (!rightStm.equals(other.rightStm))
115 } else if (other.rightStm != null)
121 public int hashCode() {
127 public GraphChanges(Resource r1, Resource r2, List<Statement> deletions, List<Statement> additions,
128 List<Modification> modifications, BijectionMap<Resource, Resource> comparable) {
132 this.deletions = deletions;
133 this.additions = additions;
134 this.modifications = modifications;
135 this.comparable = comparable;
138 public Resource getResource1() {
142 public Resource getResource2() {
146 public List<Statement> getAdditions() {
150 public List<Statement> getDeletions() {
154 public List<Modification> getModifications() {
155 return modifications;
158 public BijectionMap<Resource, Resource> getComparable() {
162 public String toString(ReadGraph graph) throws DatabaseException {
163 StringBuilder sb = new StringBuilder();
165 for (Statement stm : deletions) {
166 sb.append(toString(graph, stm));
170 for (Statement stm : additions) {
171 sb.append(toString(graph, stm));
175 for (Modification mod :modifications) {
176 sb.append(toString(graph, mod));
179 return sb.toString();
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();
189 public static String toString(ReadGraph graph, Modification mod) throws DatabaseException{
190 StringBuilder sb = new StringBuilder();
192 Statement stm = mod.getLeftStm();
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");
199 sb.append(NameUtils.getSafeName(graph, mod.getLeftSub()) + " "+ mod.getLeftSub() + " N/A\n");
203 Statement stm = mod.getRightStm();
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() + ")");
210 sb.append(NameUtils.getSafeName(graph, mod.getRightSub()) + " "+ mod.getRightSub() + " N/A");
214 return sb.toString();
217 public static String truncate(String s) {
218 if (s.length() < 100)
220 return s.substring(0, 100)+"...";
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");
232 return sb.toString();
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.
240 * @throws DatabaseException
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());
252 Resource nl = bijection.getComparable().getRight(entry.getKey());
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());
259 comparable.map(nl, entry.getValue());
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() {
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);
275 Resource o1 = del.getObject();
276 Resource o2 = bijection.getComparable().getRight(o1);
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+")");
281 Statement stm2 = null;
282 for (Statement s : graph.getStatements(s2, p2)) {
283 if (s.getObject().equals(o2)) {
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!");
297 List<Modification> modifications = new ArrayList<GraphChanges.Modification>(changes.getModifications().size());
299 session.syncRequest(new ReadRequest() {
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);
308 throw new DatabaseException("Did not find matching resource from bijection for " + sub1);
310 Resource s1 = del.getSubject();
311 Resource s2 = bijection.getComparable().getRight(s1);
312 Resource p1 = del.getPredicate();
313 Resource p2 = bijection.getComparable().getRight(p1);
316 Resource o1 = del.getObject();
317 Resource o2 = bijection.getComparable().getRight(o1);
318 if (mod.isLeftAsserted()) {
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+")");
328 Collection<Statement> stms = graph.getStatements(s2, p2);
329 Statement stm2 = null;
331 // Matching literal resources are not included in bijection map.
332 if (stms.size() == 1) {
333 stm2 = stms.iterator().next();
335 throw new DatabaseException("Did not find matching statement from bijection for (" + s1 +","+p1+","+o1+"), got (" + s2 +","+p2+","+o2+")");
338 for (Statement s : stms) {
339 if (s.getObject().equals(o2)) {
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!");
348 Modification mod2 = new Modification(sub2, mod.rightSub, stm2, mod.rightStm);
349 modifications.add(mod2);
355 return new GraphChanges(bijection.r2, changes.r2, deletions, additions, modifications, comparable);