1 package org.simantics.structural2.variables;
\r
3 import gnu.trove.map.hash.THashMap;
\r
4 import gnu.trove.set.hash.THashSet;
\r
6 import java.util.ArrayList;
\r
7 import java.util.Collection;
\r
8 import java.util.Collections;
\r
9 import java.util.HashMap;
\r
10 import java.util.HashSet;
\r
11 import java.util.List;
\r
12 import java.util.Map;
\r
13 import java.util.Set;
\r
15 import org.simantics.databoard.Bindings;
\r
16 import org.simantics.db.ReadGraph;
\r
17 import org.simantics.db.Resource;
\r
18 import org.simantics.db.Statement;
\r
19 import org.simantics.db.common.utils.Logger;
\r
20 import org.simantics.db.exception.DatabaseException;
\r
21 import org.simantics.db.exception.NoSingleResultException;
\r
22 import org.simantics.db.layer0.function.All;
\r
23 import org.simantics.db.layer0.request.ClassificationsRequest;
\r
24 import org.simantics.db.layer0.variable.AbstractChildVariable;
\r
25 import org.simantics.db.layer0.variable.NodeSupport;
\r
26 import org.simantics.db.layer0.variable.StandardAssertedGraphPropertyVariable;
\r
27 import org.simantics.db.layer0.variable.StandardConstantGraphPropertyVariable;
\r
28 import org.simantics.db.layer0.variable.Variable;
\r
29 import org.simantics.db.layer0.variable.VariableNode;
\r
30 import org.simantics.layer0.Layer0;
\r
31 import org.simantics.simulator.variable.NodeManager;
\r
32 import org.simantics.structural2.Functions;
\r
33 import org.simantics.structural2.procedural.Connection;
\r
34 import org.simantics.structural2.procedural.ConnectionPoint;
\r
35 import org.simantics.structural2.procedural.Expression;
\r
36 import org.simantics.structural2.procedural.Interface;
\r
37 import org.simantics.structural2.procedural.Property;
\r
38 import org.simantics.structural2.procedural.Terminal;
\r
39 import org.simantics.utils.datastructures.Pair;
\r
41 public class StandardProceduralChildVariable extends AbstractChildVariable {
\r
47 public Variable getPossibleSpecialChild(ReadGraph graph, String name) throws DatabaseException {
\r
51 public void collectSpecialChildren(ReadGraph graph, Map<String, Variable> children) throws DatabaseException {
\r
55 * Standard implementation
\r
59 final protected String name;
\r
60 final protected Variable parent;
\r
61 final private Resource type;
\r
62 final private Map<String, Variable> properties;
\r
63 final private List<Object> propertyIdentity;
\r
65 public static class FixedConnection implements org.simantics.structural2.variables.Connection {
\r
67 final public Collection<Pair<String,Resource>> cps = new ArrayList<Pair<String,Resource>>();
\r
69 final private Variable parent;
\r
71 public FixedConnection(Variable parent) {
\r
72 this.parent = parent;
\r
76 public Collection<Variable> getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException {
\r
78 Set<Variable> result = new THashSet<Variable>();
\r
79 for(Pair<String,Resource> cp : cps) {
\r
80 Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first);
\r
81 Variable cp2 = component.getPossibleProperty(graph, cp.second);
\r
83 for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, relationType)) {
\r
84 result.add(desc.getVariable(graph));
\r
87 System.err.println("no cp " + cp.first + " for " + component.getURI(graph));
\r
94 public Collection<String> getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException {
\r
96 Set<String> result = new THashSet<String>();
\r
97 for(Pair<String,Resource> cp : cps) {
\r
98 Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first);
\r
99 Variable cp2 = component.getPossibleProperty(graph, cp.second);
\r
101 for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, relationType)) {
\r
102 result.add(desc.getURI(graph));
\r
105 System.err.println("no cp " + cp.first + " for " + component.getURI(graph));
\r
112 public Collection<VariableConnectionPointDescriptor> getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException {
\r
114 Set<VariableConnectionPointDescriptor> result = new THashSet<VariableConnectionPointDescriptor>();
\r
115 for(Pair<String,Resource> cp : cps) {
\r
116 Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first);
\r
117 Variable cp2 = component.getPossibleProperty(graph, cp.second);
\r
119 result.addAll(ConnectionBrowser.flatten(graph, component, cp.second, relationType));
\r
121 System.err.println("no cp " + cp.first + " for " + component.getURI(graph));
\r
128 public int hashCode() {
\r
129 final int prime = 31;
\r
131 result = prime * result + ((cps == null) ? 0 : cps.hashCode());
\r
132 result = prime * result
\r
133 + ((parent == null) ? 0 : parent.hashCode());
\r
138 public boolean equals(Object obj) {
\r
143 if (getClass() != obj.getClass())
\r
145 FixedConnection other = (FixedConnection) obj;
\r
147 if (other.cps != null)
\r
149 } else if (!cps.equals(other.cps))
\r
151 if (parent == null) {
\r
152 if (other.parent != null)
\r
154 } else if (!parent.equals(other.parent))
\r
161 public StandardProceduralChildVariable(ReadGraph graph, Variable parent, VariableNode node, String name, Resource type, List<Property> properties, Collection<Connection> conns) throws DatabaseException {
\r
163 assert name != null;
\r
164 assert type != null;
\r
166 this.parent = parent;
\r
168 this.properties = new THashMap<String,Variable>();
\r
170 this.propertyIdentity = new ArrayList<Object>(properties.size()+conns.size());
\r
171 propertyIdentity.addAll(properties);
\r
172 propertyIdentity.addAll(conns);
\r
174 Layer0 L0 = Layer0.getInstance(graph);
\r
176 Map<String,Statement> assertedProperties = new THashMap<String, Statement>();
\r
177 for(Statement stm : graph.getAssertedStatements(type, L0.HasProperty)) {
\r
178 String pn = graph.getRelatedValue(stm.getPredicate(), L0.HasName, Bindings.STRING);
\r
179 assertedProperties.put(pn, stm);
\r
182 Collection<Object> nodeProperties = All.getPossibleNodeProperties(graph, (AbstractChildVariable)this);
\r
183 Set<String> used = new HashSet<String>(nodeProperties.size());
\r
184 for(Object nodeProperty : nodeProperties) {
\r
185 @SuppressWarnings("rawtypes")
\r
186 NodeSupport support = node.support;
\r
187 @SuppressWarnings("rawtypes")
\r
188 NodeManager manager = support.manager;
\r
189 @SuppressWarnings("unchecked")
\r
190 String pName = manager.getName(nodeProperty);
\r
192 Statement assertedProperty = assertedProperties.get(pName);
\r
193 if(assertedProperty != null) {
\r
194 this.properties.put(pName, new StandardAssertedGraphPropertyVariable(graph, this, new VariableNode(support, nodeProperty), assertedProperty.getSubject(), assertedProperty.getPredicate(), assertedProperty.getObject()));
\r
198 for(Map.Entry<String, Statement> entry : assertedProperties.entrySet()) {
\r
199 String pName = entry.getKey();
\r
200 if(used.contains(pName)) continue;
\r
201 Statement assertedProperty = entry.getValue();
\r
202 this.properties.put(pName, new StandardAssertedGraphPropertyVariable(graph, this, null, assertedProperty.getSubject(), assertedProperty.getPredicate(), assertedProperty.getObject()));
\r
206 for(Property p : properties) {
\r
207 String pn = graph.getRelatedValue(p.relation, L0.HasName, Bindings.STRING);
\r
208 if(p.value == null) {
\r
209 Logger.defaultLogError("StandardProceduralChildVariable " + getURI(graph) + ": null value for property " + pn);
\r
210 } else if (p.value instanceof Expression) {
\r
211 Expression expression = (Expression)p.value;
\r
212 this.properties.put(pn, new StructuralProceduralExpressionPropertyVariable(graph, this, p.relation, expression.text) );
\r
214 this.properties.put(pn, new StandardConstantGraphPropertyVariable(graph, this, p.relation, p.value) );
\r
219 Map<Resource,FixedConnection> map = new HashMap<Resource,FixedConnection>();
\r
220 for(Connection conn : conns) {
\r
222 List<Pair<String,Resource>> cps = new ArrayList<Pair<String,Resource>>();
\r
223 for(ConnectionPoint cp : conn.connectionPoints) {
\r
224 if(cp instanceof Terminal) {
\r
225 Terminal t = (Terminal)cp;
\r
226 if(t.component.equals(name)) {
\r
230 cps.add(Pair.make(t.component, t.relation));
\r
232 if(cp instanceof Interface) {
\r
233 Interface inf = (Interface)cp;
\r
234 cps.add(new Pair<String,Resource>(null, inf.relation));
\r
238 FixedConnection fc = map.get(p);
\r
240 fc = new FixedConnection(parent);
\r
243 fc.cps.addAll(cps);
\r
246 for(Map.Entry<Resource, FixedConnection> entry : map.entrySet()) {
\r
247 Resource cp = entry.getKey();
\r
248 String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);
\r
249 this.properties.put(cpName, new StandardConstantGraphPropertyVariable(graph, this, cp, entry.getValue()));
\r
255 public void validate(ReadGraph graph) throws DatabaseException {
\r
259 public Resource getType(ReadGraph graph) throws DatabaseException {
\r
264 public Resource getPossibleType(ReadGraph graph) throws DatabaseException {
\r
269 public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException {
\r
270 if (graph.isInheritedFrom(type, baseType))
\r
272 throw new NoSingleResultException("variable " + getPossibleURI(graph) + " has no type");
\r
276 public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException {
\r
277 return graph.isInheritedFrom(type, baseType) ? type : null;
\r
281 protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException {
\r
282 return properties.get(name);
\r
286 public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
\r
287 return Functions.structuralChildDomainChildren.getVariable(graph, this, name);
\r
291 public Map<String, Variable> collectDomainProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException {
\r
292 if(!this.properties.isEmpty()) {
\r
293 if(properties == null) properties = new THashMap<String,Variable>(this.properties.size());
\r
294 properties.putAll(this.properties);
\r
300 public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
\r
301 Map<String,Variable> result = Functions.structuralChildDomainChildren.getVariables(graph, this, null);
\r
302 if(result == null) return Collections.emptyList();
\r
303 else return result.values();
\r
306 public Set<String> getClassifications(ReadGraph graph) throws DatabaseException {
\r
307 Resource type = getPossibleType(graph);
\r
308 return (type != null)
\r
309 ? graph.syncRequest(new ClassificationsRequest(Collections.singleton(type)))
\r
310 : Collections.<String>emptySet();
\r
314 public String getName(ReadGraph graph) throws DatabaseException {
\r
319 public Variable getParent(ReadGraph graph) throws DatabaseException {
\r
324 final public Resource getRepresents(ReadGraph graph) throws DatabaseException {
\r
329 public int hashCode() {
\r
330 return parent.hashCode() + 31*name.hashCode() + 41*type.hashCode() + 71*System.identityHashCode(propertyIdentity);
\r
334 public boolean equals(Object obj) {
\r
340 if (getClass() != obj.getClass())
\r
343 StandardProceduralChildVariable other = (StandardProceduralChildVariable) obj;
\r
345 if(!name.equals(other.name)) return false;
\r
346 if(!type.equals(other.type)) return false;
\r
347 if(!parent.equals(other.parent)) return false;
\r
348 if(propertyIdentity != other.propertyIdentity) return false;
\r