1 package org.simantics.modeling.ui.componentTypeEditor;
\r
3 import gnu.trove.map.hash.THashMap;
\r
5 import java.util.List;
\r
7 import org.eclipse.swt.SWT;
\r
8 import org.eclipse.swt.widgets.Composite;
\r
9 import org.simantics.Simantics;
\r
10 import org.simantics.db.ReadGraph;
\r
11 import org.simantics.db.Resource;
\r
12 import org.simantics.db.exception.DatabaseException;
\r
13 import org.simantics.db.layer0.variable.Variable;
\r
14 import org.simantics.db.layer0.variable.Variables;
\r
15 import org.simantics.db.procedure.Listener;
\r
16 import org.simantics.db.request.Read;
\r
17 import org.simantics.graphviz.Edge;
\r
18 import org.simantics.graphviz.Graph;
\r
19 import org.simantics.graphviz.Node;
\r
20 import org.simantics.graphviz.Record;
\r
21 import org.simantics.graphviz.ui.GraphvizComponent;
\r
22 import org.simantics.layer0.Layer0;
\r
23 import org.simantics.modeling.ModelingResources;
\r
24 import org.simantics.structural2.Functions;
\r
25 import org.simantics.structural2.procedural.Component;
\r
26 import org.simantics.structural2.procedural.Connection;
\r
27 import org.simantics.structural2.procedural.ConnectionPoint;
\r
28 import org.simantics.structural2.procedural.Interface;
\r
29 import org.simantics.structural2.procedural.Property;
\r
30 import org.simantics.structural2.procedural.SubstructureElement;
\r
31 import org.simantics.structural2.procedural.Terminal;
\r
32 import org.simantics.ui.workbench.ResourceEditorPart;
\r
33 import org.simantics.utils.datastructures.Pair;
\r
35 public class ProceduralComponentInstanceViewer extends ResourceEditorPart {
\r
37 GraphvizComponent graphviz;
\r
40 public void createPartControl(Composite parent) {
\r
41 graphviz = new GraphvizComponent(parent, SWT.NONE);
\r
42 Simantics.getSession().asyncRequest(new Read<Graph>() {
\r
45 public Graph perform(ReadGraph graph) throws DatabaseException {
\r
46 Resource inputResource = getInputResource();
\r
47 Variable context = Variables.getPossibleVariable(graph, inputResource);
\r
49 return createErrorGraph("Couldn't create variable for the resource.");
\r
51 List<SubstructureElement> proceduralDesc =
\r
52 Functions.getProceduralDesc(graph, context);
\r
53 if(proceduralDesc == null)
\r
54 return createErrorGraph("Component does not have a procedural substructure.");
\r
55 return createGraph(graph, proceduralDesc);
\r
56 } catch(DatabaseException e) {
\r
57 e.printStackTrace();
\r
58 return createErrorGraph(e.getMessage());
\r
62 }, new Listener<Graph>() {
\r
65 public void execute(final Graph graph) {
\r
66 if(!graphviz.isDisposed())
\r
67 graphviz.getDisplay().asyncExec(new Runnable() {
\r
71 if(graphviz.isDisposed())
\r
74 graphviz.setGraph(graph);
\r
81 public void exception(Throwable t) {
\r
82 t.printStackTrace();
\r
86 public boolean isDisposed() {
\r
87 return graphviz.isDisposed();
\r
94 public void setFocus() {
\r
95 graphviz.setFocus();
\r
98 private static Graph createErrorGraph(String description) {
\r
99 Graph graph = new Graph();
\r
100 new Node(graph, description).setShape("rectangle");
\r
104 private static String nameOf(ReadGraph g, Resource r) throws DatabaseException {
\r
105 return g.getRelatedValue(r, Layer0.getInstance(g).HasName);
\r
108 private static Pair<Node, String> getCp(ReadGraph g, Graph graph, THashMap<String, Node> components, THashMap<Resource, Node> connectionPoints, ConnectionPoint cp) throws DatabaseException {
\r
109 if(cp instanceof Terminal) {
\r
110 Terminal terminal = (Terminal)cp;
\r
111 return Pair.make(components.get(terminal.component), nameOf(g, terminal.relation));
\r
114 Interface interface_ = (Interface)cp;
\r
115 Node node = connectionPoints.get(interface_.relation);
\r
117 node = new Node(graph);
\r
118 node.setShape("diamond");
\r
119 node.setLabel(nameOf(g, interface_.relation));
\r
120 connectionPoints.put(interface_.relation, node);
\r
122 return Pair.make(node, null);
\r
126 private static Graph createGraph(ReadGraph g, List<SubstructureElement> proceduralDesc) throws DatabaseException {
\r
127 Graph graph = new Graph();
\r
128 graph.setRankdir("LR");
\r
129 THashMap<String, Node> components = new THashMap<String, Node>();
\r
130 for(SubstructureElement element : proceduralDesc)
\r
131 if(element instanceof Component) {
\r
132 Component component = (Component)element;
\r
133 Record record = new Record();
\r
134 record.add(component.name + " : " + nameOf(g, component.type));
\r
135 StringBuilder b = new StringBuilder();
\r
136 boolean first = true;
\r
137 for(Property property : component.properties) {
\r
142 b.append(nameOf(g, property.relation) + " = " + property.value);
\r
144 record.add(b.toString());
\r
145 components.put(component.name, record.toNode(graph));
\r
147 THashMap<Resource, Node> connectionPoints = new THashMap<Resource, Node>();
\r
148 for(SubstructureElement element : proceduralDesc)
\r
149 if(element instanceof Connection) {
\r
150 Connection connection = (Connection)element;
\r
151 List<ConnectionPoint> cps = connection.connectionPoints;
\r
152 if(cps.size() == 2) {
\r
153 Pair<Node, String> cp1 = getCp(g, graph, components, connectionPoints, cps.get(0));
\r
154 Pair<Node, String> cp2 = getCp(g, graph, components, connectionPoints, cps.get(1));
\r
155 Edge edge = new Edge(cp1.first, cp2.first);
\r
156 if(cp1.second != null) {
\r
157 if(cp2.second != null)
\r
158 edge.setLabel(cp1.second + "-" + cp2.second);
\r
160 edge.setLabel(cp1.second);
\r
163 if(cp2.second != null)
\r
164 edge.setLabel(cp2.second);
\r
168 Node p = new Node(graph);
\r
169 p.setShape("point");
\r
170 boolean first = true;
\r
171 for(ConnectionPoint cp : cps) {
\r
172 Pair<Node, String> cp1 = getCp(g, graph, components, connectionPoints, cp);
\r
174 Edge edge = new Edge(cp1.first, p);
\r
175 edge.setLabel(cp1.second);
\r
179 Edge edge = new Edge(p, cp1.first);
\r
180 edge.setLabel(cp1.second);
\r