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