]> gerrit.simantics Code Review - simantics/platform.git/blob
d35ea9f9328f1ffa3b254115bae7d8cb5b1cd8de
[simantics/platform.git] /
1 package org.simantics.modeling.ui.componentTypeEditor;
2
3 import gnu.trove.map.hash.THashMap;
4
5 import java.util.List;
6
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;
34
35 public class ProceduralComponentInstanceViewer extends ResourceEditorPart {
36     
37     GraphvizComponent graphviz;
38     
39     @Override
40     public void createPartControl(Composite parent) {
41         graphviz = new GraphvizComponent(parent, SWT.NONE);
42         Simantics.getSession().asyncRequest(new Read<Graph>() {
43
44             @Override
45             public Graph perform(ReadGraph graph) throws DatabaseException {
46                 Resource inputResource = getInputResource();
47                 Variable context = Variables.getPossibleVariable(graph, inputResource);
48                 if(context == null)
49                     return createErrorGraph("Couldn't create variable for the resource.");
50                 try {
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) {
57                     e.printStackTrace();
58                     return createErrorGraph(e.getMessage());
59                 }
60             }
61             
62         }, new Listener<Graph>() {
63
64             @Override
65             public void execute(final Graph graph) {
66                 if(!graphviz.isDisposed())
67                     graphviz.getDisplay().asyncExec(new Runnable() {
68
69                         @Override
70                         public void run() {
71                             if(graphviz.isDisposed())
72                                 return;
73                             if(graph != null)
74                                 graphviz.setGraph(graph);
75                         }
76                         
77                     });
78             }
79
80             @Override
81             public void exception(Throwable t) {
82                 t.printStackTrace();
83             }
84
85             @Override
86             public boolean isDisposed() {
87                 return graphviz.isDisposed();
88             }
89             
90         });
91     }
92
93     @Override
94     public void setFocus() {
95         graphviz.setFocus();
96     }
97     
98     private static Graph createErrorGraph(String description) {
99         Graph graph = new Graph();
100         new Node(graph, description).setShape("rectangle");
101         return graph;
102     }
103     
104     private static String nameOf(ReadGraph g, Resource r) throws DatabaseException {
105         return g.getRelatedValue(r, Layer0.getInstance(g).HasName);
106     }
107     
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));
112         }
113         else {
114             Interface interface_ = (Interface)cp;
115             Node node = connectionPoints.get(interface_.relation);
116             if(node == null) {
117                 node = new Node(graph);
118                 node.setShape("diamond");
119                 node.setLabel(nameOf(g, interface_.relation));
120                 connectionPoints.put(interface_.relation, node);
121             }
122             return Pair.make(node, null);
123         }
124     }
125
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) {
138                     if(first)
139                         first = false;
140                     else
141                         b.append("\\n");
142                     b.append(nameOf(g, property.relation) + " = " + property.value);
143                 }
144                 record.add(b.toString());
145                 components.put(component.name, record.toNode(graph));
146             }
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);
159                         else
160                             edge.setLabel(cp1.second);
161                     }
162                     else {
163                         if(cp2.second != null)
164                             edge.setLabel(cp2.second);
165                     }
166                 }
167                 else {
168                     Node p = new Node(graph);
169                     p.setShape("point");
170                     boolean first = true;
171                     for(ConnectionPoint cp : cps) {
172                         Pair<Node, String> cp1 = getCp(g, graph, components, connectionPoints, cp);
173                         if(first) {
174                             Edge edge = new Edge(cp1.first, p);
175                             edge.setLabel(cp1.second);
176                             first = false;
177                         }
178                         else {
179                             Edge edge = new Edge(p, cp1.first);
180                             edge.setLabel(cp1.second);
181                         }
182                     }
183                 }
184             }
185         return graph;
186     }
187
188 }