--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Foster Wheeler Energia Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.interop.test;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
+import java.util.List;\r
+import java.util.Stack;\r
+\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.exception.DoesNotContainValueException;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.exception.ValidationException;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.utils.datastructures.BijectionMap;\r
+import org.simantics.utils.datastructures.MapList;\r
+\r
+/**\r
+ * Compares two subgraphs and reports differences.\r
+ * \r
+ * Assumes that subgraphs (defined using traverse relations) are not cyclic.\r
+ * \r
+ * Assumes that properties can be used to identify objects, if relation type is not enough.\r
+ * \r
+ * \r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class GraphComparator {\r
+\r
+ \r
+ private List<Resource> traversed = new ArrayList<Resource>(); // list of relations that are traversed (and tested)\r
+ private List<Resource> tested = new ArrayList<Resource>(); // list of relations that are tested, but not traversed\r
+ \r
+ \r
+ private List<Statement> changes1 = new ArrayList<Statement>();\r
+ private List<Statement> changes2 = new ArrayList<Statement>();\r
+ private BijectionMap<Statement, Statement> comparable = new BijectionMap<Statement, Statement>();\r
+ \r
+ \r
+ // runtime attributes\r
+ \r
+ private ReadGraph g;\r
+ private Builtins b;\r
+ \r
+ ArrayList<Resource> rs1 = new ArrayList<Resource>();\r
+ ArrayList<Resource> rs2 = new ArrayList<Resource>();\r
+ ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
+ ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
+ Comparator<Statement> scomp = new StatementComparator();\r
+ Comparator<Resource> rcomp = new ResourceComparator();\r
+\r
+ \r
+ public void addTraversed(Resource rel) {\r
+ traversed.add(rel);\r
+ }\r
+ \r
+ public void addTraversed(Collection<Resource> rels) {\r
+ traversed.addAll(rels);\r
+ }\r
+ \r
+ public void addTested(Resource rel) {\r
+ tested.add(rel);\r
+ }\r
+ \r
+ public void addTested(Collection<Resource> rels) {\r
+ tested.addAll(rels);\r
+ }\r
+ \r
+ public void clearRels() {\r
+ traversed.clear();\r
+ tested.clear();\r
+ }\r
+ \r
+ public void test(ReadGraph g, Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
+ this.g = g;\r
+ this.b = g.getBuiltins();\r
+ \r
+ changes1.clear();\r
+ changes2.clear();\r
+ \r
+ Stack<Resource> stack1 = new Stack<Resource>();\r
+ Stack<Resource> stack2 = new Stack<Resource>();\r
+ stack1.push(r1);\r
+ stack2.push(r2);\r
+ \r
+ ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
+ ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
+ \r
+ while (!stack1.isEmpty()) {\r
+ r1 = stack1.pop();\r
+ r2 = stack2.pop();\r
+ \r
+ System.out.println("test " + GraphUtils.getReadableName(g, r1) + " " + GraphUtils.getReadableName(g, r2));\r
+ compareProps(r1, r2);\r
+ \r
+ for (Resource rel : tested) {\r
+ filterTraversed(g.getStatements(r1, rel), ss1);\r
+ filterTraversed(g.getStatements(r2, rel), ss2);\r
+ \r
+ compareStatement(ss1, ss2, null, null);\r
+ ss1.clear();\r
+ ss2.clear();\r
+ }\r
+ \r
+ for (Resource rel : traversed) {\r
+ ss1.addAll(g.getStatements(r1, rel));\r
+ ss2.addAll(g.getStatements(r2, rel));\r
+ compareStatement(ss1, ss2, stack1, stack2);\r
+ ss1.clear();\r
+ ss2.clear();\r
+ }\r
+ }\r
+ }\r
+ \r
+ public Collection<Statement> getChanges1() {\r
+ return changes1;\r
+ }\r
+ \r
+ public Collection<Statement> getChanges2() {\r
+ return changes2;\r
+ }\r
+ \r
+ public BijectionMap<Statement, Statement> getComparable() {\r
+ return comparable;\r
+ }\r
+ \r
+ private void filterTraversed(Collection<Statement> in, Collection<Statement> out) throws ServiceException {\r
+ for (Statement s : in) {\r
+ boolean usable = true;\r
+ for (Resource r : traversed) {\r
+ if (g.isSubrelationOf(s.getPredicate(),r)) {\r
+ usable = false;\r
+ break;\r
+ }\r
+ }\r
+ if (usable) {\r
+ out.add(s);\r
+ }\r
+ \r
+ }\r
+ }\r
+ \r
+ private void compareStatement(List<Statement> ss1, List<Statement> ss2, Stack<Resource> stack1, Stack<Resource> stack2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
+ Collections.sort(ss1, scomp);\r
+ Collections.sort(ss2, scomp);\r
+ \r
+ int i1 = 0;\r
+ int i2 = 0;\r
+ \r
+ while (true) {\r
+ if (i1 >= ss1.size()) {\r
+ if (i2 >= ss2.size()) {\r
+ break;\r
+ } else {\r
+ while (i2 < ss2.size()) {\r
+ changes2.add(ss2.get(i2));\r
+ i2++;\r
+ }\r
+ break;\r
+ }\r
+ } else if (i2 >= ss2.size()) {\r
+ while (i1 < ss1.size()) {\r
+ changes1.add(ss1.get(i1));\r
+ i1++;\r
+ }\r
+ break;\r
+ }\r
+ int same1 = sameRel(ss1, i1);\r
+ int same2 = sameRel(ss2, i2);\r
+ int c = rcomp.compare(ss1.get(i1).getPredicate(),ss2.get(i2).getPredicate());\r
+ if (c == 0) {\r
+ compareObject(ss1, i1, same1, ss2, i2, same2,stack1,stack2);\r
+ i1+=same1;\r
+ i2+=same2;\r
+ } else if (c < 0) {\r
+ for (int i = 0; i < same1; i++) {\r
+ changes1.add(ss1.get(i+i1));\r
+ }\r
+ i1 += same1;\r
+ } else {\r
+ for (int i = 0; i < same2; i++) {\r
+ changes2.add(ss2.get(i+i2));\r
+ }\r
+ i2 += same2;\r
+ }\r
+ \r
+ }\r
+ }\r
+ \r
+ private int sameRel(List<Statement> statements, int off) {\r
+ if (statements.size() <= off)\r
+ return 0;\r
+ int same = 1;\r
+ long id = statements.get(off).getPredicate().getResourceId();\r
+ for (int i = off+1; i <statements.size(); i++) {\r
+ if (statements.get(i).getPredicate().getResourceId() == id)\r
+ same++;\r
+ else \r
+ break;\r
+ }\r
+ return same;\r
+ \r
+ }\r
+\r
+ \r
+ private void compareObject(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2, Stack<Resource> stack1, Stack<Resource> stack2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
+ boolean[] used1 = new boolean[len1];\r
+ for (int i = 0; i < used1.length; i++) {\r
+ used1[i] = false;\r
+ }\r
+ \r
+ boolean[] used2 = new boolean[len2];\r
+ for (int i = 0; i < used2.length; i++) {\r
+ used2[i] = false;\r
+ }\r
+ \r
+ // left, right, difference\r
+ List<List<Integer>> differences = new ArrayList<List<Integer>>();\r
+ for (int i1 = off1; i1 < off1 + len1; i1++) {\r
+ Statement s1 = ss1.get(i1);\r
+ //Map<Integer,Integer> differences = new HashMap<Integer, Integer>();\r
+ List<Integer> diff = new ArrayList<Integer>();\r
+ for (int i2 = off2; i2 < off2 + len2; i2++) {\r
+ Statement s2 = ss2.get(i2);\r
+ if (!compareType(s1.getObject(), s2.getObject())) {\r
+ diff.add(Integer.MAX_VALUE);\r
+ continue;\r
+ }\r
+ diff.add(propsDiffCount(s1.getObject(), s2.getObject()));\r
+ }\r
+ differences.add(diff);\r
+ }\r
+ // difference, left\r
+ MapList<Integer, Integer> priorities = new MapList<Integer, Integer>();\r
+ for (int i = 0; i < differences.size(); i++) {\r
+ List<Integer> list = differences.get(i);\r
+ for (int j = 0; j < list.size(); j++) {\r
+ priorities.add(list.get(j), i);\r
+ }\r
+ }\r
+ \r
+ Integer[] pris = priorities.getKeys(new Integer[]{});\r
+ Arrays.sort(pris);\r
+ \r
+ for (Integer pri : pris) {\r
+ if (pri == Integer.MAX_VALUE)\r
+ continue;\r
+ List<Integer> i1s = priorities.getValues(pri);\r
+ for (Integer i1 : i1s) {\r
+ if (used1[i1])\r
+ continue;\r
+ List<Integer> i2diff = differences.get(i1);\r
+ for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
+ if (i2diff.get(i2) == pri) {\r
+ if (used2[i2])\r
+ break;\r
+ used1[i1] = true;\r
+ used2[i2] = true;\r
+ if (stack1 != null) {\r
+ stack1.add(ss1.get(i1+off1).getObject());\r
+ stack2.add(ss2.get(i2+off2).getObject());\r
+ } else {\r
+ // TODO : how should we report non traversed differences\r
+ // using compareProps assumes that referenced objects are the same (references are not different)\r
+ // using propsDiffCount assumes that objects are different, and cannot report changes in referred object.\r
+ \r
+ //compareProps(ss1.get(i1+off1).getObject(), ss2.get(i2+off2).getObject());\r
+ int diff = propsDiffCount(ss1.get(i1+off1).getObject(), ss2.get(i2+off2).getObject());\r
+ if (diff != 0) {\r
+ changes1.add(ss1.get(i1+off1));\r
+ changes2.add(ss2.get(i2+off2));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ for (int i1 = off1; i1 < off1 + len1; i1++) {\r
+ if (!used1[i1-off1])\r
+ changes1.add(ss1.get(i1));\r
+ }\r
+ for (int i2 = off2; i2 < off2 + len2; i2++) {\r
+ if (!used2[i2-off2])\r
+ changes2.add(ss2.get(i2));\r
+ }\r
+ }\r
+ \r
+ private boolean compareType(Resource r1, Resource r2) throws ServiceException, ManyObjectsForFunctionalRelationException {\r
+ rs1.addAll(g.getObjects(r1, b.InstanceOf));\r
+ rs2.addAll(g.getObjects(r2, b.InstanceOf));\r
+ if (rs1.size() != rs2.size()) {\r
+ rs1.clear();\r
+ rs2.clear();\r
+ return false;\r
+ }\r
+ Collections.sort(rs1, rcomp);\r
+ Collections.sort(rs2, rcomp);\r
+ for (int i = 0; i < rs1.size(); i++) {\r
+ int c = rcomp.compare(rs1.get(i), rs2.get(i));\r
+ if (c != 0) {\r
+ rs1.clear();\r
+ rs2.clear();\r
+ return false;\r
+ }\r
+ }\r
+ \r
+ rs1.clear();\r
+ rs2.clear();\r
+ \r
+ return true;\r
+ }\r
+ \r
+ /**\r
+ * compares properties, assumes functional relations\r
+ * @param r1\r
+ * @param r2\r
+ * @throws ManyObjectsForFunctionalRelationException\r
+ * @throws ServiceException\r
+ * @throws DoesNotContainValueException\r
+ */\r
+ private void compareProps(Resource r1, Resource r2) throws ManyObjectsForFunctionalRelationException, ServiceException, DoesNotContainValueException {\r
+ ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
+ ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
+ ss1.addAll(g.getStatements(r1, b.HasProperty));\r
+ ss2.addAll(g.getStatements(r2, b.HasProperty));\r
+ Collections.sort(ss1, scomp);\r
+ Collections.sort(ss2, scomp);\r
+ \r
+ int i1 = 0; \r
+ int i2 = 0;\r
+ \r
+ while (true) {\r
+ if (i1 >= ss1.size()) {\r
+ if (i2 >= ss2.size())\r
+ break;\r
+ else {\r
+ while (i2 < ss2.size()) {\r
+ changes2.add(ss2.get(i2));\r
+ i2++;\r
+ }\r
+ break;\r
+ }\r
+ } else if (i2 >= ss2.size()) {\r
+ while (i1 < ss1.size()) {\r
+ changes1.add(ss1.get(i1));\r
+ i1++;\r
+ }\r
+ break;\r
+ }\r
+ Statement s1 = ss1.get(i1);\r
+ Statement s2 = ss2.get(i2);\r
+ int c = scomp.compare(s1, s2);\r
+ switch (c) {\r
+ case 0:{\r
+ boolean b1 = g.hasValue(s1.getObject());\r
+ boolean b2 = g.hasValue(s2.getObject());\r
+ if (b1 == b2) {\r
+ if (b1) {\r
+ Object v1 = g.getValue(s1.getObject());\r
+ Object v2 = g.getValue(s2.getObject());\r
+ boolean eq = false;\r
+ if (v1 instanceof Object[] && v2 instanceof Object[])\r
+ eq = Arrays.deepEquals((Object[])v1, (Object[])v2);\r
+ else\r
+ eq = v1.equals(v2);\r
+ if (!eq) {\r
+ changes1.add(s1);\r
+ changes2.add(s2);\r
+ comparable.map(s1, s2);\r
+ }\r
+ } else {\r
+ compareProps(s1.getObject(), s2.getObject());\r
+ }\r
+ } else {\r
+ changes1.add(s1);\r
+ changes2.add(s2);\r
+ comparable.map(s1, s2);\r
+ }\r
+ i1++;\r
+ i2++;\r
+ break;\r
+ }\r
+ case -1:{\r
+ changes1.add(s1);\r
+ i1++;\r
+ break;\r
+ }\r
+ \r
+ case 1:{\r
+ changes2.add(s2);\r
+ i2++;\r
+ break;\r
+ }\r
+ }\r
+ \r
+ \r
+ }\r
+ \r
+ ss1.clear();\r
+ ss2.clear();\r
+ \r
+ }\r
+ \r
+ private int propsDiffCount(Resource r1, Resource r2) throws ServiceException, DoesNotContainValueException, ValidationException {\r
+ ArrayList<Statement> ss1 = new ArrayList<Statement>();\r
+ ArrayList<Statement> ss2 = new ArrayList<Statement>();\r
+ ss1.addAll(g.getStatements(r1, b.HasProperty));\r
+ ss2.addAll(g.getStatements(r2, b.HasProperty));\r
+ //System.out.println("Props count " + GraphUtils.getReadableName(g, r1) + " " + GraphUtils.getReadableName(g, r2));\r
+ Collections.sort(ss1, scomp);\r
+ Collections.sort(ss2, scomp);\r
+ \r
+ int count = 0;\r
+ \r
+ int i1 = 0; \r
+ int i2 = 0;\r
+ \r
+ while (true) {\r
+ if (i1 >= ss1.size()) {\r
+ if (i2 >= ss2.size())\r
+ break;\r
+ else {\r
+ while (i2 < ss2.size()) {\r
+ count++;\r
+ i2++;\r
+ }\r
+ break;\r
+ }\r
+ } else if (i2 >= ss2.size()) {\r
+ while (i1 < ss1.size()) {\r
+ count++;\r
+ i1++;\r
+ }\r
+ break;\r
+ }\r
+ Statement s1 = ss1.get(i1);\r
+ Statement s2 = ss2.get(i2);\r
+ int c = scomp.compare(s1, s2);\r
+ switch (c) {\r
+ case 0:{\r
+ boolean b1 = g.hasValue(s1.getObject());\r
+ boolean b2 = g.hasValue(s2.getObject());\r
+ if (b1 == b2) {\r
+ if (b1) {\r
+ Object v1 = g.getValue(s1.getObject());\r
+ Object v2 = g.getValue(s2.getObject());\r
+ boolean eq = false;\r
+ if (v1 instanceof Object[] && v2 instanceof Object[])\r
+ eq = Arrays.deepEquals((Object[])v1, (Object[])v2);\r
+ else\r
+ eq = v1.equals(v2);\r
+ if (!eq) {\r
+ count++;\r
+ }\r
+ //System.out.println("Prop count values " + v1 + " " + v2);\r
+ } else {\r
+ count += propsDiffCount(s1.getObject(), s2.getObject());\r
+ }\r
+ } else {\r
+ //System.out.println("Props count structural vs literal");\r
+ count++;\r
+ }\r
+ i1++;\r
+ i2++;\r
+ break;\r
+ }\r
+ case -1:{\r
+ count++;\r
+ i1++;\r
+ break;\r
+ }\r
+ \r
+ case 1:{\r
+ count++;\r
+ i2++;\r
+ break;\r
+ }\r
+ }\r
+ \r
+\r
+ }\r
+ \r
+ ss1.clear();\r
+ ss2.clear();\r
+ return count;\r
+ }\r
+\r
+ \r
+ \r
+ public class StatementComparator implements Comparator<Statement> {\r
+ @Override\r
+ public int compare(Statement o1, Statement o2) {\r
+ if (o1.getPredicate().getResourceId() < o2.getPredicate().getResourceId())\r
+ return -1;\r
+ if (o1.getPredicate().getResourceId() > o2.getPredicate().getResourceId())\r
+ return 1;\r
+ return 0;\r
+ }\r
+ }\r
+ \r
+\r
+ \r
+ public class ResourceComparator implements Comparator<Resource> {\r
+ @Override\r
+ public int compare(Resource o1, Resource o2) {\r
+ if (o1.getResourceId() < o2.getResourceId())\r
+ return -1;\r
+ if (o2.getResourceId() > o2.getResourceId())\r
+ return 1;\r
+ return 0;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Foster Wheeler Energia Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.interop.test;\r
+\r
+import java.io.IOException;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.dnd.DND;\r
+import org.eclipse.swt.dnd.DropTarget;\r
+import org.eclipse.swt.dnd.DropTargetAdapter;\r
+import org.eclipse.swt.dnd.DropTargetEvent;\r
+import org.eclipse.swt.dnd.TextTransfer;\r
+import org.eclipse.swt.dnd.Transfer;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.ui.part.ViewPart;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.common.ResourceArray;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.InvalidResourceReferenceException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.exception.ValidationException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.db.service.SerialisationSupport;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.dnd.LocalObjectTransfer;\r
+import org.simantics.ui.dnd.ResourceReferenceTransfer;\r
+import org.simantics.ui.dnd.ResourceTransferUtils;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.datastructures.BijectionMap;\r
+\r
+/**\r
+ * Simple multi line text viewer for seeing differences in two subgraphs. \r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class GraphComparatorViewer extends ViewPart{\r
+ \r
+ private Session session;\r
+\r
+ private Composite composite;\r
+ \r
+ private Label resourceText1;\r
+ private Label resourceText2;\r
+ \r
+ private Text text1;\r
+ private Text text2;\r
+ \r
+ private GraphComparator comparator = new GraphComparator();\r
+ \r
+ @Override\r
+ public void createPartControl(Composite parent) {\r
+ composite = new Composite(parent, SWT.NONE);\r
+ composite.setLayout(new GridLayout(2, false));\r
+ \r
+ session = SimanticsUI.getSession();\r
+ \r
+ Composite topComposite = new Composite(composite, SWT.BORDER);\r
+ topComposite.setLayout(new GridLayout(3, false));\r
+ text1 = new Text(composite, SWT.MULTI|SWT.V_SCROLL);\r
+ text2 = new Text(composite, SWT.MULTI|SWT.V_SCROLL);\r
+ \r
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).span(2, 1).applyTo(topComposite);\r
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(text1);\r
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(text2);\r
+ \r
+ resourceText1 = createDropLabel(topComposite);\r
+ resourceText2 = createDropLabel(topComposite);\r
+ \r
+ Button button = new Button(topComposite, SWT.PUSH);\r
+ button.setText("Compare");\r
+ button.addSelectionListener(new SelectionAdapter() {\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ compare();\r
+ }\r
+ });\r
+ \r
+ }\r
+ \r
+ \r
+ \r
+ private void compare() {\r
+ text1.setText("");\r
+ text2.setText("");\r
+ final Resource r1 = (Resource)resourceText1.getData();\r
+ final Resource r2 = (Resource)resourceText2.getData();\r
+ if (r1 == null || r2 == null) {\r
+ if (r1 == null)\r
+ text1.setText("Missing input!");\r
+ if (r2 == null)\r
+ text2.setText("Missing input!");\r
+ return; \r
+ }\r
+ \r
+ session.asyncRequest(new ReadRequest() {\r
+ \r
+ @Override\r
+ public void run(final ReadGraph graph) throws DatabaseException {\r
+ comparator.clearRels();\r
+ comparator.addTraversed(graph.getBuiltins().ConsistsOf);\r
+// comparator.addTested(graph.getBuiltins().IsWeaklyRelatedTo);\r
+ comparator.test(graph, r1, r2);\r
+ BijectionMap<Statement, Statement> map = comparator.getComparable();\r
+ Map<Statement, Integer> indices = new HashMap<Statement, Integer>();\r
+ final StringBuilder sb1 = new StringBuilder();\r
+ int index = 0;\r
+ for (Statement s : comparator.getChanges1()) {\r
+ String sub;\r
+ try {\r
+ \r
+ sub = GraphUtils.getReadableName(graph, s.getSubject());\r
+ String pre = GraphUtils.getReadableName(graph, s.getPredicate());\r
+ String obj = GraphUtils.getReadableName(graph, s.getObject());\r
+ if (map.containsLeft(s)) {\r
+ index++;\r
+ indices.put(s, index);\r
+ sb1.append("["+index + "] ");\r
+ }\r
+ sb1.append(sub + " - " + pre + " - " + obj + "\n");\r
+ } catch (ValidationException e) {\r
+ e.printStackTrace();\r
+ } catch (ServiceException e) {\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ }\r
+ final StringBuilder sb2 = new StringBuilder();\r
+ for (Statement s : comparator.getChanges2()) {\r
+ String sub;\r
+ try {\r
+ sub = GraphUtils.getReadableName(graph, s.getSubject());\r
+ String pre = GraphUtils.getReadableName(graph, s.getPredicate());\r
+ String obj = GraphUtils.getReadableName(graph, s.getObject());\r
+ if (map.containsRight(s)) {\r
+ index = indices.get(map.getLeft(s));\r
+ sb2.append("["+index + "] ");\r
+ }\r
+ sb2.append(sub + " - " + pre + " - " + obj + "\n");\r
+ } catch (ValidationException e) {\r
+ e.printStackTrace();\r
+ } catch (ServiceException e) {\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ }\r
+ Display.getDefault().asyncExec(new Runnable() { \r
+ @Override\r
+ public void run() {\r
+ text1.setText(sb1.toString());\r
+ text2.setText(sb2.toString());\r
+ \r
+ }\r
+ });\r
+ }\r
+ });\r
+ }\r
+ \r
+ @Override\r
+ public void setFocus() {\r
+ composite.setFocus();\r
+ }\r
+ \r
+ @Override\r
+ public void dispose() {\r
+ super.dispose();\r
+ \r
+ }\r
+ \r
+ \r
+ // copy-paste from GraphDebugger\r
+ public Label createDropLabel(Composite parent) {\r
+ final Label label = new Label(parent, SWT.BORDER);\r
+ label.setAlignment(SWT.CENTER);\r
+ label.setText("Drag a resource here to examine it in this debugger!");\r
+ label.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));\r
+ GridData data = new GridData(SWT.FILL, SWT.TOP, true, false);\r
+ data.heightHint = 16;\r
+ label.setLayoutData(data);\r
+\r
+ // Add resource id drop support to the drop-area.\r
+ DropTarget dropTarget = new DropTarget(label, DND.DROP_LINK | DND.DROP_COPY);\r
+ dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance(), ResourceReferenceTransfer.getInstance(), LocalObjectTransfer.getTransfer() });\r
+ dropTarget.addDropListener(new DropTargetAdapter() {\r
+ @Override\r
+ public void dragEnter(DropTargetEvent event) {\r
+ event.detail = DND.DROP_LINK;\r
+ //label.setBackground(green);\r
+ return;\r
+ }\r
+ @Override\r
+ public void dragLeave(DropTargetEvent event) {\r
+ label.setBackground(null);\r
+ }\r
+\r
+ @Override\r
+ public void drop(DropTargetEvent event) {\r
+ label.setBackground(null);\r
+ ResourceArray[] data = parseEventData(event);\r
+ if (data == null || data.length != 1) {\r
+ event.detail = DND.DROP_NONE;\r
+ return;\r
+ }\r
+ final ResourceArray array = data[0];\r
+ final Resource r = array.resources[array.resources.length - 1];\r
+\r
+ label.setData(r);\r
+ try {\r
+ label.setText(session.syncRequest(new Read<String>() {\r
+ @Override\r
+ public String perform(ReadGraph graph)\r
+ throws DatabaseException {\r
+ return GraphUtils.getReadableName(graph, r);\r
+ }\r
+ }));\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ private ResourceArray[] parseEventData(DropTargetEvent event) {\r
+ //System.out.println("DATA: " + event.data);\r
+ if (event.data instanceof String) {\r
+ try {\r
+ SerialisationSupport support = session.getService(SerialisationSupport.class);\r
+ return ResourceTransferUtils.readStringTransferable(support.getResourceSerializer(), (String) event.data).toResourceArrayArray();\r
+ } catch (IllegalArgumentException e) {\r
+ e.printStackTrace();\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ } catch (InvalidResourceReferenceException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ ResourceArray[] ret = ResourceAdaptionUtils.toResourceArrays(event.data);\r
+ if (ret.length > 0)\r
+ return ret;\r
+ return null;\r
+ }\r
+ });\r
+\r
+ return label;\r
+ }\r
+ \r
+ \r
+ \r
+ \r
+ \r
+ \r
+}\r