]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java
Work in progress
[simantics/platform.git] / bundles / org.simantics.structural2 / src / org / simantics / structural2 / variables / ActualConnectionDescriptor.java
1 package org.simantics.structural2.variables;
2
3 import java.util.Collection;
4
5 import org.simantics.databoard.Bindings;
6 import org.simantics.databoard.util.URIStringUtils;
7 import org.simantics.db.ReadGraph;
8 import org.simantics.db.Resource;
9 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
10 import org.simantics.db.common.request.UnaryRead;
11 import org.simantics.db.common.utils.NameUtils;
12 import org.simantics.db.exception.DatabaseException;
13 import org.simantics.db.layer0.variable.Variable;
14 import org.simantics.layer0.Layer0;
15 import org.simantics.modeling.ModelingResources;
16 import org.simantics.structural.stubs.StructuralResource2;
17 import org.simantics.structural2.DefinedUCInterfaceMap;
18 import org.simantics.structural2.Functions;
19 import org.simantics.structural2.Functions.InterfaceResolution;
20 import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass;
21 import org.simantics.structural2.variables.ConnectionBrowser.IsLeafType;
22
23 /*
24  * This connection descriptor
25  * 
26  * -has not been lifted into interface
27  * -has a structural configuration defined as resources
28  * -might not be drilled
29  * 
30  * Note: these are constructed after climb (before drill) phase of the connection browser. This means that
31  * the component can still contain sub structure during connection browsing. This means that some descriptors
32  * are not final and are replaced by correct descriptors during drill phase.
33  * 
34  */
35 class ActualConnectionDescriptor extends AbstractVariableConnectionPointDescriptor {
36         
37         /*
38          * This is the nearest known ancestor variable
39          */
40         final Variable root;
41         /*
42          * A component on variable path under the root variable.
43          */
44         final Resource component;
45         /*
46          * TODO
47          */
48         final Resource componentType;
49         /*
50          * The connection point that has type of the component as its domain
51          */
52         final Resource cp;
53         
54         public ActualConnectionDescriptor(Variable root, Resource component, Resource componentType, Resource cp) {
55                 this.root = root;
56                 this.component = component;
57                 this.componentType = componentType;
58                 this.cp = cp;
59         }
60         
61         static class ActualConnectionDescriptorInterfaceDescription extends UnaryRead<ActualConnectionDescriptor, Collection<InterfaceResolution>> {
62
63                 public ActualConnectionDescriptorInterfaceDescription(ActualConnectionDescriptor desc) {
64                         super(desc);
65                 }
66
67                 @Override
68                 public Collection<InterfaceResolution> perform(ReadGraph graph) throws DatabaseException {
69                         
70                         System.err.println("ActualConnectionDescriptorInterfaceDescription");
71                         
72                         ConnectionBrowser.reportDescriptor(graph, parameter);
73                 
74                 /*
75                  * The componentType is the possibly replaced (STR.ReplaceableDefinedComponentType) type
76                  */
77                 StructuralComponentClass clazz = StructuralComponentClass.get(graph, parameter.componentType);
78                 if(StructuralComponentClass.PRIMITIVE.equals(clazz)) {
79                         return null;
80                 } else if(StructuralComponentClass.DEFINED.equals(clazz)) {
81                         final Collection<InterfaceResolution> interfaces = graph.syncRequest(new DefinedUCInterfaceMap(parameter.componentType));
82                         if(interfaces != null) return interfaces;
83                         else return Functions.BUILTIN_STRUCTURAL_CPS;
84                 } else if(StructuralComponentClass.REPLACEABLE.equals(clazz)) {
85                         throw new DatabaseException("ConnectionBrowser does not support nested replaceable defined structural types.");
86                 } else {
87                         return Functions.computeInterfacePaths(graph, parameter.getVariable(graph).getParent(graph));   
88                 }
89                         
90                 }
91                 
92         }
93         
94         @Override
95         public boolean isLeaf(ReadGraph graph) throws DatabaseException {
96                 
97                 StructuralResource2 STR = StructuralResource2.getInstance(graph);
98                 Resource type = graph.getPossibleType(component, STR.Component);
99                 return graph.syncRequest(new IsLeafType(type));
100                 
101         }
102         
103         @Override
104         public Collection<InterfaceResolution> getInterfaceDescription(ReadGraph graph) throws DatabaseException {
105                 return graph.syncRequest(new ActualConnectionDescriptorInterfaceDescription(this), TransientCacheAsyncListener.<Collection<InterfaceResolution>>instance());
106         }
107         
108         public Resource getConnectionPointResource(ReadGraph graph) throws DatabaseException {
109                 return cp;
110         }
111         
112         static class ComputeVariable extends UnaryRead<ActualConnectionDescriptor, Variable> {
113
114                 public ComputeVariable(ActualConnectionDescriptor desc) {
115                         super(desc);
116                 }
117
118                 @Override
119                 public Variable perform(ReadGraph graph) throws DatabaseException {
120                         
121                 Variable c = ConnectionBrowser.resolve(graph, parameter.root, parameter.component);
122                 if(c != null) {
123                         Variable cnp = c.getPossibleProperty(graph, parameter.cp);
124                         if(cnp != null) {
125                                 return cnp;
126                         }
127                 }
128                 
129                 throw new DatabaseException("Unresolved connection point (root=" + parameter.root.getURI(graph) + ", component=" + NameUtils.getURIOrSafeNameInternal(graph, parameter.component) + ", cp=" + NameUtils.getURIOrSafeNameInternal(graph, parameter.cp) + ")");
130                         
131                 }
132                 
133         }
134         
135         @Override
136         public Variable getVariable(ReadGraph graph) throws DatabaseException {
137                 return graph.syncRequest(new ComputeVariable(this), TransientCacheAsyncListener.<Variable>instance());
138         }
139
140         @Override
141         public String getURI(ReadGraph graph) throws DatabaseException {
142                 
143                 Variable var = getVariable(graph);
144                 return var.getURI(graph);
145                 
146         }
147
148         @Override
149         public boolean isFlattenedFrom(ReadGraph graph, Variable possiblyStructuralCp) throws DatabaseException {
150
151                 // This is a top-level configured connection point - we return true if possiblyStructuralCp is actually this connection point
152                 
153                 Resource otherCp = possiblyStructuralCp.getPossiblePredicateResource(graph);
154                 if(!cp.equals(otherCp)) return false;
155
156                 Variable otherComponentVariable = possiblyStructuralCp.getParent(graph);
157                 
158                 Resource otherComponent = otherComponentVariable.getPossibleRepresents(graph);
159                 if(!component.equals(otherComponent)) return false;
160
161                 Variable otherContainer = otherComponentVariable.getParent(graph);
162                 if(otherContainer.equals(root)) return true;
163                 
164                 return getVariable(graph).equals(possiblyStructuralCp);
165                 
166         }
167         
168         @Override
169         public String getRelativeRVI(ReadGraph graph, Variable base) throws DatabaseException {
170
171         Layer0 L0 = Layer0.getInstance(graph);
172         String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);
173                 
174         if(cpName.startsWith("/")) {
175             ModelingResources MOD = ModelingResources.getInstance(graph);
176             if(graph.isInstanceOf(component, MOD.ReferenceElement)) {
177                 return "#" + cpName;
178             }
179             }
180             
181                 if(root.equals(base.getParent(graph))) {
182                         
183                         StringBuilder b = new StringBuilder();
184                         b.append("./");
185                         String cName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING);
186                         b.append(URIStringUtils.escape(cName));
187                         b.append("#");
188                         b.append(cpName);
189                         
190                         return b.toString();
191                         
192                 }
193
194                 return super.getRelativeRVI(graph, base);
195
196         }
197         
198 }