1 package org.simantics.structural2.utils;
\r
3 import gnu.trove.set.hash.THashSet;
\r
5 import java.util.ArrayList;
\r
6 import java.util.Collection;
\r
7 import java.util.HashMap;
\r
8 import java.util.Set;
\r
10 import org.simantics.databoard.Bindings;
\r
11 import org.simantics.datatypes.literal.GUID;
\r
12 import org.simantics.db.ReadGraph;
\r
13 import org.simantics.db.RequestProcessor;
\r
14 import org.simantics.db.Resource;
\r
15 import org.simantics.db.Statement;
\r
16 import org.simantics.db.WriteGraph;
\r
17 import org.simantics.db.common.CommentMetadata;
\r
18 import org.simantics.db.common.request.ObjectsWithType;
\r
19 import org.simantics.db.common.utils.NameUtils;
\r
20 import org.simantics.db.exception.DatabaseException;
\r
21 import org.simantics.db.layer0.exception.MissingVariableException;
\r
22 import org.simantics.db.layer0.request.InstantiateRequest;
\r
23 import org.simantics.db.layer0.util.Layer0Utils;
\r
24 import org.simantics.db.layer0.variable.Variable;
\r
25 import org.simantics.layer0.Layer0;
\r
26 import org.simantics.structural.stubs.StructuralResource2;
\r
27 import org.simantics.structural2.internal.queries.ConnectedTo;
\r
28 import org.simantics.structural2.internal.queries.RelatedConnections;
\r
29 import org.simantics.structural2.internal.queries.RelatedConnectionsOfConnectionJoin;
\r
30 import org.simantics.structural2.queries.Terminal;
\r
31 import org.simantics.structural2.variables.Connection;
\r
32 import org.simantics.utils.datastructures.Pair;
\r
35 * A utility class for manipulating structural models.
\r
37 * @author Hannu Niemistö
\r
39 public class StructuralUtils {
\r
41 public static Collection<Resource> getConnectionRelations(ReadGraph graph, Resource componentType) throws DatabaseException {
\r
42 Layer0 L0 = Layer0.getInstance(graph);
\r
43 StructuralResource2 STR = StructuralResource2.getInstance(graph);
\r
44 return graph.syncRequest(new ObjectsWithType(componentType, L0.DomainOf, STR.ConnectionRelation));
\r
47 public static Collection<Resource> getPropertyRelations(ReadGraph graph, Resource componentType) throws DatabaseException {
\r
48 Layer0 L0 = Layer0.getInstance(graph);
\r
49 ArrayList<Resource> result = new ArrayList<Resource>();
\r
50 for(Resource relation : graph.getObjects(componentType, L0.DomainOf))
\r
51 if(graph.isSubrelationOf(relation, L0.HasProperty))
\r
52 result.add(relation);
\r
56 public static boolean isDomainOfRelation(ReadGraph graph,
\r
57 Resource componentType, Resource connectionRelation) throws DatabaseException {
\r
58 Layer0 L0 = Layer0.getInstance(graph);
\r
59 for(Resource domain : graph.getObjects(connectionRelation, L0.HasDomain))
\r
60 if(graph.isInheritedFrom(componentType, domain))
\r
65 public static void addConnectionPoint(WriteGraph g, Resource componentType,
\r
66 Resource connectionPoint) throws DatabaseException {
\r
67 Layer0 L0 = Layer0.getInstance(g);
\r
68 g.claim(connectionPoint, L0.HasDomain, componentType);
\r
71 public static Resource createConnectionPoint(WriteGraph g, Resource componentType, Resource copy) throws DatabaseException {
\r
72 String proposition = NameUtils.getSafeName(g, copy);
\r
73 String newName = NameUtils.findFreshName(g, proposition, componentType);
\r
74 return createConnectionPoint(g, componentType, copy, newName);
\r
77 public static Resource createConnectionPoint(WriteGraph g, Resource componentType, Resource copy, String name) throws DatabaseException {
\r
78 return createConnectionPointP(g, componentType, copy, name).first;
\r
81 public static Pair<Resource,Resource> createConnectionPointP(WriteGraph g, Resource componentType, Resource copy, String name) throws DatabaseException {
\r
83 Layer0 L0 = Layer0.getInstance(g);
\r
84 StructuralResource2 STR = StructuralResource2.getInstance(g);
\r
86 // Create the connection point
\r
87 Resource connectionPoint = g.newResource();
\r
88 Resource connectionPointInv = g.newResource();
\r
90 for (Resource superrelation : g.getObjects(copy, L0.SubrelationOf)) {
\r
91 g.claim(connectionPoint, L0.SubrelationOf, null, superrelation);
\r
92 Resource inverse = g.getPossibleInverse(superrelation);
\r
93 if (inverse != null)
\r
94 g.claim(connectionPointInv, L0.SubrelationOf, null, inverse);
\r
96 for (Resource type : g.getObjects(copy, L0.InstanceOf)) {
\r
97 g.claim(connectionPoint, L0.InstanceOf, null, type);
\r
99 for (Resource attachment : g.getObjects(copy, STR.HasAttachmentRelation)) {
\r
100 g.claim(connectionPoint, STR.HasAttachmentRelation, attachment);
\r
102 for (Statement stm : g.getStatements(copy, STR.AllowsConnectionType)) {
\r
103 if (!stm.isAsserted(copy)) {
\r
104 g.claim(connectionPoint, stm.getPredicate(), stm.getObject());
\r
108 g.claim(connectionPoint, L0.InverseOf, connectionPointInv);
\r
109 g.claimLiteral(connectionPoint, L0.HasName, name, Bindings.STRING);
\r
110 g.claim(connectionPoint, L0.ConsistsOf, connectionPointInv);
\r
111 g.claimLiteral(connectionPointInv, L0.HasName, "Inverse", Bindings.STRING);
\r
113 StructuralUtils.addConnectionPoint(g, componentType, connectionPoint);
\r
115 g.claim(componentType, L0.ConsistsOf, connectionPoint);
\r
117 return Pair.make(connectionPoint, connectionPointInv);
\r
122 * Creates a new component and the templates associated with it.
\r
123 * This method does not check whether there already exists
\r
124 * a component with the same name and parent.
\r
126 * @param parent The parent composite of the new component.
\r
127 * @param name The name of the new component.
\r
128 * @param componentType The type of the new component.
\r
130 * @throws DatabaseException
\r
132 public static Resource newComponent(WriteGraph g, Resource parent, String name, Resource componentType) throws DatabaseException {
\r
133 Layer0 L0 = Layer0.getInstance(g);
\r
135 HashMap<String,Object> parameters = new HashMap<String,Object>();
\r
136 parameters.put("parent", parent);
\r
138 InstantiateRequest ir = new InstantiateRequest(componentType, parameters);
\r
139 Resource component = ir.perform(g);
\r
140 g.claim(component, L0.HasName, Layer0Utils.literal(g, name));
\r
141 g.claim(component, L0.HasLabel, Layer0Utils.literal(g, ""));
\r
142 g.addLiteral(component, L0.identifier, L0.identifier_Inverse, L0.GUID, GUID.random(), GUID.BINDING);
\r
143 g.claim(parent, L0.ConsistsOf, component);
\r
144 // Add comment to change set.
\r
145 CommentMetadata cm = g.getMetadata(CommentMetadata.class);
\r
146 g.addMetadata(cm.add("Created component " + component));
\r
151 * Returns all child components of a composite.
\r
153 public static Collection<Resource> getChildComponents(ReadGraph g, Resource parent) throws DatabaseException {
\r
154 Layer0 L0 = Layer0.getInstance(g);
\r
155 StructuralResource2 STR = StructuralResource2.getInstance(g);
\r
157 Collection<Resource> allChildren = g.getObjects(parent, L0.ConsistsOf);
\r
158 ArrayList<Resource> result = new ArrayList<Resource>(allChildren.size());
\r
159 for(Resource child : allChildren)
\r
160 // Composite may contain other things than components, therefore we must do checking
\r
161 if(g.isInstanceOf(child, STR.Component))
\r
167 * Returns the component type of the given component or null if the
\r
168 * parameter is not a component.
\r
170 public static Resource getComponentType(ReadGraph g, Resource component) throws DatabaseException {
\r
171 StructuralResource2 STR = StructuralResource2.getInstance(g);
\r
172 return g.getPossibleType(component, STR.Component);
\r
176 * Returns the definitions of the component type or null, if the component
\r
177 * type does not have a definition.
\r
179 public static Resource getComponentTypeDefinition(ReadGraph g, Resource componentType) throws DatabaseException {
\r
180 StructuralResource2 STR = StructuralResource2.getInstance(g);
\r
181 return g.getPossibleObject(componentType, STR.IsDefinedBy);
\r
185 * Returns all (component,connectionRelation) pairs that are connected
\r
186 * to the given component and connectionRelation.
\r
188 * @param bindingRelation
\r
191 public static Set<Terminal> getRelatedTerminals(RequestProcessor g, Resource component, Resource connectionRelation) throws DatabaseException {
\r
192 return g.syncRequest(new ConnectedTo(component, connectionRelation));
\r
196 * Returns all connections that are reachable from the given connection
\r
197 * with IsJoinedBy-relation including the given connection itself.
\r
199 public static Set<Resource> getRelatedConnections(RequestProcessor g, Resource connection) throws DatabaseException {
\r
200 return g.syncRequest(new RelatedConnections(connection));
\r
204 * Returns all connections that are reachable from the given connection join. *
\r
206 public static Set<Resource> getRelatedConnectionsOfConnectionJoin(RequestProcessor g, Resource connectionJoin) throws DatabaseException {
\r
207 return g.syncRequest(new RelatedConnectionsOfConnectionJoin(connectionJoin));
\r
211 * Returns all connections that are reachable from the given connection join
\r
212 * without visiting the resources in the collection excludedConnections.
\r
214 public static Set<Resource> getRelatedConnectionsOfConnectionJoin(RequestProcessor g, Resource connectionJoin, Collection<Resource> excludedConnections) throws DatabaseException {
\r
215 return g.syncRequest(new RelatedConnectionsOfConnectionJoin(connectionJoin, excludedConnections));
\r
219 * Returns true if the given composite is a parent of some/all components
\r
220 * where the connection is attached to.
\r
222 public static boolean isConnectionInComposite(ReadGraph g, Resource connection, Resource composite) throws DatabaseException {
\r
223 StructuralResource2 STR = StructuralResource2.getInstance(g);
\r
224 Layer0 L0 = Layer0.getInstance(g);
\r
225 Collection<Resource> connects = g.getObjects(connection, STR.Connects);
\r
226 if (!connects.isEmpty()) {
\r
227 for(Resource component : connects)
\r
228 for(Resource parent : g.getObjects(component, L0.PartOf))
\r
229 if(parent.equals(composite))
\r
232 Set<Resource> joinedComposites = null;
\r
233 for(Resource join : g.getObjects(connection, STR.IsJoinedBy)) {
\r
234 Collection<Resource> joined = g.getObjects(join, STR.JoinsComposite);
\r
235 if (joinedComposites == null) {
\r
236 joinedComposites = new THashSet<Resource>(joined);
\r
238 joinedComposites.retainAll(joined);
\r
241 if (joinedComposites != null && joinedComposites.size() == 1) {
\r
242 return joinedComposites.contains(composite);
\r
248 public static Variable getConnectionPoint(ReadGraph graph, Variable component, Resource relation) throws DatabaseException {
\r
249 Layer0 L0 = Layer0.getInstance(graph);
\r
250 String relationName = graph.getRelatedValue(relation, L0.HasName, Bindings.STRING);
\r
251 return component.getProperty(graph, relationName);
\r
254 public static Variable getPossibleConnectionPoint(ReadGraph graph, Variable component, Resource relation) throws DatabaseException {
\r
256 return getConnectionPoint(graph, component, relation);
\r
257 } catch (MissingVariableException e) {
\r
262 public static Variable getPossibleConnectionTo(ReadGraph graph, Variable component, Resource relation) throws DatabaseException {
\r
263 Variable property = component.getPossibleProperty(graph, relation);
\r
264 if(property == null) return null;
\r
265 Connection conn = property.getPossibleValue(graph);
\r
266 if(conn == null) return null;
\r
267 Collection<Variable> cps = conn.getConnectionPoints(graph, null);
\r
268 if(cps.size() == 2) {
\r
269 for(Variable var : cps) {
\r
270 if(property.equals(var)) continue;
\r