]> gerrit.simantics Code Review - simantics/platform.git/blob
a5b50f6f36bc5dc7f1368ff0acc80d9ea4a46e23
[simantics/platform.git] /
1 package org.simantics.structural2.variables;
2
3 import gnu.trove.map.hash.THashMap;
4 import gnu.trove.set.hash.THashSet;
5
6 import java.util.ArrayList;
7 import java.util.Collection;
8 import java.util.Collections;
9 import java.util.HashMap;
10 import java.util.HashSet;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14
15 import org.simantics.databoard.Bindings;
16 import org.simantics.db.ReadGraph;
17 import org.simantics.db.Resource;
18 import org.simantics.db.Statement;
19 import org.simantics.db.common.utils.Logger;
20 import org.simantics.db.exception.DatabaseException;
21 import org.simantics.db.exception.NoSingleResultException;
22 import org.simantics.db.layer0.function.All;
23 import org.simantics.db.layer0.request.ClassificationsRequest;
24 import org.simantics.db.layer0.variable.AbstractChildVariable;
25 import org.simantics.db.layer0.variable.NodeSupport;
26 import org.simantics.db.layer0.variable.StandardAssertedGraphPropertyVariable;
27 import org.simantics.db.layer0.variable.StandardConstantGraphPropertyVariable;
28 import org.simantics.db.layer0.variable.Variable;
29 import org.simantics.db.layer0.variable.VariableNode;
30 import org.simantics.layer0.Layer0;
31 import org.simantics.simulator.variable.NodeManager;
32 import org.simantics.structural2.Functions;
33 import org.simantics.structural2.procedural.Connection;
34 import org.simantics.structural2.procedural.ConnectionPoint;
35 import org.simantics.structural2.procedural.Expression;
36 import org.simantics.structural2.procedural.Interface;
37 import org.simantics.structural2.procedural.Property;
38 import org.simantics.structural2.procedural.Terminal;
39 import org.simantics.utils.datastructures.Pair;
40 import org.slf4j.LoggerFactory;
41
42 public class StandardProceduralChildVariable extends AbstractChildVariable {
43
44     private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StandardProceduralChildVariable.class);
45         /*
46          * Extension points
47          * 
48          */
49         public Variable getPossibleSpecialChild(ReadGraph graph, String name) throws DatabaseException {
50                 return null;
51         }
52
53         public void collectSpecialChildren(ReadGraph graph, Map<String, Variable> children) throws DatabaseException {
54         }
55
56         /*
57          * Standard implementation
58          * 
59          */
60         
61         final protected String name;
62         final protected Variable parent;
63         final private Resource type;
64         final private Map<String, Variable> properties;
65         final private List<Object> propertyIdentity;
66         
67     public static class FixedConnection implements org.simantics.structural2.variables.Connection {
68
69                 final public Collection<Pair<String,Resource>> cps = new ArrayList<Pair<String,Resource>>();
70         
71         final private Variable parent;
72         
73         public FixedConnection(Variable parent) {
74             this.parent = parent;
75         }
76         
77         @Override
78         public Collection<Variable> getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException {
79                 
80                 Set<Variable> result = new THashSet<Variable>();
81             for(Pair<String,Resource> cp : cps) {
82                 Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first); 
83                 Variable cp2 = component.getPossibleProperty(graph, cp.second);
84                 if(cp2 != null)
85                         for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, relationType)) {
86                                 result.add(desc.getVariable(graph));
87                         }
88                 else
89                         LOGGER.warn("no cp " + cp.first + " for " + component.getURI(graph));
90             }
91             return result;
92             
93         }
94         
95                 @Override
96                 public Collection<String> getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException {
97                         
98                 Set<String> result = new THashSet<String>();
99             for(Pair<String,Resource> cp : cps) {
100                 Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first); 
101                 Variable cp2 = component.getPossibleProperty(graph, cp.second);
102                 if(cp2 != null)
103                         for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, relationType)) {
104                                 result.add(desc.getURI(graph));
105                         }
106                 else
107                         LOGGER.warn("no cp " + cp.first + " for " + component.getURI(graph));
108             }
109             return result;
110                         
111                 }
112                 
113                 @Override
114                 public Collection<VariableConnectionPointDescriptor> getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException {
115                         
116                 Set<VariableConnectionPointDescriptor> result = new THashSet<VariableConnectionPointDescriptor>();
117             for(Pair<String,Resource> cp : cps) {
118                 Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first); 
119                 Variable cp2 = component.getPossibleProperty(graph, cp.second);
120                 if(cp2 != null)
121                         result.addAll(ConnectionBrowser.flatten(graph, component, cp.second, relationType));
122                 else
123                         LOGGER.warn("no cp " + cp.first + " for " + component.getURI(graph));
124             }
125             return result;
126                         
127                 }        
128
129         @Override
130                 public int hashCode() {
131                         final int prime = 31;
132                         int result = 1;
133                         result = prime * result + ((cps == null) ? 0 : cps.hashCode());
134                         result = prime * result
135                                         + ((parent == null) ? 0 : parent.hashCode());
136                         return result;
137                 }
138
139                 @Override
140                 public boolean equals(Object obj) {
141                         if (this == obj)
142                                 return true;
143                         if (obj == null)
144                                 return false;
145                         if (getClass() != obj.getClass())
146                                 return false;
147                         FixedConnection other = (FixedConnection) obj;
148                         if (cps == null) {
149                                 if (other.cps != null)
150                                         return false;
151                         } else if (!cps.equals(other.cps))
152                                 return false;
153                         if (parent == null) {
154                                 if (other.parent != null)
155                                         return false;
156                         } else if (!parent.equals(other.parent))
157                                 return false;
158                         return true;
159                 }
160
161     }
162     
163         public StandardProceduralChildVariable(ReadGraph graph, Variable parent, VariableNode node, String name, Resource type, List<Property> properties, Collection<Connection> conns) throws DatabaseException {
164                 super(node);
165                 assert name != null;
166         assert type != null;
167         this.name = name;
168                 this.parent = parent;
169                 this.type = type;
170                 this.properties = new THashMap<String,Variable>();
171                 
172                 this.propertyIdentity = new ArrayList<Object>(properties.size()+conns.size());
173                 propertyIdentity.addAll(properties);
174                 propertyIdentity.addAll(conns);
175                 
176                 Layer0 L0 = Layer0.getInstance(graph);
177
178                 Map<String,Statement> assertedProperties = new THashMap<String, Statement>();
179                 for(Statement stm : graph.getAssertedStatements(type, L0.HasProperty)) {
180             String pn = graph.getRelatedValue(stm.getPredicate(), L0.HasName, Bindings.STRING);
181             assertedProperties.put(pn, stm);
182                 }
183                 
184         Collection<Object> nodeProperties = All.getPossibleNodeProperties(graph, (AbstractChildVariable)this);
185         Set<String> used = new HashSet<String>(nodeProperties.size());
186         for(Object nodeProperty : nodeProperties) {
187             @SuppressWarnings("rawtypes")
188             NodeSupport support = node.support;
189             @SuppressWarnings("rawtypes")
190             NodeManager manager = support.manager;
191             @SuppressWarnings("unchecked")
192             String pName = manager.getName(nodeProperty);
193             used.add(pName);
194             Statement assertedProperty = assertedProperties.get(pName); 
195             if(assertedProperty != null) {
196                 this.properties.put(pName, new StandardAssertedGraphPropertyVariable(graph, this, new VariableNode(support, nodeProperty), assertedProperty.getSubject(), assertedProperty.getPredicate(), assertedProperty.getObject()));
197             }
198         }
199         
200         for(Map.Entry<String, Statement> entry : assertedProperties.entrySet()) {
201             String pName = entry.getKey();
202             if(used.contains(pName)) continue;
203             Statement assertedProperty = entry.getValue();
204             this.properties.put(pName, new StandardAssertedGraphPropertyVariable(graph, this, null, assertedProperty.getSubject(), assertedProperty.getPredicate(), assertedProperty.getObject()));
205         }
206                 
207                 
208                 for(Property p : properties) {
209                     String pn = graph.getRelatedValue(p.relation, L0.HasName, Bindings.STRING);
210                     if(p.value == null) {
211                         Logger.defaultLogError("StandardProceduralChildVariable " + getURI(graph) + ": null value for property " + pn);
212                     } else if (p.value instanceof Expression) {
213                         Expression expression = (Expression)p.value;
214                             this.properties.put(pn, new StructuralProceduralExpressionPropertyVariable(graph, this, p.relation, expression.text) );
215                     } else {
216                             this.properties.put(pn, new StandardConstantGraphPropertyVariable(graph, this, p.relation, p.value) );
217                     }
218                         
219                         
220                 }
221             Map<Resource,FixedConnection> map = new HashMap<Resource,FixedConnection>();
222                 for(Connection conn : conns) {
223                     Resource p = null;
224                     List<Pair<String,Resource>> cps = new ArrayList<Pair<String,Resource>>();
225                     for(ConnectionPoint cp : conn.connectionPoints) {
226                         if(cp instanceof Terminal) {
227                             Terminal t = (Terminal)cp;
228                             if(t.component.equals(name)) {
229                                 p = t.relation;
230                                 continue;
231                             }
232                             cps.add(Pair.make(t.component, t.relation));
233                         }
234                         if(cp instanceof Interface) {
235                                 Interface inf = (Interface)cp;
236                             cps.add(new Pair<String,Resource>(null, inf.relation));
237                         }
238                     }
239                     if(p != null) {
240                         FixedConnection fc = map.get(p);
241                         if(fc == null) {
242                                 fc = new FixedConnection(parent);
243                                 map.put(p, fc);
244                         }
245                         fc.cps.addAll(cps);             
246                     }
247                 }
248                 for(Map.Entry<Resource, FixedConnection> entry : map.entrySet()) {
249                         Resource cp = entry.getKey();
250             String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);
251                 this.properties.put(cpName, new StandardConstantGraphPropertyVariable(graph, this, cp, entry.getValue()));
252                 }
253                 
254         }
255
256         @Override
257         public void validate(ReadGraph graph) throws DatabaseException {
258         }
259         
260         @Override
261         public Resource getType(ReadGraph graph) throws DatabaseException {
262             return type;
263         }
264         
265         @Override
266         public Resource getPossibleType(ReadGraph graph) throws DatabaseException {
267             return type;
268         }
269         
270         @Override
271         public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException {
272                 if (graph.isInheritedFrom(type, baseType))
273                         return type;
274                 throw new NoSingleResultException("variable " + getPossibleURI(graph) + " has no type");
275         }
276         
277         @Override
278         public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException {
279                 return graph.isInheritedFrom(type, baseType) ? type : null;
280         }
281         
282         @Override
283         protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException {
284             return properties.get(name);
285         }
286
287         @Override
288         public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
289             return Functions.structuralChildDomainChildren.getVariable(graph, this, name);
290         }
291
292         @Override
293         public Map<String, Variable> collectDomainProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException {
294                 if(!this.properties.isEmpty()) {
295                         if(properties == null) properties = new THashMap<String,Variable>(this.properties.size());
296                         properties.putAll(this.properties);
297                 }
298                 return properties;
299         }
300
301         @Override
302         public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
303              Map<String,Variable> result = Functions.structuralChildDomainChildren.getVariables(graph, this, null);
304              if(result == null) return Collections.emptyList();
305              else return result.values();
306         }
307
308         public Set<String> getClassifications(ReadGraph graph) throws DatabaseException {
309                 Resource type = getPossibleType(graph);
310                 return (type != null)
311                                 ? graph.syncRequest(new ClassificationsRequest(Collections.singleton(type)))
312                                 : Collections.<String>emptySet();
313         }
314
315         @Override
316         public String getName(ReadGraph graph) throws DatabaseException {
317             return name;
318         }
319
320         @Override
321         public Variable getParent(ReadGraph graph) throws DatabaseException {
322                 return parent;
323         }
324         
325         @Override
326         final public Resource getRepresents(ReadGraph graph) throws DatabaseException {
327             return null;
328         }
329
330         @Override
331         public int hashCode() {
332                 return parent.hashCode() + 31*name.hashCode() + 41*type.hashCode() + 71*System.identityHashCode(propertyIdentity);
333         }
334
335         @Override
336         public boolean equals(Object obj) {
337                 
338                 if (this == obj)
339                         return true;
340                 if (obj == null)
341                         return false;
342                 if (getClass() != obj.getClass())
343                         return false;
344                 
345                 StandardProceduralChildVariable other = (StandardProceduralChildVariable) obj;
346                 
347                 if(!name.equals(other.name)) return false;
348                 if(!type.equals(other.type)) return false;
349                 if(!parent.equals(other.parent)) return false;
350                 if(propertyIdentity != other.propertyIdentity) return false;
351                                 
352                 return true;
353                 
354         }
355         
356 }