]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
4724a0d5c4ae713a228ac509f09e072e6a65019a
[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.sysdyn.SysdynResource;\r
28 \r
29 /**\r
30  * Builds a graph about the modular structure of the model where a selected object is located.\r
31  * \r
32  * @author Teemu Lempinen\r
33  *\r
34  */\r
35 public class ModuleStructureGraphRequest implements Read<Graph> {\r
36 \r
37     private Resource resource;\r
38 \r
39     /**\r
40      * Request a hierarchical graph about the model of resource\r
41      * @param resource\r
42      */\r
43     public ModuleStructureGraphRequest(Resource resource) {\r
44         this.resource = resource;\r
45     }\r
46 \r
47     @Override\r
48     public Graph perform(ReadGraph graph) throws DatabaseException {\r
49         SysdynResource sr = SysdynResource.getInstance(graph);\r
50         Layer0 l0 = Layer0.getInstance(graph);\r
51 \r
52         Graph g = new Graph();\r
53         g.setRankdir("TB");\r
54 \r
55         // Find model resource, the root of this\r
56         Resource model = resource;\r
57         while(model != null && !graph.isInstanceOf(model, sr.SysdynModel)) {\r
58             model = graph.getPossibleObject(model, l0.PartOf);\r
59         }\r
60 \r
61         // Model root was not found, return empty graph\r
62         if(model == null)\r
63             return g;\r
64 \r
65         // Set root node\r
66         Node rootNode = new Node(g, NameUtils.getSafeLabel(graph, model));\r
67         rootNode.setShape("rectangle");\r
68         HashSet<Resource> visited = new HashSet<Resource>();\r
69         visited.add(model);\r
70         findChildModules(g, rootNode, graph, model, visited);\r
71 \r
72 \r
73         return g;\r
74     }\r
75 \r
76     /**\r
77      * Recursive call for finding child modules \r
78      * @param g GraphViz graph\r
79      * @param parent Parent module or model\r
80      * @param graph ReadGraph\r
81      * @param resource Module type or model\r
82      * @param visited All visited modules. Needed to check for loops in the structure. Loops are not allowed.\r
83      * @throws DatabaseException\r
84      */\r
85     private void findChildModules(Graph g, Node parent, ReadGraph graph, Resource resource, HashSet<Resource> visited) throws DatabaseException {\r
86         SysdynResource sr = SysdynResource.getInstance(graph);\r
87         Layer0 l0 = Layer0.getInstance(graph);\r
88 \r
89         HashMap<Resource, Integer> modules = new HashMap<Resource, Integer>();\r
90 \r
91         // Find all module children\r
92         Resource configuration = graph.syncRequest(new PossibleObjectWithType(resource, l0.ConsistsOf, sr.Configuration));\r
93         for(Resource m : graph.getObjects(configuration, l0.ConsistsOf)) {\r
94             Resource type = graph.getPossibleObject(m, l0.InstanceOf);\r
95             if(graph.isInheritedFrom(type, sr.Module)) {\r
96                 if(!modules.containsKey(type))\r
97                     modules.put(type, 0);\r
98                 modules.put(type, modules.get(type) + 1);\r
99             }\r
100         }\r
101 \r
102         // Display module children in graph\r
103         for(Resource type : modules.keySet()) {\r
104 \r
105             Node node = new Node(g, NameUtils.getSafeName(graph, type));\r
106             node.setShape("rectangle");\r
107             Edge edge = new Edge(g, parent, node);\r
108             edge.set("labeldistance", "1.5");\r
109             edge.set("labelfontsize", "7");\r
110             edge.setFontColor("#4f4f4f");\r
111             if(modules.get(type) > 1)\r
112                 edge.setHeadLabel(modules.get(type).toString());\r
113             \r
114             if(visited.contains(type)) {\r
115                 // Found a loop. Stop recursive call and display error.\r
116                 edge.setFontColor("#FF0000");\r
117                 edge.setColor("#FF000");\r
118                 edge.setLabel("Error: loop");\r
119                 node.setColor("#FF0000");\r
120                 node.setFontColor("#FF0000");\r
121                 continue;\r
122             } else {\r
123                 visited.add(type);\r
124                 findChildModules(g, node, graph, type, visited);\r
125             }\r
126             \r
127         }\r
128 \r
129     }\r
130 \r
131 }\r