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