1 package org.simantics.structural2.variables;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.HashSet;
12 import org.simantics.databoard.Bindings;
13 import org.simantics.db.ReadGraph;
14 import org.simantics.db.Resource;
15 import org.simantics.db.Statement;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.exception.NoSingleResultException;
18 import org.simantics.db.layer0.function.All;
19 import org.simantics.db.layer0.request.ClassificationsRequest;
20 import org.simantics.db.layer0.variable.AbstractChildVariable;
21 import org.simantics.db.layer0.variable.NodeSupport;
22 import org.simantics.db.layer0.variable.StandardAssertedGraphPropertyVariable;
23 import org.simantics.db.layer0.variable.StandardConstantGraphPropertyVariable;
24 import org.simantics.db.layer0.variable.Variable;
25 import org.simantics.db.layer0.variable.VariableNode;
26 import org.simantics.layer0.Layer0;
27 import org.simantics.simulator.variable.NodeManager;
28 import org.simantics.structural2.Functions;
29 import org.simantics.structural2.procedural.Connection;
30 import org.simantics.structural2.procedural.ConnectionPoint;
31 import org.simantics.structural2.procedural.Expression;
32 import org.simantics.structural2.procedural.Interface;
33 import org.simantics.structural2.procedural.Property;
34 import org.simantics.structural2.procedural.Terminal;
35 import org.simantics.utils.datastructures.Pair;
36 import org.slf4j.LoggerFactory;
38 import gnu.trove.map.hash.THashMap;
40 public class StandardProceduralChildVariable extends AbstractChildVariable {
42 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StandardProceduralChildVariable.class);
48 public Variable getPossibleSpecialChild(ReadGraph graph, String name) throws DatabaseException {
52 public void collectSpecialChildren(ReadGraph graph, Map<String, Variable> children) throws DatabaseException {
56 * Standard implementation
60 final protected String name;
61 final protected Variable parent;
62 final private Resource type;
63 final private Map<String, Variable> properties;
64 final private List<Object> propertyIdentity;
66 public StandardProceduralChildVariable(ReadGraph graph, Variable parent, VariableNode node, String name, Resource type, List<Property> properties, Collection<Connection> conns) throws DatabaseException {
73 this.properties = new THashMap<String,Variable>();
75 this.propertyIdentity = new ArrayList<Object>(properties.size()+conns.size());
76 propertyIdentity.addAll(properties);
77 propertyIdentity.addAll(conns);
79 Layer0 L0 = Layer0.getInstance(graph);
81 Map<String,Statement> assertedProperties = new THashMap<String, Statement>();
82 for(Statement stm : graph.getAssertedStatements(type, L0.HasProperty)) {
83 String pn = graph.getRelatedValue(stm.getPredicate(), L0.HasName, Bindings.STRING);
84 assertedProperties.put(pn, stm);
87 Collection<Object> nodeProperties = All.getPossibleNodeProperties(graph, (AbstractChildVariable)this);
88 Set<String> used = new HashSet<String>(nodeProperties.size());
89 for(Object nodeProperty : nodeProperties) {
90 @SuppressWarnings("rawtypes")
91 NodeSupport support = node.support;
92 @SuppressWarnings("rawtypes")
93 NodeManager manager = support.manager;
94 @SuppressWarnings("unchecked")
95 String pName = manager.getName(nodeProperty);
97 Statement assertedProperty = assertedProperties.get(pName);
98 if(assertedProperty != null) {
99 this.properties.put(pName, new StandardAssertedGraphPropertyVariable(graph, this, new VariableNode(support, nodeProperty), assertedProperty.getSubject(), assertedProperty.getPredicate(), assertedProperty.getObject()));
103 for(Map.Entry<String, Statement> entry : assertedProperties.entrySet()) {
104 String pName = entry.getKey();
105 if(used.contains(pName)) continue;
106 Statement assertedProperty = entry.getValue();
107 this.properties.put(pName, new StandardAssertedGraphPropertyVariable(graph, this, null, assertedProperty.getSubject(), assertedProperty.getPredicate(), assertedProperty.getObject()));
111 for(Property p : properties) {
112 String pn = graph.getRelatedValue(p.relation, L0.HasName, Bindings.STRING);
113 if(p.value == null) {
114 LOGGER.error("StandardProceduralChildVariable " + getURI(graph) + ": null value for property " + pn);
115 } else if (p.value instanceof Expression) {
116 Expression expression = (Expression)p.value;
117 this.properties.put(pn, new StructuralProceduralExpressionPropertyVariable(graph, this, p.relation, expression.text) );
119 this.properties.put(pn, new StandardConstantGraphPropertyVariable(graph, this, p.relation, p.value) );
124 Map<Resource,FixedConnection> map = new HashMap<Resource,FixedConnection>();
125 for(Connection conn : conns) {
127 List<Pair<String,Resource>> cps = new ArrayList<Pair<String,Resource>>();
128 for(ConnectionPoint cp : conn.connectionPoints) {
129 if(cp instanceof Terminal) {
130 Terminal t = (Terminal)cp;
131 if(t.component.equals(name)) {
135 cps.add(Pair.make(t.component, t.relation));
137 if(cp instanceof Interface) {
138 Interface inf = (Interface)cp;
139 cps.add(new Pair<String,Resource>(null, inf.relation));
143 FixedConnection fc = map.get(p);
145 fc = new FixedConnection(parent);
151 for(Map.Entry<Resource, FixedConnection> entry : map.entrySet()) {
152 Resource cp = entry.getKey();
153 String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);
154 this.properties.put(cpName, new StandardConstantGraphPropertyVariable(graph, this, cp, entry.getValue()));
160 public void validate(ReadGraph graph) throws DatabaseException {
164 public Resource getType(ReadGraph graph) throws DatabaseException {
169 public Resource getPossibleType(ReadGraph graph) throws DatabaseException {
174 public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException {
175 if (graph.isInheritedFrom(type, baseType))
177 throw new NoSingleResultException("variable " + getPossibleURI(graph) + " has no type", -1);
181 public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException {
182 return graph.isInheritedFrom(type, baseType) ? type : null;
186 protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException {
187 return properties.get(name);
191 public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
192 return Functions.structuralChildDomainChildren.getVariable(graph, this, name);
196 public Map<String, Variable> collectDomainProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException {
197 if(!this.properties.isEmpty()) {
198 if(properties == null) properties = new THashMap<String,Variable>(this.properties.size());
199 properties.putAll(this.properties);
205 public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
206 Map<String,Variable> result = Functions.structuralChildDomainChildren.getVariables(graph, this, null);
207 if(result == null) return Collections.emptyList();
208 else return result.values();
211 public Set<String> getClassifications(ReadGraph graph) throws DatabaseException {
212 Resource type = getPossibleType(graph);
213 return (type != null)
214 ? graph.syncRequest(new ClassificationsRequest(Collections.singleton(type)))
215 : Collections.<String>emptySet();
219 public String getName(ReadGraph graph) throws DatabaseException {
224 public Variable getParent(ReadGraph graph) throws DatabaseException {
229 final public Resource getRepresents(ReadGraph graph) throws DatabaseException {
234 public int hashCode() {
235 return parent.hashCode() + 31*name.hashCode() + 41*type.hashCode() + 71*System.identityHashCode(propertyIdentity);
239 public boolean equals(Object obj) {
245 if (getClass() != obj.getClass())
248 StandardProceduralChildVariable other = (StandardProceduralChildVariable) obj;
250 if(!name.equals(other.name)) return false;
251 if(!type.equals(other.type)) return false;
252 if(!parent.equals(other.parent)) return false;
253 if(propertyIdentity != other.propertyIdentity) return false;