1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2012 Association for Decentralized Information Management in
\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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.sysdyn.ui.structure;
\r
14 import java.util.HashMap;
\r
15 import java.util.HashSet;
\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
32 * Builds a graph about the modular structure of the model where a selected object is located.
\r
34 * @author Teemu Lempinen
\r
37 public class ModuleStructureGraphRequest implements Read<Graph> {
\r
39 private Resource resource;
\r
42 * Request a hierarchical graph about the model of resource
\r
45 public ModuleStructureGraphRequest(Resource resource) {
\r
46 this.resource = resource;
\r
50 public Graph perform(ReadGraph graph) throws DatabaseException {
\r
51 SysdynResource sr = SysdynResource.getInstance(graph);
\r
52 Layer0 l0 = Layer0.getInstance(graph);
\r
54 Graph g = new Graph();
\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
63 // Model root was not found, return empty graph
\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
76 Node rootNode = new Node(g, NameUtils.getSafeLabel(graph, model));
\r
77 rootNode.setShape("rectangle");
\r
78 HashSet<Resource> visited = new HashSet<Resource>();
\r
80 findChildModules(g, rootNode, graph, model, parentResource, visited);
\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
93 * @param visited All visited modules. Needed to check for loops in the structure. Loops are not allowed.
\r
94 * @throws DatabaseException
\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
100 Resource configuration = graph.syncRequest(new PossibleObjectWithType(resource, l0.ConsistsOf, sr.Configuration));
\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
106 HashMap<Resource, Integer> modules = new HashMap<Resource, Integer>();
\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
118 // Display module children in graph
\r
119 for(Resource type : modules.keySet()) {
\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
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
139 HashSet<Resource> copy = new HashSet<Resource>(visited);
\r
141 findChildModules(g, node, graph, type, parentResource, copy);
\r