]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
c32a30047fe77e5b3241fcfc90c5c429ca046e3a
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.sysdyn.ui.structure;\r
13 \r
14 import java.util.HashMap;\r
15 import java.util.HashSet;\r
16 \r
17 import org.simantics.db.ReadGraph;\r
18 import org.simantics.db.Resource;\r
19 import org.simantics.db.common.request.PossibleObjectWithType;\r
20 import org.simantics.db.common.utils.NameUtils;\r
21 import org.simantics.db.exception.DatabaseException;\r
22 import org.simantics.db.request.Read;\r
23 import org.simantics.graphviz.Edge;\r
24 import org.simantics.graphviz.Graph;\r
25 import org.simantics.graphviz.Node;\r
26 import org.simantics.layer0.Layer0;\r
27 import org.simantics.modeling.ModelingResources;\r
28 import org.simantics.simulation.ontology.SimulationResource;\r
29 import org.simantics.sysdyn.SysdynResource;\r
30 \r
31 /**\r
32  * Builds a graph about the modular structure of the model where a selected object is located.\r
33  * \r
34  * @author Teemu Lempinen\r
35  *\r
36  */\r
37 public class ModuleStructureGraphRequest implements Read<Graph> {\r
38 \r
39     private Resource resource;\r
40 \r
41     /**\r
42      * Request a hierarchical graph about the model of resource\r
43      * @param resource\r
44      */\r
45     public ModuleStructureGraphRequest(Resource resource) {\r
46         this.resource = resource;\r
47     }\r
48 \r
49     @Override\r
50     public Graph perform(ReadGraph graph) throws DatabaseException {\r
51         SysdynResource sr = SysdynResource.getInstance(graph);\r
52         Layer0 l0 = Layer0.getInstance(graph);\r
53 \r
54         Graph g = new Graph();\r
55         g.setRankdir("TB");\r
56 \r
57         // Find model resource, the root of this\r
58         Resource model = resource;\r
59         while(model != null && !graph.isInstanceOf(model, sr.SysdynModel)) {\r
60             model = graph.getPossibleObject(model, l0.PartOf);\r
61         }\r
62 \r
63         // Model root was not found, return empty graph\r
64         if(model == null)\r
65             return g;\r
66         \r
67         // Find the parent module/model of the selected resource\r
68         Resource parentResource = graph.getPossibleObject(resource, l0.PartOf);\r
69         if(graph.isInstanceOf(parentResource, sr.ConfigurationDiagram)) {\r
70                 parentResource = graph.getPossibleObject(parentResource, ModelingResources.getInstance(graph).DiagramToComposite);\r
71         } else if(graph.isInstanceOf(parentResource, sr.SysdynModel)) {\r
72                 parentResource = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration);\r
73         }\r
74 \r
75         // Set root node\r
76         Node rootNode = new Node(g, NameUtils.getSafeLabel(graph, model));\r
77         rootNode.setShape("rectangle");\r
78         HashSet<Resource> visited = new HashSet<Resource>();\r
79         visited.add(model);\r
80         findChildModules(g, rootNode, graph, model, parentResource, visited);\r
81 \r
82 \r
83         return g;\r
84     }\r
85 \r
86     /**\r
87      * Recursive call for finding child modules \r
88      * @param g GraphViz graph\r
89      * @param parent Parent module or model\r
90      * @param graph ReadGraph\r
91      * @param resource Module type or model\r
92      * @param parent2 \r
93      * @param visited All visited modules. Needed to check for loops in the structure. Loops are not allowed.\r
94      * @throws DatabaseException\r
95      */\r
96     private void findChildModules(Graph g, Node parent, ReadGraph graph, Resource resource, Resource parentResource, HashSet<Resource> visited) throws DatabaseException {\r
97         SysdynResource sr = SysdynResource.getInstance(graph);\r
98         Layer0 l0 = Layer0.getInstance(graph);\r
99 \r
100         Resource configuration = graph.syncRequest(new PossibleObjectWithType(resource, l0.ConsistsOf, sr.Configuration));\r
101 \r
102         // Set the parent color different, if it is the parent of the selected resource\r
103         if(configuration.equals(parentResource))\r
104                 parent.setColor("#ff8c00");\r
105         \r
106         HashMap<Resource, Integer> modules = new HashMap<Resource, Integer>();\r
107 \r
108         // Find all module children\r
109         for(Resource m : graph.getObjects(configuration, l0.ConsistsOf)) {\r
110             Resource type = graph.getPossibleObject(m, l0.InstanceOf);\r
111             if(graph.isInheritedFrom(type, sr.Module)) {\r
112                 if(!modules.containsKey(type))\r
113                     modules.put(type, 0);\r
114                 modules.put(type, modules.get(type) + 1);\r
115             }\r
116         }\r
117 \r
118         // Display module children in graph\r
119         for(Resource type : modules.keySet()) {\r
120 \r
121             Node node = new Node(g, NameUtils.getSafeName(graph, type));\r
122             node.setShape("rectangle");\r
123             Edge edge = new Edge(g, parent, node);\r
124             edge.set("labeldistance", "1.5");\r
125             edge.set("labelfontsize", "7");\r
126             edge.setFontColor("#4f4f4f");\r
127             if(modules.get(type) > 1)\r
128                 edge.setHeadLabel(modules.get(type).toString());\r
129             \r
130             if(visited.contains(type)) {\r
131                 // Found a loop. Stop recursive call and display error.\r
132                 edge.setFontColor("#FF0000");\r
133                 edge.setColor("#FF000");\r
134                 edge.setLabel("Error: loop");\r
135                 node.setColor("#FF0000");\r
136                 node.setFontColor("#FF0000");\r
137                 continue;\r
138             } else {\r
139                 HashSet<Resource> copy = new HashSet<Resource>(visited);\r
140                 copy.add(type);\r
141                 findChildModules(g, node, graph, type, parentResource, copy);\r
142             }\r
143             \r
144         }\r
145 \r
146     }\r
147 \r
148 }\r