]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.structural2/src/org/simantics/structural2/variables/StandardProceduralChildVariable.java
e96fd050a021ee1c9451efe19c1ee88d112d5855
[simantics/platform.git] / bundles / org.simantics.structural2 / src / org / simantics / structural2 / variables / StandardProceduralChildVariable.java
1 package org.simantics.structural2.variables;
2
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;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Set;
11
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;
37
38 import gnu.trove.map.hash.THashMap;
39
40 public class StandardProceduralChildVariable extends AbstractChildVariable {
41
42         private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StandardProceduralChildVariable.class);
43
44         /*
45          * Extension points
46          * 
47          */
48         public Variable getPossibleSpecialChild(ReadGraph graph, String name) throws DatabaseException {
49                 return null;
50         }
51
52         public void collectSpecialChildren(ReadGraph graph, Map<String, Variable> children) throws DatabaseException {
53         }
54
55         /*
56          * Standard implementation
57          * 
58          */
59         
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;
65         
66         public StandardProceduralChildVariable(ReadGraph graph, Variable parent, VariableNode node, String name, Resource type, List<Property> properties, Collection<Connection> conns) throws DatabaseException {
67                 super(node);
68                 assert name != null;
69         assert type != null;
70         this.name = name;
71                 this.parent = parent;
72                 this.type = type;
73                 this.properties = new THashMap<String,Variable>();
74                 
75                 this.propertyIdentity = new ArrayList<Object>(properties.size()+conns.size());
76                 propertyIdentity.addAll(properties);
77                 propertyIdentity.addAll(conns);
78                 
79                 Layer0 L0 = Layer0.getInstance(graph);
80
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);
85                 }
86                 
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);
96             used.add(pName);
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()));
100             }
101         }
102         
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()));
108         }
109                 
110                 
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) );
118                     } else {
119                             this.properties.put(pn, new StandardConstantGraphPropertyVariable(graph, this, p.relation, p.value) );
120                     }
121                         
122                         
123                 }
124             Map<Resource,FixedConnection> map = new HashMap<Resource,FixedConnection>();
125                 for(Connection conn : conns) {
126                     Resource p = null;
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)) {
132                                 p = t.relation;
133                                 continue;
134                             }
135                             cps.add(Pair.make(t.component, t.relation));
136                         }
137                         if(cp instanceof Interface) {
138                                 Interface inf = (Interface)cp;
139                             cps.add(new Pair<String,Resource>(null, inf.relation));
140                         }
141                     }
142                     if(p != null) {
143                         FixedConnection fc = map.get(p);
144                         if(fc == null) {
145                                 fc = new FixedConnection(parent);
146                                 map.put(p, fc);
147                         }
148                         fc.addAll(cps);
149                     }
150                 }
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()));
155                 }
156                 
157         }
158
159         @Override
160         public void validate(ReadGraph graph) throws DatabaseException {
161         }
162         
163         @Override
164         public Resource getType(ReadGraph graph) throws DatabaseException {
165             return type;
166         }
167         
168         @Override
169         public Resource getPossibleType(ReadGraph graph) throws DatabaseException {
170             return type;
171         }
172         
173         @Override
174         public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException {
175                 if (graph.isInheritedFrom(type, baseType))
176                         return type;
177                 throw new NoSingleResultException("variable " + getPossibleURI(graph) + " has no type", -1);
178         }
179         
180         @Override
181         public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException {
182                 return graph.isInheritedFrom(type, baseType) ? type : null;
183         }
184         
185         @Override
186         protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException {
187             return properties.get(name);
188         }
189
190         @Override
191         public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
192             return Functions.structuralChildDomainChildren.getVariable(graph, this, name);
193         }
194
195         @Override
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);
200                 }
201                 return properties;
202         }
203
204         @Override
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();
209         }
210
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();
216         }
217
218         @Override
219         public String getName(ReadGraph graph) throws DatabaseException {
220             return name;
221         }
222
223         @Override
224         public Variable getParent(ReadGraph graph) throws DatabaseException {
225                 return parent;
226         }
227         
228         @Override
229         final public Resource getRepresents(ReadGraph graph) throws DatabaseException {
230             return null;
231         }
232
233         @Override
234         public int hashCode() {
235                 return parent.hashCode() + 31*name.hashCode() + 41*type.hashCode() + 71*System.identityHashCode(propertyIdentity);
236         }
237
238         @Override
239         public boolean equals(Object obj) {
240                 
241                 if (this == obj)
242                         return true;
243                 if (obj == null)
244                         return false;
245                 if (getClass() != obj.getClass())
246                         return false;
247                 
248                 StandardProceduralChildVariable other = (StandardProceduralChildVariable) obj;
249                 
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;
254                                 
255                 return true;
256                 
257         }
258         
259 }