\r
import java.util.ArrayList;\r
import java.util.Collection;\r
+import java.util.Collections;\r
import java.util.HashMap;\r
\r
import org.simantics.db.ReadGraph;\r
import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.request.Read;\r
import org.simantics.graphviz.Edge;\r
\r
public class CreateDependencyGraph implements Read<Graph> {\r
\r
- Resource root;\r
- HashMap<Resource, Node> nodes;\r
- boolean isInverted;\r
- int levels;\r
-\r
- public CreateDependencyGraph(Resource root, int levels, boolean isInverted) {\r
- this.root = root;\r
- this.isInverted = isInverted; \r
- this.levels = levels;\r
- }\r
-\r
- @Override\r
- public Graph perform(ReadGraph g) throws DatabaseException {\r
- nodes = new HashMap<Resource, Node>();\r
- Graph graph = new Graph();\r
- graph.setRankdir("LR");\r
- ModelingResources mr = ModelingResources.getInstance(g);\r
- Resource element = g.getPossibleObject(root, mr.ElementToComponent);\r
- if (element != null) {\r
- root = element;\r
- }\r
- SysdynResource sr = SysdynResource.getInstance(g);\r
- if (g.isInstanceOf(root, sr.IndependentVariable) || g.isInstanceOf(root, sr.Input)) {\r
- Collection<Resource> resources = new ArrayList<Resource>(); \r
- resources.add(root);\r
- for (int i = 0; i < levels && !resources.isEmpty(); i++) {\r
- Collection<Resource> newResources = new ArrayList<Resource>();\r
- for(Resource r : resources) {\r
- newResources.addAll(getDependencies(g, graph, r));\r
- }\r
- resources = new ArrayList<Resource>(newResources);\r
- }\r
- }\r
- return graph;\r
- }\r
- \r
- private Collection<Resource> getDependencies(ReadGraph g, IGraph graph, Resource r) throws DatabaseException{\r
- Collection<Resource> dependants = new ArrayList<Resource>();\r
- SysdynResource sr = SysdynResource.getInstance(g);\r
- Node n;\r
- if (!nodes.containsKey(r)) {\r
- n = new Node(graph, getName(g, r));\r
- setShape(g, r, n);\r
- n.set("style", "filled");\r
- n.setFillColor("#d3d3d3");\r
- nodes.put(r, n);\r
- }\r
- // stop here if element is a module\r
- if (g.isInstanceOf(r, sr.Module))\r
- return dependants;\r
- \r
- Resource headRelation = sr.IsHeadOf;\r
- Resource tailRelation = sr.HasTail; \r
- if(isInverted) {\r
- headRelation = sr.IsTailOf;\r
- tailRelation = sr.HasHead;\r
- }\r
- \r
- Collection<Resource> dependencies = g.getObjects(r, headRelation);\r
- for(Resource d : dependencies) {\r
- Resource dependant = g.getPossibleObject(d, tailRelation);\r
- if(dependant == null)\r
- continue;\r
- if(g.isInstanceOf(dependant, sr.Cloud)) {\r
- break;\r
- }\r
- if( !nodes.containsKey(dependant)) {\r
- n= new Node(graph, getName(g, dependant));\r
- setShape(g, dependant, n);\r
- nodes.put(dependant, n);\r
- dependants.add(dependant);\r
- } else {\r
- n = nodes.get(dependant);\r
- }\r
- if(isInverted) \r
- new Edge(graph, nodes.get(r), n);\r
- else\r
- new Edge(graph, n, nodes.get(r));\r
- }\r
- return dependants;\r
- }\r
-\r
- private void setShape(ReadGraph g, Resource r, Node n) throws DatabaseException {\r
- SysdynResource sr = SysdynResource.getInstance(g);\r
- if(g.isInstanceOf(r, sr.Stock))\r
- n.setShape("rectangle");\r
- else if(g.isInstanceOf(r, sr.Module))\r
- n.setShape("rectangle");\r
- else\r
- n.setShape("ellipse");\r
- }\r
-\r
- private String getName(ReadGraph g, Resource r) throws DatabaseException {\r
- return (String)g.getRelatedValue(r, g.getBuiltins().HasName);\r
- }\r
+ Resource root;\r
+ HashMap<Resource, Node> nodes;\r
+ boolean isInverted;\r
+ int levels;\r
+\r
+ public CreateDependencyGraph(Resource root, int levels, boolean isInverted) {\r
+ this.root = root;\r
+ this.isInverted = isInverted; \r
+ this.levels = levels;\r
+ }\r
+\r
+ @Override\r
+ public Graph perform(ReadGraph g) throws DatabaseException {\r
+\r
+ nodes = new HashMap<Resource, Node>();\r
+ Graph graph = new Graph();\r
+ graph.setRankdir("LR");\r
+ ModelingResources mr = ModelingResources.getInstance(g);\r
+ Resource element = g.getPossibleObject(root, mr.ElementToComponent);\r
+ if (element != null) {\r
+ root = element;\r
+ }\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ if (g.isInstanceOf(root, sr.IndependentVariable) || g.isInstanceOf(root, sr.Input)) {\r
+ setRoot(g, graph, root);\r
+ Collection<Resource> resources = new ArrayList<Resource>(); \r
+ resources.add(root);\r
+ for (int i = 0; i < levels && !resources.isEmpty(); i++) {\r
+ Collection<Resource> newResources = new ArrayList<Resource>();\r
+ for(Resource r : resources) {\r
+ newResources.addAll(setDependencies(g, graph, r));\r
+ }\r
+ resources = new ArrayList<Resource>(newResources);\r
+ }\r
+ }\r
+ return graph;\r
+ }\r
+\r
+ private void setRoot(ReadGraph g, IGraph graph, Resource root) throws DatabaseException {\r
+ Node n;\r
+ n = new Node(graph, getName(g, root));\r
+ setShape(g, root, n);\r
+ n.set("style", "filled");\r
+ n.setFillColor("#d3d3d3");\r
+ nodes.put(root, n);\r
+ }\r
+\r
+\r
+ private Collection<Resource> getDependants(ReadGraph g, IGraph graph, Resource r, Resource toDependency, Resource fromDependency, Resource connectionType) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+ Collection<Resource> dependencies = g.syncRequest(new ObjectsWithType(r, toDependency, connectionType));\r
+\r
+ Collection<Resource> dependants = new ArrayList<Resource>();\r
+ Node n;\r
+ for(Resource d : dependencies) {\r
+ Resource dependant = g.getPossibleObject(d, fromDependency);\r
+ if(dependant == null)\r
+ continue;\r
+ if(g.isInstanceOf(dependant, sr.Cloud)) {\r
+ break;\r
+ }\r
+ if( !nodes.containsKey(dependant)) {\r
+ n= new Node(graph, getName(g, dependant));\r
+ setShape(g, dependant, n);\r
+ nodes.put(dependant, n);\r
+ dependants.add(dependant);\r
+ }\r
+\r
+ if(isInverted) {\r
+ new Edge(graph, nodes.get(r), nodes.get(dependant));\r
+ } else {\r
+ new Edge(graph, nodes.get(dependant), nodes.get(r));\r
+ }\r
+ }\r
+ return dependants;\r
+ }\r
+ private Collection<Resource> setDependencies(ReadGraph g, IGraph graph, Resource r) throws DatabaseException{\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+ // stop here if element is a module\r
+ if (g.isInstanceOf(r, sr.Module))\r
+ return Collections.emptyList();\r
+\r
+ Collection<Resource> dependants;\r
+ if(isInverted)\r
+ dependants = getDependants(g, graph, r, sr.IsTailOf, sr.HasHead, sr.Dependency);\r
+ else {\r
+ dependants = getDependants(g, graph, r, sr.IsHeadOf, sr.HasTail, sr.Dependency);\r
+ if (g.isInstanceOf(r, sr.Stock)) {\r
+ dependants.addAll(getDependants(g, graph, r, sr.IsTailOf, sr.HasHead, sr.Flow));\r
+ dependants.addAll(getDependants(g, graph, r, sr.IsHeadOf, sr.HasTail, sr.Flow));\r
+ }\r
+ }\r
+\r
+ return dependants;\r
+ }\r
+\r
+ private void setShape(ReadGraph g, Resource r, Node n) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ if(g.isInstanceOf(r, sr.Stock))\r
+ n.setShape("rectangle");\r
+ else if(g.isInstanceOf(r, sr.Module)) {\r
+ n.setShape("rectangle");\r
+ n.setStyle("rounded"); \r
+ }\r
+ else\r
+ n.setShape("ellipse");\r
+ }\r
+\r
+ private String getName(ReadGraph g, Resource r) throws DatabaseException {\r
+ return (String)g.getRelatedValue(r, g.getBuiltins().HasName);\r
+ }\r
\r
}\r