-package org.simantics.debug.ui.graph;\r
-\r
-import java.awt.Point;\r
-import java.awt.event.MouseEvent;\r
-import java.awt.event.MouseListener;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.NoninvertibleTransformException;\r
-import java.awt.geom.Point2D;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collection;\r
-import java.util.Comparator;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import javax.swing.SwingUtilities;\r
-\r
-import org.eclipse.jface.layout.GridDataFactory;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.browser.Browser;\r
-import org.eclipse.swt.layout.GridData;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Composite;\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.uri.ResourceToPossibleURI;\r
-import org.simantics.db.common.utils.OrderedSetUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.exception.ValidationException;\r
-import org.simantics.db.service.ClusteringSupport;\r
-import org.simantics.debug.ui.GraphDebugger;\r
-import org.simantics.debug.ui.internal.HashMultiMap;\r
-import org.simantics.graphviz.Edge;\r
-import org.simantics.graphviz.Graph;\r
-import org.simantics.graphviz.IGraphPart;\r
-import org.simantics.graphviz.Node;\r
-import org.simantics.graphviz.drawable.ViewerCanvas;\r
-import org.simantics.graphviz.ui.GraphvizComponent2;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.utils.datastructures.BijectionMap;\r
-import org.simantics.utils.datastructures.MapList;\r
-import org.simantics.utils.ui.ErrorLogger;\r
-\r
-\r
-\r
-public class GraphicalDebugger extends GraphDebugger {\r
- \r
- public enum Style{dot,neato,fdp,sfdp,twopi,circo};\r
- \r
- private Graph graph;\r
- private BijectionMap<Resource, Node> nodeMap = new BijectionMap<Resource, Node>();\r
- private MapList<Resource, Edge> edgeMap = new MapList<Resource, Edge>();\r
- private Map<Edge,Resource> edgeMap2 = new HashMap<Edge, Resource>();\r
- private Set<Resource> processed = new HashSet<Resource>();\r
- \r
- private GraphvizComponent2 graphVizComponent;\r
- \r
- private int depth = 1;\r
- private Style style = Style.dot;\r
- \r
- public GraphicalDebugger(Composite parent, int style, final Session session, Resource resource) {\r
- super(parent, style, session, resource);\r
- }\r
- \r
- public void defaultInitializeUI() {\r
- setLayout(new GridLayout(2, false));\r
- setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
-\r
- createResourceText(this);\r
- createDropLabel(this);\r
- createGraph(this);\r
-\r
- }\r
- \r
- public int getDepth() {\r
- return depth;\r
- }\r
- \r
- public void setDepth(int depth) {\r
- if (depth < 1)\r
- return;\r
- if(depth == this.depth)\r
- return;\r
- this.depth = depth;\r
- refreshBrowser();\r
- }\r
- \r
- public Style getGraphStyle() {\r
- return style;\r
- }\r
- \r
- public void setGraphStyle(Style style) {\r
- if (this.style == style)\r
- return;\r
- this.style = style;\r
- refreshBrowser();\r
- }\r
- \r
- @Override\r
- protected void initializeCSS() {\r
- // do nothing\r
- }\r
- \r
- @Override\r
- public Browser createBrowser(Composite parent) {\r
- // do nothing\r
- return null;\r
- }\r
- \r
- public GraphvizComponent2 createGraph(Composite parent) {\r
- graph = new Graph();\r
- graph.setRankdir("LR");\r
- graphVizComponent = new GraphvizComponent2(parent, SWT.NONE);\r
- SwingUtilities.invokeLater(new Runnable() {\r
- \r
- @Override\r
- public void run() {\r
- graphVizComponent.getCanvas().addMouseListener(new MouseListener() {\r
- \r
- @Override\r
- public void mouseReleased(MouseEvent arg0) {\r
-\r
- }\r
- \r
- @Override\r
- public void mousePressed(MouseEvent arg0) {\r
-\r
- }\r
- \r
- @Override\r
- public void mouseExited(MouseEvent arg0) {\r
-\r
- }\r
- \r
- @Override\r
- public void mouseEntered(MouseEvent arg0) {\r
-\r
- }\r
- \r
- @Override\r
- public void mouseClicked(MouseEvent arg0) {\r
- if (arg0.getClickCount() > 1) {\r
- Point p = arg0.getPoint();\r
- pick(p);\r
- }\r
- }\r
- });\r
- }\r
- });\r
-\r
- GridDataFactory.fillDefaults().span(2, 1).grab(true, true).applyTo(graphVizComponent);\r
- refreshBrowser();\r
- return graphVizComponent;\r
- }\r
- \r
- protected void pick(Point p) {\r
- \r
- AffineTransform at = ((ViewerCanvas)graphVizComponent.getCanvas()).getTransform();\r
- Point2D pickPoint = new Point2D.Double();\r
- try {\r
- at.inverseTransform(new Point2D.Double((double)p.x,(double)p.y), pickPoint);\r
- } catch (NoninvertibleTransformException e) {\r
- return;\r
- }\r
-\r
- Collection<IGraphPart> parts = graphVizComponent.getDrawable().pick(pickPoint);\r
- for (IGraphPart part : parts) {\r
- if (part instanceof Node) {\r
- Resource r = nodeMap.getLeft((Node)part);\r
- if (r != null && !r.equals(getDebuggerLocation())) {\r
- changeLocation(r);\r
- return;\r
- } \r
- \r
- } \r
- }\r
- for (IGraphPart part : parts) {\r
- if (part instanceof Edge) {\r
- Resource r = edgeMap2.get(part);\r
- if (r != null && !r.equals(getDebuggerLocation())) {\r
- changeLocation(r);\r
- return;\r
- }\r
- }\r
- }\r
- }\r
- \r
- protected Node getOrCreate(Resource r) {\r
- Node n = nodeMap.getRight(r);\r
- if (n == null) {\r
- n = new Node(graph);\r
- if (!r.isPersistent()) {\r
- n.setShape("box");\r
- n.setFontColor("blue");\r
- }\r
- nodeMap.map(r, n);\r
- }\r
- return n;\r
- }\r
- \r
- @SuppressWarnings("unused")\r
- protected void appendLabel(Node node, String text) {\r
- String label = node.get("label");\r
- if (true) {\r
- if (label == null || label.length() == 0)\r
- label = text;//escape(text);\r
- else {\r
- label = label.substring(1,label.length()-1);\r
- label += "<br/>"+text;\r
- }\r
- label = "<" + label + ">";\r
- } else {\r
- if (label == null || label.length() == 0)\r
- label = text;\r
- else {\r
- label += " "+text;\r
- }\r
- \r
- }\r
- node.setLabel(label);\r
- }\r
- \r
-\r
-\r
- \r
- protected synchronized void updateContent(final ReadGraph g, Resource... resources) throws DatabaseException {\r
- L0 = Layer0.getInstance(g);\r
- \r
- graph = new Graph();\r
- graph.setRankdir("LR");\r
- \r
- nodeMap.clear();\r
- edgeMap.clear();\r
- edgeMap2.clear();\r
- processed.clear();\r
- \r
- //links.clear();\r
- //StringBuffer content = new StringBuffer();\r
-\r
- // Generate HTML -page\r
-// content.append("<html><head>" + getHead() + "</head>\n");\r
-// content.append("<body>\n");\r
-// content.append("<div id=\"mainContent\">\n");\r
-\r
- // content.append("</div>\n");\r
- //content.append("</body></html>\n");\r
- createContent(g, depth, resources);\r
- \r
- // Update content\r
- //graph.write(System.out);\r
- graphVizComponent.setGraph(graph,style.toString());\r
- }\r
- \r
- private void createContent(final ReadGraph g, int iter, Resource... resources) throws DatabaseException {\r
- if (iter == 0)\r
- return;\r
- for (Resource r : resources) {\r
- if (r == null)\r
- continue;\r
- if (processed.contains(r))\r
- continue;\r
- Node node = getResourceRef(g, r);\r
- if (r.equals(getDebuggerLocation())) {\r
- node.setFillColor("#aaffaa");\r
- node.setStyle("filled");\r
- }\r
- //Node node = getOrCreate(r);\r
- processed.add(r);\r
- \r
- \r
- \r
- String uri = null;\r
- try {\r
- uri = g.syncRequest(new ResourceToPossibleURI(r));\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- uri = "Cannot get URI: " + e.getMessage();\r
- }\r
- if (uri != null)\r
- appendLabel(node, "URI: " + uri);\r
- //content.append("\t\t<div class=\"monospaced\">" + uri + "</div><br/>");\r
-\r
- Collection<Statement> statements = g.getStatements(r, L0.IsWeaklyRelatedTo);\r
- HashMultiMap<Resource, Resource[]> map = new HashMultiMap<Resource, Resource[]>();\r
- for(org.simantics.db.Statement statement : statements) {\r
- Resource predicate = null;\r
- Resource subject = null;\r
- Resource obj = null;\r
- try {\r
- predicate = statement.getPredicate();\r
- subject = statement.getSubject();\r
- obj = statement.getObject();\r
- map.add(predicate, new Resource[] {subject, obj});\r
- } catch (Throwable e) {\r
- e.printStackTrace();\r
- ErrorLogger.defaultLogError("Cannot find statement " + subject + " " + predicate + " " + obj, e);\r
- }\r
- }\r
- ClusteringSupport support = g.getSession().getService(ClusteringSupport.class);\r
- //content.append("<h3>" + " ["+ r.getResourceId() + "-" + support.getCluster(r) + "] " + "</h3>\n");\r
- appendLabel(node, " ["+ r.getResourceId() + "-" + support.getCluster(r) + "]");\r
- \r
- //content.append("<table>\n");\r
- //content.append("<tr><th>Predicate</th><th>Object</th></tr>");\r
- //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Basic information</td></tr>");\r
-\r
- boolean isOrderedSet = g.isInstanceOf(r, L0.OrderedSet);\r
- map.remove(r);\r
-\r
- // BASIC INFORMATION:\r
- for (Resource pred :\r
- new Resource[] {L0.HasName, L0.InstanceOf,\r
- L0.Inherits, L0.SubrelationOf,\r
- L0.ConsistsOf, L0.PartOf})\r
- if (map.containsKey(pred))\r
- updatePred(node, g, r, pred, map.remove(pred));\r
-\r
- // TAGS\r
- //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Tags</td></tr>");\r
- for(Statement stm : statements) {\r
- if(stm.getSubject().equals(stm.getObject())) {\r
- updateTag(node, g, r, stm.getPredicate(), "Tag");\r
- map.remove(stm.getPredicate());\r
- }\r
- }\r
-\r
- // ORDERED SETS\r
- //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Ordered Sets</td></tr>");\r
- for(Statement stm : statements) {\r
- Resource predicate = stm.getPredicate();\r
- if(g.isInstanceOf(stm.getPredicate(), L0.OrderedSet)) {\r
- updateTag(node, g, r, stm.getPredicate(), "Ordered Set");\r
- map.remove(stm.getPredicate());\r
- }\r
- Resource inverse = g.getPossibleInverse(predicate);\r
- if (inverse != null) {\r
- if(g.isInstanceOf(inverse, L0.OrderedSet)) {\r
- map.remove(stm.getPredicate());\r
- }\r
- } else {\r
- // FIXME : should we inform missing inverse\r
- }\r
- }\r
-\r
- // IS RELATED TO\r
- //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Is Related To</td></tr>");\r
-\r
- // ELEMENTS OF ORDERED SET\r
- if(isOrderedSet) {\r
- //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Ordered set</td></tr>");\r
- try {\r
- updateOrderedSet(node, g, r);\r
- } catch (ValidationException e) {\r
- //content.append("<td colspan=\"2\"><span style=\"color:red;font-weight:bold\">BROKEN ORDERED SET:<br/></span><span style=\"color:red\">" + e.getMessage() + "</span></td>");\r
- }\r
- }\r
-\r
- // IS RELATED TO (other)\r
- Resource[] preds = map.keySet().toArray(new Resource[0]);\r
- final Map<Resource, String> strmap = new HashMap<Resource, String>(preds.length);\r
- for(Resource pred : preds) {\r
- String str = htmlEscape(getResourceName(g, pred));\r
- if(str == null)\r
- str = "<null>";\r
- strmap.put(pred, str);\r
- }\r
- Arrays.sort(preds, new Comparator<Resource>() {\r
- @Override\r
- public int compare(Resource o1, Resource o2) {\r
- return strmap.get(o1).compareTo(strmap.get(o2));\r
- }\r
- });\r
- for(Resource pred : preds)\r
- if(g.isSubrelationOf(pred, L0.IsRelatedTo))\r
- updatePred(node, g, r, pred, map.get(pred));\r
-\r
- // OTHER STATEMENTS\r
- //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Other statements</td></tr>");\r
- for(Resource pred : preds)\r
- if(!g.isSubrelationOf(pred, L0.IsRelatedTo))\r
- updatePred(node, g, r, pred, map.get(pred));\r
- // content.append("</table>\n");\r
- \r
- Resource objects[] = new Resource[statements.size()];\r
- int i = 0;\r
- for (Statement stm : statements) {\r
- objects[i] = stm.getObject();\r
- i++;\r
- }\r
- createContent(g, iter-1, objects);\r
- }\r
- }\r
- \r
- private Node getResourceRef(ReadGraph graph, Resource r) throws DatabaseException {\r
- Node node = nodeMap.getRight(r);\r
- if (node == null) {\r
- node = getOrCreate(r);\r
- appendLabel(node, htmlEscape(getResourceName(graph, r)));\r
- }\r
- return node;\r
- }\r
- \r
- private class NodeObject {\r
- public String name;\r
- public Node node;\r
- @SuppressWarnings("unused")\r
- public Resource r;\r
- \r
- }\r
- \r
- private void updatePred(Node node, ReadGraph graph, Resource subj, Resource pred, List<Resource[]> stats) throws DatabaseException {\r
- // Generate output content from statements\r
- NodeObject[] objects = new NodeObject[stats.size()];\r
- for (int i = 0; i < stats.size(); ++i) {\r
- Resource stmSubject = stats.get(i)[0];\r
- Resource object = stats.get(i)[1];\r
-\r
- objects[i] = new NodeObject();\r
- objects[i].r = object;\r
- objects[i].name = htmlEscape( getResourceName(graph, object) );\r
- objects[i].node = getResourceRef(graph, object);\r
-\r
- // Make a note if the statement was acquired.\r
- if(!stmSubject.equals(subj)) {\r
- Node asserted = getResourceRef(graph, stmSubject);\r
- Edge e = new Edge(this.graph, objects[i].node, asserted);\r
- e.setLabel("Asserted in");\r
- \r
- objects[i].node.setFillColor("#ffaaaa");\r
- objects[i].node.setStyle("filled");\r
- }\r
- }\r
-\r
- // Sort statements by object name\r
- Arrays.sort(objects, new Comparator<NodeObject>() {\r
- @Override\r
- public int compare(NodeObject o1, NodeObject o2) {\r
- return o1.name.compareTo(o2.name);\r
- }\r
- });\r
-\r
- String predName = getResourceName(graph, pred);\r
- // Output table rows\r
- for (int i = 0; i < objects.length; ++i) {\r
- Edge e = new Edge(this.graph,node, objects[i].node);\r
- e.setLabel(predName);\r
- edgeMap.add(pred, e);\r
- edgeMap2.put(e, pred);\r
- //content.append("<tr>");\r
- // Predicate column\r
- //if (i == 0)\r
- //content.append("<td rowspan=\"" + objects.length + "\" valign=\"top\">" + getResourceRef(graph, pred) + "</td>");\r
-\r
- // Object column\r
- //if (objects[i][3] == null) content.append("<td>");\r
- //else content.append("<td class=\"acquired\">");\r
-\r
- //content.append(objects[i][2]);\r
- //if (objects[i][3] != null)\r
- // content.append(objects[i][3]);\r
-\r
- //content.append("</td>");\r
-\r
- // Statement remove -link column\r
- // Only allowed for non-acquired statements.\r
- //if (objects[i][3] == null) {\r
- // content.append("<td class=\"remove\">");\r
- // content.append(getStatementRemoveRef(subj, pred, links.getRight(objects[i][0])));\r
- // content.append("</td>");\r
- //}\r
- //content.append("</tr>");\r
- }\r
- }\r
- \r
- private void updateTag(Node node, ReadGraph graph, Resource subj, Resource tag, String title) throws DatabaseException {\r
-\r
- // Generate output content from statements\r
- Node ref = getResourceRef(graph, tag);\r
- Edge e = new Edge(this.graph, node, ref);\r
- e.setLabel(title);\r
- \r
-// content.append("<tr>");\r
-// content.append("<td rowspan=\"1\" colspan=\"2\" valign=\"top\">" + ref + "</td>");\r
-// content.append("<td class=\"remove\">");\r
-// content.append(getStatementRemoveRef(subj, tag, subj));\r
-// content.append("</td>");\r
-// content.append("</tr>");\r
-\r
- }\r
- \r
- \r
- \r
- private void updateOrderedSet(Node node, ReadGraph graph, Resource subj) throws DatabaseException {\r
-\r
-// StringBuffer content = new StringBuffer();\r
- //List<String> list = new ArrayList<String>();\r
- List<Node> list = new ArrayList<Node>();\r
- Resource cur = subj;\r
- while(true) {\r
- try {\r
- cur = OrderedSetUtils.next(graph, subj, cur);\r
- } catch(DatabaseException e) {\r
- Edge edge = new Edge(this.graph, node, node);\r
- edge.setLabel("Broken Ordered Set");\r
- //list.add("<span style=\"color:red;font-weight:bold\">BROKEN ORDERED SET:<br/></span><span style=\"color:red\">" + e.getMessage() + "</span>");\r
-// Resource inv = graph.getPossibleInverse(subj);\r
-// for(Statement stat : graph.getStatements(cur, L0.IsRelatedTo)) {\r
-// if(stat.getSubject().equals(cur)) {\r
-// if(stat.getPredicate().equals(subj)) {\r
-// list.add("next " + getResourceRef(graph, stat.getObject()));\r
-// }\r
-// else if(stat.getPredicate().equals(inv)) {\r
-// list.add("prev " + getResourceRef(graph, stat.getObject()));\r
-// }\r
-// }\r
-// }\r
-// break;\r
- }\r
- if(cur.equals(subj))\r
- break;\r
- //list.add(getResourceName(graph, cur));\r
- list.add(getResourceRef(graph, cur));\r
- }\r
- for (int i = 0; i < list.size() ; ++i) {\r
- Edge e = new Edge(this.graph, node, list.get(i));\r
- e.setLabel("Oredered set item " + i);\r
- }\r
-\r
- // Output table rows\r
-// content.append("<table>\n");\r
-// for (int i = 0; i < list.size() ; ++i) {\r
-// content.append("<tr>");\r
-// // Predicate column\r
-// if (i == 0)\r
-// content.append("<td rowspan=\"" + list.size() + "\" valign=\"top\">Ordered Set Elements</td>");\r
-//\r
-// // Object column\r
-// content.append("<td>");\r
-// content.append(list.get(i));\r
-// content.append("</td>");\r
-//\r
-// content.append("</tr>");\r
-// }\r
-// content.append("</table>\n");\r
-// appendLabel(node, content.toString());\r
- }\r
- \r
- \r
- \r
-}\r
+package org.simantics.debug.ui.graph;
+
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.SwingUtilities;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.Statement;
+import org.simantics.db.common.uri.ResourceToPossibleURI;
+import org.simantics.db.common.utils.OrderedSetUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ValidationException;
+import org.simantics.db.service.ClusteringSupport;
+import org.simantics.debug.ui.GraphDebugger;
+import org.simantics.debug.ui.internal.HashMultiMap;
+import org.simantics.graphviz.Edge;
+import org.simantics.graphviz.Graph;
+import org.simantics.graphviz.IGraphPart;
+import org.simantics.graphviz.Node;
+import org.simantics.graphviz.drawable.ViewerCanvas;
+import org.simantics.graphviz.ui.GraphvizComponent2;
+import org.simantics.layer0.Layer0;
+import org.simantics.utils.datastructures.BijectionMap;
+import org.simantics.utils.datastructures.MapList;
+import org.simantics.utils.ui.ErrorLogger;
+
+
+
+public class GraphicalDebugger extends GraphDebugger {
+
+ public enum Style{dot,neato,fdp,sfdp,twopi,circo};
+
+ private Graph graph;
+ private BijectionMap<Resource, Node> nodeMap = new BijectionMap<Resource, Node>();
+ private MapList<Resource, Edge> edgeMap = new MapList<Resource, Edge>();
+ private Map<Edge,Resource> edgeMap2 = new HashMap<Edge, Resource>();
+ private Set<Resource> processed = new HashSet<Resource>();
+
+ private GraphvizComponent2 graphVizComponent;
+
+ private int depth = 1;
+ private Style style = Style.dot;
+
+ public GraphicalDebugger(Composite parent, int style, final Session session, Resource resource) {
+ super(parent, style, session, resource);
+ }
+
+ public void defaultInitializeUI() {
+ setLayout(new GridLayout(2, false));
+ setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ createResourceText(this);
+ createDropLabel(this);
+ createGraph(this);
+
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public void setDepth(int depth) {
+ if (depth < 1)
+ return;
+ if(depth == this.depth)
+ return;
+ this.depth = depth;
+ refreshBrowser();
+ }
+
+ public Style getGraphStyle() {
+ return style;
+ }
+
+ public void setGraphStyle(Style style) {
+ if (this.style == style)
+ return;
+ this.style = style;
+ refreshBrowser();
+ }
+
+ @Override
+ protected void initializeCSS() {
+ // do nothing
+ }
+
+ @Override
+ public Browser createBrowser(Composite parent) {
+ // do nothing
+ return null;
+ }
+
+ public GraphvizComponent2 createGraph(Composite parent) {
+ graph = new Graph();
+ graph.setRankdir("LR");
+ graphVizComponent = new GraphvizComponent2(parent, SWT.NONE);
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ graphVizComponent.getCanvas().addMouseListener(new MouseListener() {
+
+ @Override
+ public void mouseReleased(MouseEvent arg0) {
+
+ }
+
+ @Override
+ public void mousePressed(MouseEvent arg0) {
+
+ }
+
+ @Override
+ public void mouseExited(MouseEvent arg0) {
+
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent arg0) {
+
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent arg0) {
+ if (arg0.getClickCount() > 1) {
+ Point p = arg0.getPoint();
+ pick(p);
+ }
+ }
+ });
+ }
+ });
+
+ GridDataFactory.fillDefaults().span(2, 1).grab(true, true).applyTo(graphVizComponent);
+ refreshBrowser();
+ return graphVizComponent;
+ }
+
+ protected void pick(Point p) {
+
+ AffineTransform at = ((ViewerCanvas)graphVizComponent.getCanvas()).getTransform();
+ Point2D pickPoint = new Point2D.Double();
+ try {
+ at.inverseTransform(new Point2D.Double((double)p.x,(double)p.y), pickPoint);
+ } catch (NoninvertibleTransformException e) {
+ return;
+ }
+
+ Collection<IGraphPart> parts = graphVizComponent.getDrawable().pick(pickPoint);
+ for (IGraphPart part : parts) {
+ if (part instanceof Node) {
+ Resource r = nodeMap.getLeft((Node)part);
+ if (r != null && !r.equals(getDebuggerLocation())) {
+ changeLocation(r);
+ return;
+ }
+
+ }
+ }
+ for (IGraphPart part : parts) {
+ if (part instanceof Edge) {
+ Resource r = edgeMap2.get(part);
+ if (r != null && !r.equals(getDebuggerLocation())) {
+ changeLocation(r);
+ return;
+ }
+ }
+ }
+ }
+
+ protected Node getOrCreate(Resource r) {
+ Node n = nodeMap.getRight(r);
+ if (n == null) {
+ n = new Node(graph);
+ if (!r.isPersistent()) {
+ n.setShape("box");
+ n.setFontColor("blue");
+ }
+ nodeMap.map(r, n);
+ }
+ return n;
+ }
+
+ @SuppressWarnings("unused")
+ protected void appendLabel(Node node, String text) {
+ String label = node.get("label");
+ if (true) {
+ if (label == null || label.length() == 0)
+ label = text;//escape(text);
+ else {
+ label = label.substring(1,label.length()-1);
+ label += "<br/>"+text;
+ }
+ label = "<" + label + ">";
+ } else {
+ if (label == null || label.length() == 0)
+ label = text;
+ else {
+ label += " "+text;
+ }
+
+ }
+ node.setLabel(label);
+ }
+
+
+
+
+ protected synchronized void updateContent(final ReadGraph g, Resource... resources) throws DatabaseException {
+ L0 = Layer0.getInstance(g);
+
+ graph = new Graph();
+ graph.setRankdir("LR");
+
+ nodeMap.clear();
+ edgeMap.clear();
+ edgeMap2.clear();
+ processed.clear();
+
+ //links.clear();
+ //StringBuffer content = new StringBuffer();
+
+ // Generate HTML -page
+// content.append("<html><head>" + getHead() + "</head>\n");
+// content.append("<body>\n");
+// content.append("<div id=\"mainContent\">\n");
+
+ // content.append("</div>\n");
+ //content.append("</body></html>\n");
+ createContent(g, depth, resources);
+
+ // Update content
+ //graph.write(System.out);
+ graphVizComponent.setGraph(graph,style.toString());
+ }
+
+ private void createContent(final ReadGraph g, int iter, Resource... resources) throws DatabaseException {
+ if (iter == 0)
+ return;
+ for (Resource r : resources) {
+ if (r == null)
+ continue;
+ if (processed.contains(r))
+ continue;
+ Node node = getResourceRef(g, r);
+ if (r.equals(getDebuggerLocation())) {
+ node.setFillColor("#aaffaa");
+ node.setStyle("filled");
+ }
+ //Node node = getOrCreate(r);
+ processed.add(r);
+
+
+
+ String uri = null;
+ try {
+ uri = g.syncRequest(new ResourceToPossibleURI(r));
+ } catch (Exception e) {
+ e.printStackTrace();
+ uri = "Cannot get URI: " + e.getMessage();
+ }
+ if (uri != null)
+ appendLabel(node, "URI: " + uri);
+ //content.append("\t\t<div class=\"monospaced\">" + uri + "</div><br/>");
+
+ Collection<Statement> statements = g.getStatements(r, L0.IsWeaklyRelatedTo);
+ HashMultiMap<Resource, Resource[]> map = new HashMultiMap<Resource, Resource[]>();
+ for(org.simantics.db.Statement statement : statements) {
+ Resource predicate = null;
+ Resource subject = null;
+ Resource obj = null;
+ try {
+ predicate = statement.getPredicate();
+ subject = statement.getSubject();
+ obj = statement.getObject();
+ map.add(predicate, new Resource[] {subject, obj});
+ } catch (Throwable e) {
+ e.printStackTrace();
+ ErrorLogger.defaultLogError("Cannot find statement " + subject + " " + predicate + " " + obj, e);
+ }
+ }
+ ClusteringSupport support = g.getSession().getService(ClusteringSupport.class);
+ //content.append("<h3>" + " ["+ r.getResourceId() + "-" + support.getCluster(r) + "] " + "</h3>\n");
+ appendLabel(node, " ["+ r.getResourceId() + "-" + support.getCluster(r) + "]");
+
+ //content.append("<table>\n");
+ //content.append("<tr><th>Predicate</th><th>Object</th></tr>");
+ //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Basic information</td></tr>");
+
+ boolean isOrderedSet = g.isInstanceOf(r, L0.OrderedSet);
+ map.remove(r);
+
+ // BASIC INFORMATION:
+ for (Resource pred :
+ new Resource[] {L0.HasName, L0.InstanceOf,
+ L0.Inherits, L0.SubrelationOf,
+ L0.ConsistsOf, L0.PartOf})
+ if (map.containsKey(pred))
+ updatePred(node, g, r, pred, map.remove(pred));
+
+ // TAGS
+ //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Tags</td></tr>");
+ for(Statement stm : statements) {
+ if(stm.getSubject().equals(stm.getObject())) {
+ updateTag(node, g, r, stm.getPredicate(), "Tag");
+ map.remove(stm.getPredicate());
+ }
+ }
+
+ // ORDERED SETS
+ //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Ordered Sets</td></tr>");
+ for(Statement stm : statements) {
+ Resource predicate = stm.getPredicate();
+ if(g.isInstanceOf(stm.getPredicate(), L0.OrderedSet)) {
+ updateTag(node, g, r, stm.getPredicate(), "Ordered Set");
+ map.remove(stm.getPredicate());
+ }
+ Resource inverse = g.getPossibleInverse(predicate);
+ if (inverse != null) {
+ if(g.isInstanceOf(inverse, L0.OrderedSet)) {
+ map.remove(stm.getPredicate());
+ }
+ } else {
+ // FIXME : should we inform missing inverse
+ }
+ }
+
+ // IS RELATED TO
+ //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Is Related To</td></tr>");
+
+ // ELEMENTS OF ORDERED SET
+ if(isOrderedSet) {
+ //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Ordered set</td></tr>");
+ try {
+ updateOrderedSet(node, g, r);
+ } catch (ValidationException e) {
+ //content.append("<td colspan=\"2\"><span style=\"color:red;font-weight:bold\">BROKEN ORDERED SET:<br/></span><span style=\"color:red\">" + e.getMessage() + "</span></td>");
+ }
+ }
+
+ // IS RELATED TO (other)
+ Resource[] preds = map.keySet().toArray(new Resource[0]);
+ final Map<Resource, String> strmap = new HashMap<Resource, String>(preds.length);
+ for(Resource pred : preds) {
+ String str = htmlEscape(getResourceName(g, pred));
+ if(str == null)
+ str = "<null>";
+ strmap.put(pred, str);
+ }
+ Arrays.sort(preds, new Comparator<Resource>() {
+ @Override
+ public int compare(Resource o1, Resource o2) {
+ return strmap.get(o1).compareTo(strmap.get(o2));
+ }
+ });
+ for(Resource pred : preds)
+ if(g.isSubrelationOf(pred, L0.IsRelatedTo))
+ updatePred(node, g, r, pred, map.get(pred));
+
+ // OTHER STATEMENTS
+ //content.append("<tr><td class=\"subtitle\" colspan=\"2\">Other statements</td></tr>");
+ for(Resource pred : preds)
+ if(!g.isSubrelationOf(pred, L0.IsRelatedTo))
+ updatePred(node, g, r, pred, map.get(pred));
+ // content.append("</table>\n");
+
+ Resource objects[] = new Resource[statements.size()];
+ int i = 0;
+ for (Statement stm : statements) {
+ objects[i] = stm.getObject();
+ i++;
+ }
+ createContent(g, iter-1, objects);
+ }
+ }
+
+ private Node getResourceRef(ReadGraph graph, Resource r) throws DatabaseException {
+ Node node = nodeMap.getRight(r);
+ if (node == null) {
+ node = getOrCreate(r);
+ appendLabel(node, htmlEscape(getResourceName(graph, r)));
+ }
+ return node;
+ }
+
+ private class NodeObject {
+ public String name;
+ public Node node;
+ @SuppressWarnings("unused")
+ public Resource r;
+
+ }
+
+ private void updatePred(Node node, ReadGraph graph, Resource subj, Resource pred, List<Resource[]> stats) throws DatabaseException {
+ // Generate output content from statements
+ NodeObject[] objects = new NodeObject[stats.size()];
+ for (int i = 0; i < stats.size(); ++i) {
+ Resource stmSubject = stats.get(i)[0];
+ Resource object = stats.get(i)[1];
+
+ objects[i] = new NodeObject();
+ objects[i].r = object;
+ objects[i].name = htmlEscape( getResourceName(graph, object) );
+ objects[i].node = getResourceRef(graph, object);
+
+ // Make a note if the statement was acquired.
+ if(!stmSubject.equals(subj)) {
+ Node asserted = getResourceRef(graph, stmSubject);
+ Edge e = new Edge(this.graph, objects[i].node, asserted);
+ e.setLabel("Asserted in");
+
+ objects[i].node.setFillColor("#ffaaaa");
+ objects[i].node.setStyle("filled");
+ }
+ }
+
+ // Sort statements by object name
+ Arrays.sort(objects, new Comparator<NodeObject>() {
+ @Override
+ public int compare(NodeObject o1, NodeObject o2) {
+ return o1.name.compareTo(o2.name);
+ }
+ });
+
+ String predName = getResourceName(graph, pred);
+ // Output table rows
+ for (int i = 0; i < objects.length; ++i) {
+ Edge e = new Edge(this.graph,node, objects[i].node);
+ e.setLabel(predName);
+ edgeMap.add(pred, e);
+ edgeMap2.put(e, pred);
+ //content.append("<tr>");
+ // Predicate column
+ //if (i == 0)
+ //content.append("<td rowspan=\"" + objects.length + "\" valign=\"top\">" + getResourceRef(graph, pred) + "</td>");
+
+ // Object column
+ //if (objects[i][3] == null) content.append("<td>");
+ //else content.append("<td class=\"acquired\">");
+
+ //content.append(objects[i][2]);
+ //if (objects[i][3] != null)
+ // content.append(objects[i][3]);
+
+ //content.append("</td>");
+
+ // Statement remove -link column
+ // Only allowed for non-acquired statements.
+ //if (objects[i][3] == null) {
+ // content.append("<td class=\"remove\">");
+ // content.append(getStatementRemoveRef(subj, pred, links.getRight(objects[i][0])));
+ // content.append("</td>");
+ //}
+ //content.append("</tr>");
+ }
+ }
+
+ private void updateTag(Node node, ReadGraph graph, Resource subj, Resource tag, String title) throws DatabaseException {
+
+ // Generate output content from statements
+ Node ref = getResourceRef(graph, tag);
+ Edge e = new Edge(this.graph, node, ref);
+ e.setLabel(title);
+
+// content.append("<tr>");
+// content.append("<td rowspan=\"1\" colspan=\"2\" valign=\"top\">" + ref + "</td>");
+// content.append("<td class=\"remove\">");
+// content.append(getStatementRemoveRef(subj, tag, subj));
+// content.append("</td>");
+// content.append("</tr>");
+
+ }
+
+
+
+ private void updateOrderedSet(Node node, ReadGraph graph, Resource subj) throws DatabaseException {
+
+// StringBuffer content = new StringBuffer();
+ //List<String> list = new ArrayList<String>();
+ List<Node> list = new ArrayList<Node>();
+ Resource cur = subj;
+ while(true) {
+ try {
+ cur = OrderedSetUtils.next(graph, subj, cur);
+ } catch(DatabaseException e) {
+ Edge edge = new Edge(this.graph, node, node);
+ edge.setLabel("Broken Ordered Set");
+ //list.add("<span style=\"color:red;font-weight:bold\">BROKEN ORDERED SET:<br/></span><span style=\"color:red\">" + e.getMessage() + "</span>");
+// Resource inv = graph.getPossibleInverse(subj);
+// for(Statement stat : graph.getStatements(cur, L0.IsRelatedTo)) {
+// if(stat.getSubject().equals(cur)) {
+// if(stat.getPredicate().equals(subj)) {
+// list.add("next " + getResourceRef(graph, stat.getObject()));
+// }
+// else if(stat.getPredicate().equals(inv)) {
+// list.add("prev " + getResourceRef(graph, stat.getObject()));
+// }
+// }
+// }
+// break;
+ }
+ if(cur.equals(subj))
+ break;
+ //list.add(getResourceName(graph, cur));
+ list.add(getResourceRef(graph, cur));
+ }
+ for (int i = 0; i < list.size() ; ++i) {
+ Edge e = new Edge(this.graph, node, list.get(i));
+ e.setLabel("Oredered set item " + i);
+ }
+
+ // Output table rows
+// content.append("<table>\n");
+// for (int i = 0; i < list.size() ; ++i) {
+// content.append("<tr>");
+// // Predicate column
+// if (i == 0)
+// content.append("<td rowspan=\"" + list.size() + "\" valign=\"top\">Ordered Set Elements</td>");
+//
+// // Object column
+// content.append("<td>");
+// content.append(list.get(i));
+// content.append("</td>");
+//
+// content.append("</tr>");
+// }
+// content.append("</table>\n");
+// appendLabel(node, content.toString());
+ }
+
+
+
+}