]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Replaceable Defined Component Types 11/2011/7
authorAntti Villberg <antti.villberg@semantum.fi>
Fri, 17 Aug 2018 11:01:31 +0000 (14:01 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 28 Aug 2018 13:44:17 +0000 (13:44 +0000)
gitlab #83

Change-Id: I26ec5d8f6a66805999663e0856601e5ab2f98cb0

13 files changed:
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java
bundles/org.simantics.layer0/graph/Layer0.pgraph
bundles/org.simantics.structural.ontology/graph/Structural.pgraph
bundles/org.simantics.structural2/scl/Simantics/Structural.scl
bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl2.java [new file with mode: 0644]
bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java [new file with mode: 0644]
bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java
bundles/org.simantics.structural2/src/org/simantics/structural2/queries/ConnectionPointMapOfResource.java
bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java
bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ActualConnectionDescriptor.java
bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java
bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java [new file with mode: 0644]
bundles/org.simantics.structural2/src/org/simantics/structural2/variables/VariableConnectionPointDescriptor.java

index d9366b132aa2a41e471bf0cd2ea7d1c9b19cef96..53c5fb5b72922d4885dd0c03791f4c4f3c989902 100644 (file)
@@ -39,6 +39,8 @@ import org.simantics.db.layer0.variable.RVI.ResourceRVIPart;
 import org.simantics.db.layer0.variable.RVI.StringRVIPart;
 import org.simantics.db.layer0.variable.Variables.Role;
 import org.simantics.layer0.Layer0;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function2;
 
 /**
  * Abstract implementation of Variable -interface.
@@ -187,18 +189,6 @@ public abstract class AbstractVariable implements Variable {
                return graph.getPossibleRelatedValue2(represents, graph.getService(Layer0.class).HasLabel, getParent(graph), Bindings.STRING);
     }
 
-    public Resource getType(ReadGraph graph) throws DatabaseException {
-       
-        Resource resource = getPossibleRepresents(graph);
-        if(resource == null) {
-               String uri = getPossiblePropertyValue(graph, "typeURI");
-               if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.<Resource>instance());
-            throw new DatabaseException("No type for " + getURI(graph));
-        }
-        return graph.getSingleType(resource);
-        
-    }
-    
     public RVIPart getRVIPart(ReadGraph graph) throws DatabaseException {
         throw new UnsupportedOperationException();
     }
@@ -950,42 +940,108 @@ public abstract class AbstractVariable implements Variable {
         }
        }
 
-       @Override
-       public Resource getPossibleType(ReadGraph graph) throws DatabaseException {
+    public Resource getType(ReadGraph graph) throws DatabaseException {
+        Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, Layer0.getInstance(graph).Entity, getPossibleTypeFunction(graph));
+        if (typeFromFunction != null)
+            return typeFromFunction;
+
         Resource resource = getPossibleRepresents(graph);
-        if(resource == null) {
-               String uri = getPossiblePropertyValue(graph, "typeURI");
-               if(uri != null) return graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.<Resource>instance());
+        if (resource == null) {
+            String uri = getPossiblePropertyValue(graph, "typeURI");
+            if (uri != null)
+                return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri),
+                        TransientCacheAsyncListener.<Resource> instance());
+            throw new DatabaseException("No type for " + getURI(graph));
+        }
+        return graph.getSingleType(resource);
+    }
+
+    @Override
+    public Resource getPossibleType(ReadGraph graph) throws DatabaseException {
+        try {
+            Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, Layer0.getInstance(graph).Entity, getPossibleTypeFunction(graph));
+            if (typeFromFunction != null)
+                return typeFromFunction;
+        } catch (Throwable t) {
+            return null;
+        }
+
+        Resource resource = getPossibleRepresents(graph);
+        if (resource == null) {
+            String uri = getPossiblePropertyValue(graph, "typeURI");
+            if (uri != null)
+                return graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.<Resource> instance());
             return null;
         }
         return graph.getPossibleObject(resource, Layer0.getInstance(graph).InstanceOf);
-       }
+    }
 
     public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException {
+        Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, baseType, getPossibleTypeFunction(graph));
+        if (typeFromFunction != null)
+            return typeFromFunction;
+
         Resource resource = getPossibleRepresents(graph);
-        if(resource == null) {
-               String uri = getPossiblePropertyValue(graph, "typeURI");
-               if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.<Resource>instance());
+        if (resource == null) {
+            String uri = getPossiblePropertyValue(graph, "typeURI");
+            if (uri != null)
+                return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri),
+                        TransientCacheAsyncListener.<Resource> instance());
             throw new DatabaseException("No type for " + getURI(graph));
         }
         return graph.getSingleType(resource, baseType);
     }
 
-       @Override
-       public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException {
+    @Override
+    public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException {
+        try {
+            Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, baseType, getPossibleTypeFunction(graph));
+            if (typeFromFunction != null)
+                return typeFromFunction;
+        } catch (Throwable t) {
+            return null;
+        }
+
         Resource resource = getPossibleRepresents(graph);
         if(resource == null) {
-               String uri = getPossiblePropertyValue(graph, "typeURI");
-               if(uri != null) {
-                       Resource type = graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.<Resource>instance());
-                       if(type == null) return null;
-                       if(graph.isInheritedFrom(type, baseType)) return type;
-                       else return null;
-               }
+            String uri = getPossiblePropertyValue(graph, "typeURI");
+            if(uri != null) {
+                Resource type = graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.<Resource>instance());
+                if(type == null) return null;
+                if(graph.isInheritedFrom(type, baseType)) return type;
+                else return null;
+            }
             return null;
         }
         return graph.getPossibleType(resource, baseType);
-       }
+    }
+
+    private Resource getTypeFromPossibleTypeFunction(ReadGraph graph, Resource baseType,
+            Function2<Variable, Resource, Resource> fn) throws DatabaseException {
+        if (fn == null)
+            // Type function was not defined - return nothing
+            return null;
+
+        SCLContext sclContext = SCLContext.getCurrent();
+        Object oldGraph = sclContext.put("graph", graph);
+        try {
+            return (Resource) fn.apply(this, baseType);
+        } catch (Throwable t) {
+            if (t instanceof DatabaseException)
+                throw (DatabaseException) t;
+            throw new DatabaseException(t);
+        } finally {
+            sclContext.put("graph", oldGraph);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private Function2<Variable, Resource, Resource> getPossibleTypeFunction(ReadGraph graph) throws DatabaseException {
+        Variable custom = getPossibleProperty(graph, "typeResource");
+        return custom != null
+            ? (Function2<Variable, Resource, Resource>) custom.getPossibleValue(graph)
+            : null;
+    }
 
     public Map<String, Variable> collectDomainProperties(ReadGraph graph, String classification, Map<String, Variable> map) throws DatabaseException {
        Map<String,Variable> all = collectDomainProperties(graph, null);
index ec2048acbd40d158762430d95b9b0a0e8a78167f..5fe74ec0175fd9e358bd724dc2e36f47672c2fdb 100644 (file)
@@ -25,6 +25,9 @@ L0.Entity : L0.Type
     >-- L0.typeURI <R L0.HasProperty : L0.FunctionalRelation
         L0.HasLabel "Type URI"
         --> L0.String
+    >-- L0.typeResource <R L0.HasProperty : L0.FunctionalRelation
+        L0.HasLabel "Type Resource"
+        ==> "Variable -> Resource -> <ReadGraph> Resource"
     >-- L0.HasComment --> L0.String <R L0.HasProperty
     >-- L0.ConsistsOf --> L0.Entity <R L0.IsComposedOf
         L0.InverseOf L0.PartOf : L0.FunctionalRelation
index aa31879c524944a994d17f72065de7d328036170..fa0624ce75605b8ccc8b82b161b881071cb4e0cd 100644 (file)
@@ -36,6 +36,8 @@ STR.AbstractDefinedComponentType <T STR.ComponentType
 
 STR.DefinedComponentType <T STR.AbstractDefinedComponentType
 
+STR.ReplaceableDefinedComponentType <T STR.AbstractDefinedComponentType
+
 STR.ProceduralComponentType <T STR.AbstractDefinedComponentType
     >-- STR.ProceduralComponentType.code --> STR.ProceduralComponentTypeCode <R L0.HasProperty : L0.TotalFunction
     >-- STR.ProceduralComponentType.environment --> L0.SCLValue.Environment <R L0.IsRelatedTo : L0.FunctionalRelation
@@ -262,6 +264,10 @@ STR.Component
   @L0.assert L0.domainChildren 
     STR.Functions.structuralChildDomainChildren : L0.ExternalValue
       L0.HasValueType "VariableMap"
+  @L0.assert L0.typeResource
+    _ : L0.SCLValue
+      L0.SCLValue.expression "structuralTypeResource"
+      L0.HasValueType "Variable -> Resource -> <ReadGraph> Resource"
 
 STR.Run
   @L0.assert L0.domainChildren 
@@ -343,4 +349,10 @@ STR.ComponentTypeScript <T L0.Entity
 STR.ComponentType.Locked
     @L0.defTag
     L0.HasDomain STR.ComponentType
-    L0.HasDescription "Indicates that the component type is locked and cannot be opened for editing."
\ No newline at end of file
+    L0.HasDescription "Indicates that the component type is locked and cannot be opened for editing."
+    
+STR.TypeOverride <T L0.Entity
+    >-- STR.TypeOverride.HasOriginalType --> STR.ComponentType <R L0.IsRelatedTo : L0.TotalFunction
+    >-- STR.TypeOverride.HasReplacementType --> STR.ComponentType <R L0.IsRelatedTo : L0.TotalFunction 
+STR.HasTypeOverride --> STR.TypeOverride <R L0.IsRelatedTo    
\ No newline at end of file
index 33b0ec14713945bfbd30b2460a91bdc886a47ef7..a568a5731ea8a4f5406b303d4b6a544f0b9c5ce2 100644 (file)
@@ -14,3 +14,4 @@ importJava "org.simantics.structural2.variables.Connection" where
 
 importJava "org.simantics.structural2.utils.StructuralUtils" where
   structuralConnectionConnectionPoints :: StructuralConnection -> Resource -> <ReadGraph> [Variable]
+  structuralTypeResource :: Variable -> Resource -> <ReadGraph> Resource
\ No newline at end of file
diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl2.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl2.java
new file mode 100644 (file)
index 0000000..e4b898a
--- /dev/null
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.structural2;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.structural2.variables.Connection;
+import org.simantics.structural2.variables.ConnectionBrowser;
+import org.simantics.structural2.variables.VariableConnectionPointDescriptor;
+
+import gnu.trove.set.hash.THashSet;
+
+public class ConnectionImpl2 implements Connection {
+
+    private final Variable component;
+    private final Resource predicate;
+    
+    public ConnectionImpl2(Variable component, Resource predicate) {
+        this.component = component;
+        this.predicate = predicate;
+    }
+    
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((predicate == null) ? 0 : predicate.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ConnectionImpl2 other = (ConnectionImpl2) obj;
+        if (predicate == null) {
+            if (other.predicate != null)
+                return false;
+        } else if (!predicate.equals(other.predicate))
+            return false;
+        return true;
+    }
+
+    @Override
+    public Collection<Variable> getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException {
+        Set<Variable> result = new THashSet<Variable>();
+        for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, predicate, relationType)) {
+            result.add(desc.getVariable(graph));
+        }
+        return result;
+    }
+    
+    @Override
+    public Collection<String> getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException {
+        Set<String> result = new THashSet<String>();
+        for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, predicate, relationType)) {
+            result.add(desc.getURI(graph));
+        }
+        return result;
+    }
+
+    @Override
+    public Collection<VariableConnectionPointDescriptor> getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException {
+        return ConnectionBrowser.flatten(graph, component, predicate, relationType);
+    }
+
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/DefinedUCInterfaceMap.java
new file mode 100644 (file)
index 0000000..eb2b195
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.structural2;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Statement;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.structural2.Functions.InterfaceResolution;
+
+public class DefinedUCInterfaceMap extends ResourceRead<Collection<InterfaceResolution>> {
+
+    public DefinedUCInterfaceMap(Resource resource) {
+        super(resource);
+    }
+
+    @Override
+    public Collection<InterfaceResolution> perform(ReadGraph graph)
+            throws DatabaseException {
+
+        StructuralResource2 STR = StructuralResource2.getInstance(graph);
+        Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);
+        if(definition != null) {
+            Collection<InterfaceResolution> result = new ArrayList<>();
+            Layer0 L0 = Layer0.getInstance(graph);
+            for(Resource cp : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, STR.ConnectionRelation))) {
+                String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);
+                for(Resource conn : graph.getObjects(cp, STR.IsBoundBy)) {
+                    Statement stm = graph.getPossibleStatement(conn, STR.Connects);
+                    if(stm == null) continue;
+                    Resource component = stm.getObject();
+                    String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING);
+                    result.add(new InterfaceResolution(cp, cpName, componentName, graph.getInverse(stm.getPredicate())));
+                }
+            }
+            return result;
+        }
+        return null;
+    }
+
+}
\ No newline at end of file
index d9d8857af77210acfa2be0f1d170981f547ca2a5..f429fdc91d104fabcaf53d6fd6c5752bdb1699ad 100644 (file)
@@ -27,6 +27,7 @@ import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.request.PossibleIndexRoot;
+import org.simantics.db.common.request.PossibleObjectWithType;
 import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
 import org.simantics.db.exception.DatabaseException;
@@ -47,6 +48,7 @@ import org.simantics.db.layer0.variable.Variable;
 import org.simantics.db.layer0.variable.VariableMap;
 import org.simantics.db.layer0.variable.VariableMapImpl;
 import org.simantics.db.layer0.variable.VariableNode;
+import org.simantics.db.service.CollectionSupport;
 import org.simantics.issues.common.IssueUtils;
 import org.simantics.layer0.Layer0;
 import org.simantics.scl.reflection.annotations.SCLValue;
@@ -66,14 +68,12 @@ import org.simantics.structural2.queries.ConnectionPointMapOfResource;
 import org.simantics.structural2.queries.PossibleConnectionPointInfo;
 import org.simantics.structural2.scl.CompileStructuralValueRequest;
 import org.simantics.structural2.scl.procedural.CompileProceduralComponentTypeRequest;
+import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass;
 import org.simantics.structural2.variables.Connection;
-import org.simantics.structural2.variables.ConnectionBrowser;
 import org.simantics.structural2.variables.StandardProceduralChildVariable;
-import org.simantics.structural2.variables.VariableConnectionPointDescriptor;
 import org.simantics.utils.datastructures.MapList;
 
 import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
 
 public class Functions {
        
@@ -153,39 +153,6 @@ public class Functions {
                
        };
        
-       static class ConnectionImpl implements Connection {
-
-               final private StandardGraphPropertyVariable connectionPoint;
-               
-               public ConnectionImpl(StandardGraphPropertyVariable connectionPoint) {
-                       this.connectionPoint = connectionPoint;
-               }
-               
-               @Override
-               public Collection<Variable> getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException {
-                   Set<Variable> result = new THashSet<Variable>();
-                   for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) {
-                       result.add(desc.getVariable(graph));
-                   }
-                   return result;
-               }
-               
-               @Override
-               public Collection<String> getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException {
-                   Set<String> result = new THashSet<String>();
-                   for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType)) {
-                       result.add(desc.getURI(graph));
-                   }
-                   return result;
-               }
-
-               @Override
-               public Collection<VariableConnectionPointDescriptor> getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException {
-                   return ConnectionBrowser.flatten(graph, connectionPoint.parent, connectionPoint.property.predicate, relationType);
-               }
-
-       }
-       
        @SCLValue(type="ValueAccessor")
        public static final ValueAccessor connectionValueAccessor = new ValueAccessor() {
 
@@ -213,7 +180,7 @@ public class Functions {
                @Override
                public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
                        StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context; 
-                       return new ConnectionImpl(variable);
+                       return new ConnectionImpl2(context.getParent(graph), variable.property.predicate);
                }
 
                @Override
@@ -233,10 +200,10 @@ public class Functions {
        
                public Variable getPossibleConnectionPointFromContext(ReadGraph graph, Variable variable, Resource context, String name) throws DatabaseException {
 
-                       Map<String, Resource> connectionPoints = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,Resource>>instance());
-                       Resource cp = connectionPoints.get(name);
+                       Map<String, PropertyInfo> connectionPoints = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,PropertyInfo>>instance());
+                       PropertyInfo cp = connectionPoints.get(name);
                        if(cp == null) return null;
-                       else return new StandardGraphPropertyVariable(graph, variable, cp);
+                       else return new StandardGraphPropertyVariable(graph, variable, cp.predicate);
                        
                }
                
@@ -244,16 +211,16 @@ public class Functions {
                        
                        if(graph.isImmutable(context)) {
 
-                               Map<String, Resource> cps = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,Resource>>instance());
+                               Map<String, PropertyInfo> cps = graph.syncRequest(new ConnectionPointMapOfResource(graph, context), TransientCacheAsyncListener.<Map<String,PropertyInfo>>instance());
                                if(cps.size() == 0) return map;
                                
                                if(map == null) map = new THashMap<String,Variable>(cps.size());
                                
-                               for(Map.Entry<String, Resource> entry : cps.entrySet()) {
+                               for(Map.Entry<String, PropertyInfo> entry : cps.entrySet()) {
                                        String name = entry.getKey();
-                                       Resource cp = entry.getValue();
-                                       if(needSynchronized && !graph.isInstanceOf(cp, STR.SynchronizedConnectionRelation)) continue;
-                                       map.put(name, new StandardGraphPropertyVariable(graph, variable, cp));
+                                       PropertyInfo cp = entry.getValue();
+                                       if(needSynchronized && !graph.isInstanceOf(cp.predicate, STR.SynchronizedConnectionRelation)) continue;
+                                       map.put(name, new StandardGraphPropertyVariable(graph, variable, cp.predicate));
                                }
                                
                                return map;
@@ -313,78 +280,30 @@ public class Functions {
                
        };
 
-       static class StructuralChildMapOfResource extends ResourceRead<Map<String, Resource>> {
+       static class StructuralRunContext extends ResourceRead<Resource> {
 
-               public StructuralChildMapOfResource(Resource resource) {
+               public StructuralRunContext(Resource resource) {
                        super(resource);
                }
 
                @Override
-               public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
-                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
-                       Resource type = graph.getPossibleType(resource, STR.Component);
-                       if(type != null) {
-                               Resource definition = graph.getPossibleObject(type, STR.IsDefinedBy);
-                               if(definition != null) {
-                                       Map<String, Resource> map = graph.syncRequest(new UnescapedChildMapOfResource(definition));
-                                       if (!map.isEmpty())
-                                               return map;
-                               } 
-                       }
-                       Map<String, Resource> directChildren = graph.syncRequest(new UnescapedChildMapOfResource(resource));
-                       return directChildren;
-               }
-
-       }
-
-    static class StructuralChildMapOfResourceT extends ResourceRead<Map<String, Resource>> {
-
-        public StructuralChildMapOfResourceT(Resource resource) {
-            super(resource);
-        }
-
-        @Override
-        public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
-            StructuralResource2 STR = StructuralResource2.getInstance(graph);
-            Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);
-            if(definition != null) {
-                Map<String, Resource> map = graph.syncRequest(new UnescapedChildMapOfResource(definition));
-                if (!map.isEmpty())
-                    return map;
-            } 
-            return Collections.emptyMap();
-        }
-
-    }
-
-       static class StructuralRunChildMapOfResource extends ResourceRead<Map<String, Resource>> {
-
-               public StructuralRunChildMapOfResource(Resource resource) {
-                       super(resource);
-               }
-
-               public Map<String, Resource> fromContext(ReadGraph graph, Resource context) throws DatabaseException {
-                       return graph.sync(new StructuralChildMapOfResource(context));
-               }
-               
-               @Override
-               public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
+               public Resource perform(ReadGraph graph) throws DatabaseException {
 
                        Layer0 L0 = Layer0.getInstance(graph);
                        SimulationResource SIMU = SimulationResource.getInstance(graph);
                        Resource model = graph.sync(new PossibleIndexRoot(resource));
                        if(graph.isInstanceOf(model, L0.RVIContext)) {
-                               return fromContext(graph, model);
+                               return model;
                        }
                        Resource configuration = graph.getPossibleObject(model, SIMU.HasConfiguration);
                        if(configuration != null) {
                                if(graph.isInstanceOf(configuration, L0.RVIContext)) {
-                                       return fromContext(graph, configuration);
+                                       return configuration;
                                }
                        }
-                       
-                       return Collections.emptyMap();
-                       
+
+                       return null;
+
                }
                
        }
@@ -488,6 +407,143 @@ public class Functions {
             }
         }
         
+       public static class StructuralTypeOverrideMap extends ResourceRead<Map<Resource,Resource>> {
+
+               protected StructuralTypeOverrideMap(Resource composite) {
+                       super(composite);
+               }
+
+               @Override
+               public Map<Resource, Resource> perform(ReadGraph graph) throws DatabaseException {
+                       
+                       Layer0 L0 = Layer0.getInstance(graph);
+                       
+                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                       
+                       CollectionSupport cs = graph.getService(CollectionSupport.class);
+                       
+                       Map<Resource,Resource> result = null;
+                       
+                       for(Resource override : graph.getObjects(resource, STR.HasTypeOverride)) {
+                               Resource original = graph.getSingleObject(override, STR.TypeOverride_HasOriginalType);
+                               Resource replacement = graph.getSingleObject(override, STR.TypeOverride_HasReplacementType);
+                               if(result == null) result = cs.createMap(Resource.class);
+                               result.put(original, replacement);
+                       }
+                       
+                       if(result == null) return Collections.emptyMap();
+                       
+                       return result;
+                       
+               }
+               
+       }
+       
+       public static class StructuralOverrideData {
+               @Override
+               public int hashCode() {
+                       final int prime = 31;
+                       int result = 1;
+                       result = prime * result + ((actualRepresents == null) ? 0 : actualRepresents.hashCode());
+                       result = prime * result + ((actualType == null) ? 0 : actualType.hashCode());
+                       result = prime * result + ((overrideType == null) ? 0 : overrideType.hashCode());
+                       return result;
+               }
+               @Override
+               public boolean equals(Object obj) {
+                       if (this == obj)
+                               return true;
+                       if (obj == null)
+                               return false;
+                       if (getClass() != obj.getClass())
+                               return false;
+                       StructuralOverrideData other = (StructuralOverrideData) obj;
+                       if (actualRepresents == null) {
+                               if (other.actualRepresents != null)
+                                       return false;
+                       } else if (!actualRepresents.equals(other.actualRepresents))
+                               return false;
+                       if (actualType == null) {
+                               if (other.actualType != null)
+                                       return false;
+                       } else if (!actualType.equals(other.actualType))
+                               return false;
+                       if (overrideType == null) {
+                               if (other.overrideType != null)
+                                       return false;
+                       } else if (!overrideType.equals(other.overrideType))
+                               return false;
+                       return true;
+               }
+               Resource actualRepresents;
+               Resource actualType;
+               Resource overrideType;
+               public StructuralOverrideData(Resource actualRepresents, Resource actualType, Resource overrideType) {
+                       this.actualRepresents = actualRepresents;
+                       this.actualType = actualType;
+                       this.overrideType = overrideType;
+               }
+
+               public static StructuralOverrideData compute(ReadGraph graph, Variable context) throws DatabaseException {
+                       return graph.syncRequest(new StructuralOverrideDataRequest(context));
+               }
+               
+               public Resource type() {
+                       if(overrideType != null)
+                               return overrideType;
+                       return actualType;
+               }
+
+               public Resource represents() {
+                       return actualRepresents;
+               }
+
+       }
+       
+       public static class StructuralOverrideDataRequest extends VariableRead<StructuralOverrideData> {
+
+               public StructuralOverrideDataRequest(Variable component) {
+                       super(component);
+               }
+
+               public StructuralOverrideData walk(ReadGraph graph, Variable component, Resource actualRepresents, Resource actualType) throws DatabaseException {
+               Resource represents = component.getPossibleRepresents(graph);
+               if(represents != null) {
+                       Layer0 L0 = Layer0.getInstance(graph);
+                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                       Resource container = graph.syncRequest(new PossibleObjectWithType(represents, L0.PartOf, STR.Composite));
+                       if(container != null) {
+                       Map<Resource,Resource> overrides = graph.syncRequest(new StructuralTypeOverrideMap(container));
+                       Resource override = overrides.get(actualType);
+                       if(override != null) {
+                               return new StructuralOverrideData(actualRepresents, actualType, override);
+                       }
+                       }
+               }
+               Variable parent = component.getParent(graph);
+               if(parent == null) return new StructuralOverrideData(actualRepresents, actualType, null);
+               else return walk(graph, parent, represents, actualType);
+               }
+               
+               @Override
+               public StructuralOverrideData perform(ReadGraph graph) throws DatabaseException {
+
+               Resource represents = variable.getPossibleRepresents(graph);
+               if(represents == null) {
+                       String uri = variable.getPossiblePropertyValue(graph, "typeURI");
+                       if(uri != null) {
+                               Resource actualType = graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.<Resource>instance()); 
+                               return walk(graph, variable, null, actualType);
+                       }
+                       throw new DatabaseException("No type for " + variable.getURI(graph));
+               } else {
+                       return walk(graph, variable, represents, graph.getPossibleType(represents, Layer0.getInstance(graph).Entity));
+               }
+                       
+               }
+               
+       }
+
        
        @SCLValue(type = "VariableMap")
        public static VariableMap structuralChildDomainChildren = new VariableMapImpl() {
@@ -495,53 +551,64 @@ public class Functions {
                @Override
                public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
                        
-               final Resource type = context.getPossibleType(graph);
-               if(type != null) {
-                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
-                   if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
-                           Map<String,Variable> map = graph.syncRequest(new ProceduralSubstructureRequest(context),
-                               TransientCacheListener.<Map<String,Variable>>instance());
-                           if(map != null) return map.get(name);
-                   }
-               }
-
-                   Resource represents = context.getPossibleRepresents(graph);
-            if(represents == null) {
-                Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(type));
+                       Resource type = context.getPossibleType(graph);
+                       if(type == null) return null;
+                       
+                       StructuralComponentClass clazz = StructuralComponentClass.get(graph, type);
+                       if(StructuralComponentClass.PROCEDURAL.equals(clazz)) {
+                   Map<String,Variable> map = graph.syncRequest(new ProceduralSubstructureRequest(context),
+                        TransientCacheListener.<Map<String,Variable>>instance());
+                   if(map != null) return map.get(name);
+                   return null;
+                       } else if (StructuralComponentClass.DEFINED.equals(clazz)) {
+                               StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                               Resource def = graph.getSingleObject(type, STR.IsDefinedBy);
+                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(def));
                 Resource child = children.get(name);
-                return All.getStandardChildDomainChildVariable(graph, context, child, name);
-            }
-            Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResource(represents));
-            Resource child = children.get(name);
-            return All.getStandardChildDomainChildVariable(graph, context, child, name);
+                if(child == null) return null;
+                return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name);
+                       } else {
+                               Resource represents = context.getPossibleRepresents(graph);
+                               if(represents == null) return null;
+                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(represents));
+                Resource child = children.get(name);
+                if(child == null) return null;
+                return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name);
+                       }
+
                }
 
                @Override
                public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
                        
-               final Resource type = context.getPossibleType(graph);
-               if(type != null) {
-                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
-                   if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
-                       Map<String,Variable> mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context),
-                                       TransientCacheListener.<Map<String,Variable>>instance());
-                       if(mapPrime != null) {
-                               if(map != null) {
-                                       map.putAll(mapPrime);
-                                       return map;
-                               }
-                               else
-                                       return mapPrime;
-                       }
-                   }
-               }
-            Resource represents = context.getPossibleRepresents(graph);
-            if(represents == null) {
-                Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResourceT(type));
+                       Resource type = context.getPossibleType(graph);
+                       if(type == null) return null;
+                       
+                       StructuralComponentClass clazz = StructuralComponentClass.get(graph, type);
+                       if(StructuralComponentClass.PROCEDURAL.equals(clazz)) {
+               Map<String,Variable> mapPrime = graph.syncRequest(new ProceduralSubstructureRequest(context),
+                               TransientCacheListener.<Map<String,Variable>>instance());
+               if(mapPrime != null) {
+                       if(map != null) {
+                               map.putAll(mapPrime);
+                               return map;
+                       }
+                       else
+                               return mapPrime;
+               }
+               return map;
+                       } else if (StructuralComponentClass.DEFINED.equals(clazz)) {
+                               StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                               Resource def = graph.getSingleObject(type, STR.IsDefinedBy);
+                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(def));
                 return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
-            }
-            Map<String, Resource> children = graph.syncRequest(new StructuralChildMapOfResource(represents));
-            return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
+                       } else {
+                               Resource represents = context.getPossibleRepresents(graph);
+                               if(represents == null) return null;
+                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(represents));
+                return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
+                       }
+            
                }
                
        };
@@ -551,15 +618,18 @@ public class Functions {
        
                @Override
                public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
-                   Map<String, Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(context.getRepresents(graph)));
+                       Resource ctx = graph.syncRequest(new StructuralRunContext(context.getRepresents(graph)));
+                       if(ctx == null) return null;
+                   Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(ctx));
                        Resource child = children.get(name);
             return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name);
                }
 
                @Override
                public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
-            StandardGraphChildVariable variable = (StandardGraphChildVariable)context;
-            Map<String,Resource> children = graph.syncRequest(new StructuralRunChildMapOfResource(variable.resource));
+                       Resource ctx = graph.syncRequest(new StructuralRunContext(context.getRepresents(graph)));
+                       if(ctx == null) return map;
+                   Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(ctx));
                    return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
                }
                
@@ -765,38 +835,6 @@ public class Functions {
        
     }
     
-    static class DefinedUCInterfaceMap extends ResourceRead<Collection<InterfaceResolution>> {
-
-       public DefinedUCInterfaceMap(Resource resource) {
-               super(resource);
-       }
-
-       @Override
-       public Collection<InterfaceResolution> perform(ReadGraph graph)
-                       throws DatabaseException {
-
-               StructuralResource2 STR = StructuralResource2.getInstance(graph);
-               Resource definition = graph.getPossibleObject(resource, STR.IsDefinedBy);
-               if(definition != null) {
-                       Collection<InterfaceResolution> result = new ArrayList<InterfaceResolution>();
-                       Layer0 L0 = Layer0.getInstance(graph);
-                       for(Resource cp : graph.syncRequest(new ObjectsWithType(resource, L0.ConsistsOf, STR.ConnectionRelation))) {
-                                       String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);
-                               for(Resource conn : graph.getObjects(cp, STR.IsBoundBy)) {
-                                       Statement stm = graph.getPossibleStatement(conn, STR.Connects);
-                                       if(stm == null) continue;
-                                       Resource component = stm.getObject();
-                                       String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING);
-                                       result.add(new InterfaceResolution(cp, cpName, componentName, graph.getInverse(stm.getPredicate())));
-                               }
-                       }
-                       return result;
-               }
-               return null;
-       }
-
-    }
-    
     public static final Collection<InterfaceResolution> BUILTIN_STRUCTURAL_CPS = new ArrayList<InterfaceResolution>();
 
        @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
index 3b2e42ae77f184f9e77bd141a9eef634eb495a9f..2cfc97296655c1c41d15df484e7cf4c22951320a 100644 (file)
@@ -13,6 +13,7 @@ package org.simantics.structural2.queries;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 
 import org.simantics.db.ReadGraph;
@@ -26,47 +27,45 @@ import org.simantics.db.service.QueryControl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import gnu.trove.map.hash.THashMap;
-
-public class ConnectionPointMapOfResource extends TransientResourceRead<Map<String, Resource>> {
+public class ConnectionPointMapOfResource extends TransientResourceRead<Map<String, PropertyInfo>> {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionPointMapOfResource.class);
 
-       public ConnectionPointMapOfResource(ReadGraph graph, Resource resource) throws DatabaseException {
-           super(graph, resource);
-       }
-       
-       public ConnectionPointMapOfResource(ReadGraph graph, QueryControl qc, Resource resource) throws DatabaseException {
-               super(graph, qc, resource);
-       }
-
-       @Override
-       public Map<String,Resource> perform(ReadGraph graph, Resource resource) throws DatabaseException {
-           
-               Collection<Resource> predicates = graph.getPredicates(resource);
-               
-               THashMap<String,Resource> result = null;
-               
-               for(Resource predicate : predicates) {
-                       
-                       PropertyInfo info = graph.syncRequest(new PossibleConnectionPointInfo(predicate), TransientCacheAsyncListener.<PropertyInfo>instance());
-                       if(info != null) {
-                               if (result == null) result = new THashMap<String,Resource>(predicates.size());
-                               if (result.put(info.name, predicate) != null)
-                                   LOGGER.error("The database contains siblings with the same name " + info.name + " (resource=$" + resource.getResourceId() + ").");
-                       }                               
-                       
-               }
-
-               if(result != null) return result;
-               
-               else return Collections.emptyMap();
-                       
-       }
-       
-       @Override
-       public int getType() {
-               return RequestFlags.INVALIDATE;
-       }
-       
+    public ConnectionPointMapOfResource(ReadGraph graph, Resource resource) throws DatabaseException {
+        super(graph, resource);
+    }
+
+    public ConnectionPointMapOfResource(ReadGraph graph, QueryControl qc, Resource resource) throws DatabaseException {
+        super(graph, qc, resource);
+    }
+
+    @Override
+    public Map<String,PropertyInfo> perform(ReadGraph graph, Resource resource) throws DatabaseException {
+        
+        Collection<Resource> predicates = graph.getPredicates(resource);
+
+        HashMap<String,PropertyInfo> result = null;
+
+        for(Resource predicate : predicates) {
+
+            PropertyInfo info = graph.syncRequest(new PossibleConnectionPointInfo(predicate), TransientCacheAsyncListener.<PropertyInfo>instance());
+            if(info != null) {
+                if (result == null) result = new HashMap<>(predicates.size());
+                if (result.put(info.name, info) != null)
+                LOGGER.error("The database contains siblings with the same name " + info.name + " (resource=$" + resource.getResourceId() + ").");
+            }
+
+        }
+
+        if(result != null) return result;
+
+        else return Collections.emptyMap();
+
+    }
+
+    @Override
+    public int getType() {
+        return RequestFlags.INVALIDATE;
+    }
+
 }
index 9a77d100fca3ded3b6924aee9915d05119f52ecb..584b4acf73f924f4ab57de7de12764fc39548ec3 100644 (file)
@@ -1,3 +1,14 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
 package org.simantics.structural2.utils;
 
 import java.util.ArrayList;
@@ -23,6 +34,7 @@ import org.simantics.db.layer0.util.Layer0Utils;
 import org.simantics.db.layer0.variable.Variable;
 import org.simantics.layer0.Layer0;
 import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.structural2.Functions.StructuralOverrideData;
 import org.simantics.structural2.internal.queries.ConnectedTo;
 import org.simantics.structural2.internal.queries.RelatedConnections;
 import org.simantics.structural2.internal.queries.RelatedConnectionsOfConnectionJoin;
@@ -39,6 +51,25 @@ import gnu.trove.set.hash.THashSet;
  */
 public class StructuralUtils {
     
+    public static enum StructuralComponentClass {
+
+        PRIMITIVE,REPLACEABLE,DEFINED,PROCEDURAL;
+
+        public static StructuralComponentClass get(ReadGraph graph, Resource componentType) throws DatabaseException {
+            StructuralResource2 STR = StructuralResource2.getInstance(graph);
+            Set<Resource> types = graph.getTypes(componentType);
+            if(types.contains(STR.ProceduralComponentType))
+                return StructuralComponentClass.PROCEDURAL;
+            else if(graph.hasStatement(componentType, STR.IsDefinedBy))
+                return StructuralComponentClass.DEFINED;
+            else if(types.contains(STR.ReplaceableDefinedComponentType))
+                return StructuralComponentClass.REPLACEABLE;
+            else
+                return StructuralComponentClass.PRIMITIVE;
+        }
+
+    }
+
     public static Collection<Resource> getConnectionRelations(ReadGraph graph, Resource componentType) throws DatabaseException {
         Layer0 L0 = Layer0.getInstance(graph);
         StructuralResource2 STR = StructuralResource2.getInstance(graph);
@@ -168,6 +199,7 @@ public class StructuralUtils {
      * Returns the component type of the given component or null if the 
      * parameter is not a component.
      */
+    @Deprecated
     public static Resource getComponentType(ReadGraph g, Resource component) throws DatabaseException {
         StructuralResource2 STR = StructuralResource2.getInstance(g);
         return g.getPossibleType(component, STR.Component);
@@ -288,7 +320,21 @@ public class StructuralUtils {
     }
     
     public static List<Variable> structuralConnectionConnectionPoints(ReadGraph graph, Connection conn, Resource relationType) throws DatabaseException {
-       return new ArrayList<Variable>(conn.getConnectionPoints(graph, relationType));
+        return new ArrayList<Variable>(conn.getConnectionPoints(graph, relationType));
+    }
+    
+    public static Resource structuralTypeResource(ReadGraph graph, Variable component, Resource baseType) throws DatabaseException {
+        StructuralOverrideData od = StructuralOverrideData.compute(graph, component);
+        return od.type();
     }
+    
+    public static Resource getComponentType(ReadGraph graph, Variable configuration, Resource component) throws DatabaseException {
+
+        Variable componentVariable = configuration.browse(graph, component);
+        return componentVariable.getType(graph);
+
+    }
+
+
 
 }
index e0b93837ee9765deac16ba1ba2ce4dc1af5e6198..716d4a0017014e3cb727a4d1b26c587f71411680 100644 (file)
@@ -14,50 +14,93 @@ import org.simantics.db.layer0.variable.Variable;
 import org.simantics.layer0.Layer0;
 import org.simantics.modeling.ModelingResources;
 import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.structural2.DefinedUCInterfaceMap;
 import org.simantics.structural2.Functions;
 import org.simantics.structural2.Functions.InterfaceResolution;
+import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass;
 import org.simantics.structural2.variables.ConnectionBrowser.IsLeafType;
 
 /*
- * This connection descriptor variable 
+ * This connection descriptor
+ * 
  * -has not been lifted into interface
  * -has a structural configuration defined as resources
- * -has not been drilled
+ * -might not be drilled
+ * 
+ * Note: these are constructed after climb (before drill) phase of the connection browser. This means that
+ * the component can still contain sub structure during connection browsing. This means that some descriptors
+ * are not final and are replaced by correct descriptors during drill phase.
+ * 
  */
 class ActualConnectionDescriptor extends AbstractVariableConnectionPointDescriptor {
        
-       final private Variable root;
-       final private Resource component;
-       final private Resource cp;
+       /*
+        * This is the nearest known ancestor variable
+        */
+       final Variable root;
+       /*
+        * A component on variable path under the root variable.
+        */
+       final Resource component;
+       /*
+        * TODO
+        */
+       final Resource componentType;
+       /*
+        * The connection point that has type of the component as its domain
+        */
+       final Resource cp;
        
-       public ActualConnectionDescriptor(Variable root, Resource component, Resource cp) {
+       public ActualConnectionDescriptor(Variable root, Resource component, Resource componentType, Resource cp) {
                this.root = root;
                this.component = component;
+               this.componentType = componentType;
                this.cp = cp;
        }
        
-       static class ComputeInterfaceDescription extends UnaryRead<ActualConnectionDescriptor, Collection<InterfaceResolution>> {
+       static class ActualConnectionDescriptorInterfaceDescription extends UnaryRead<ActualConnectionDescriptor, Collection<InterfaceResolution>> {
 
-               public ComputeInterfaceDescription(ActualConnectionDescriptor desc) {
+               public ActualConnectionDescriptorInterfaceDescription(ActualConnectionDescriptor desc) {
                        super(desc);
                }
 
                @Override
                public Collection<InterfaceResolution> perform(ReadGraph graph) throws DatabaseException {
                        
-               StructuralResource2 STR = StructuralResource2.getInstance(graph);
-               Resource type = graph.getPossibleType(parameter.component, STR.Component);
-               if(graph.syncRequest(new IsLeafType(type))) return null;
-
-                       return Functions.computeInterfacePaths(graph, parameter.getVariable(graph).getParent(graph));
+//                     ConnectionBrowser.reportDescriptor(graph, parameter);
+               
+               /*
+                * The componentType is the possibly replaced (STR.ReplaceableDefinedComponentType) type
+                */
+               StructuralComponentClass clazz = StructuralComponentClass.get(graph, parameter.componentType);
+               if(StructuralComponentClass.PRIMITIVE.equals(clazz)) {
+                       return null;
+               } else if(StructuralComponentClass.DEFINED.equals(clazz)) {
+                       final Collection<InterfaceResolution> interfaces = graph.syncRequest(new DefinedUCInterfaceMap(parameter.componentType));
+                       if(interfaces != null) return interfaces;
+                       else return Functions.BUILTIN_STRUCTURAL_CPS;
+               } else if(StructuralComponentClass.REPLACEABLE.equals(clazz)) {
+                       throw new DatabaseException("ConnectionBrowser does not support nested replaceable defined structural types.");
+               } else {
+                       return Functions.computeInterfacePaths(graph, parameter.getVariable(graph).getParent(graph));   
+               }
                        
                }
                
        }
        
+       @Override
+       public boolean isLeaf(ReadGraph graph) throws DatabaseException {
+               
+               StructuralResource2 STR = StructuralResource2.getInstance(graph);
+               Resource type = graph.getPossibleType(component, STR.Component);
+               return graph.syncRequest(new IsLeafType(type));
+               
+       }
+       
        @Override
        public Collection<InterfaceResolution> getInterfaceDescription(ReadGraph graph) throws DatabaseException {
-               return graph.syncRequest(new ComputeInterfaceDescription(this), TransientCacheAsyncListener.<Collection<InterfaceResolution>>instance());
+               return graph.syncRequest(new ActualConnectionDescriptorInterfaceDescription(this), TransientCacheAsyncListener.<Collection<InterfaceResolution>>instance());
        }
        
        public Resource getConnectionPointResource(ReadGraph graph) throws DatabaseException {
index ac1dceceb3ddfce6739ece5c01909ebc7c618c7a..7f43f59d171bb0177c855d869026457a256cffa6 100644 (file)
@@ -1,8 +1,5 @@
 package org.simantics.structural2.variables;
 
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -36,9 +33,14 @@ import org.simantics.structural.stubs.StructuralResource2;
 import org.simantics.structural2.Functions;
 import org.simantics.structural2.Functions.InterfaceResolution;
 import org.simantics.structural2.queries.ConnectionSet;
+import org.simantics.structural2.utils.StructuralUtils;
+import org.simantics.structural2.utils.StructuralUtils.StructuralComponentClass;
 import org.simantics.structural2.variables.StandardProceduralChildVariable.FixedConnection;
 import org.simantics.utils.datastructures.Pair;
 
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
 public class ConnectionBrowser {
 
     /**
@@ -79,7 +81,7 @@ public class ConnectionBrowser {
                  Resource relation = graph.getInverse(stat.getPredicate());
                  //System.out.println(NameUtils.getSafeName(graph, component) + "." + NameUtils.getSafeName(graph, relation));
                  Resource boundConnection = graph.getPossibleObject(relation, STR.IsBoundBy);
-                 Resource type = graph.getPossibleObject(component, L0.InstanceOf);
+                 Resource type = StructuralUtils.getComponentType(graph, configuration, component);
                  Resource def = type != null ? graph.getPossibleObject(type, STR.IsDefinedBy) : null;
                  if(boundConnection != null && def != null) {
                      // The connection point is bound in component type
@@ -383,6 +385,21 @@ public class ConnectionBrowser {
         
     }
     
+    public static void reportDescriptor(ReadGraph graph, VariableConnectionPointDescriptor d) throws DatabaseException {
+
+       if(d instanceof ActualConnectionDescriptor) {
+               ActualConnectionDescriptor d2 = (ActualConnectionDescriptor)d; 
+               
+               System.err.println("--ActualConnectionPointDescriptor2");
+               System.err.println("---root: " + d2.root.getURI(graph));
+               System.err.println("---component: " + graph.getPossibleURI(d2.component));
+               System.err.println("---type: " + graph.getPossibleURI(d2.componentType));
+               System.err.println("---cp: " + graph.getPossibleURI(d2.cp));
+               System.err.println("---var: " + d2.getVariable(graph).getURI(graph));
+       }
+       
+    }
+    
     public static class ConnectionVariables extends BinaryRead<Variable, List<Resource>, Collection<VariableConnectionPointDescriptor>> {
 
        private ConnectionVariables(Variable parameter1, List<Resource> parameter2) {
@@ -427,6 +444,7 @@ public class ConnectionBrowser {
                @Override
                public Collection<VariableConnectionPointDescriptor> perform(ReadGraph graph) throws DatabaseException {
                        if(parameter == null) return Collections.emptyList();
+               Layer0 L0 = Layer0.getInstance(graph);
                        StructuralResource2 STR = StructuralResource2.getInstance(graph);
             ArrayList<VariableConnectionPointDescriptor> result = null;
             for(int i=1;i<parameter2.size();i++) {
@@ -435,7 +453,13 @@ public class ConnectionBrowser {
                        Resource component = stm.getObject();
                        Resource connectionPoint = graph.getInverse(stm.getPredicate());
                        if(result == null) result = new ArrayList<VariableConnectionPointDescriptor>();
-                       result.add(new ActualConnectionDescriptor(parameter, component, connectionPoint));
+                       String componentName = graph.getRelatedValue(component, L0.HasName, Bindings.STRING);
+                       Variable possibleChild = parameter.getPossibleChild(graph, componentName);
+                       if(possibleChild != null) {
+                               result.add(new ActualConnectionDescriptor(parameter, component, possibleChild.getType(graph), connectionPoint));
+                       } else {
+                               throw new DatabaseException("No child with name " + componentName + " could be resolved for variable " + parameter.getURI(graph));
+                       }
                }
             }
             if(result == null) return Collections.emptyList();
@@ -453,12 +477,8 @@ public class ConnectionBrowser {
                @Override
                public Boolean perform(ReadGraph graph) throws DatabaseException {
                        
-                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
-
-                       if(graph.isInstanceOf(resource, STR.ProceduralComponentType)) return false;
-                       if(graph.hasStatement(resource, STR.IsDefinedBy)) return false;
-                       
-                       return true;
+                       StructuralComponentClass clazz = StructuralComponentClass.get(graph, resource);
+                       return StructuralComponentClass.PRIMITIVE.equals(clazz);
 
                }
        
@@ -591,28 +611,42 @@ public class ConnectionBrowser {
 
        public static Collection<VariableConnectionPointDescriptor> doFlatten(ReadGraph graph, Variable child, Resource cp, Resource relationType) throws DatabaseException {
        
-        Collection<VariableConnectionPointDescriptor> climbed = climb(graph, child, cp, null);
-        boolean needDrill = false;
+        Set<VariableConnectionPointDescriptor> result = null;
+        Set<VariableConnectionPointDescriptor> needDrill = null;
+        
+               Collection<VariableConnectionPointDescriptor> climbed = climb(graph, child, cp, null);
         for(VariableConnectionPointDescriptor desc : climbed) {
                if(!desc.isLeaf(graph)) {
-                       needDrill = true;
-                       break;
+                       if(needDrill == null)
+                               needDrill = new THashSet<VariableConnectionPointDescriptor>(climbed.size());
+                       needDrill.add(desc);
+               } else {
+                       if(result == null)
+                               result = new THashSet<VariableConnectionPointDescriptor>(climbed.size());
+                       result.add(desc);
                }
         }
         
-        if(!needDrill) {
+        if(needDrill == null) {
+               /*
+                * All descriptors were already flat - just take case of filtering
+                */
             if(relationType != null) {
                 ArrayList<VariableConnectionPointDescriptor> filtered = new ArrayList<VariableConnectionPointDescriptor>(climbed.size());
                 for(VariableConnectionPointDescriptor desc : climbed)
                     if(filterByRelationType(graph, desc, relationType))
                         filtered.add(desc);
                 return filtered;
+            } else {
+                return climbed;
             }
-            return climbed;
         }
         
-        THashSet<VariableConnectionPointDescriptor> result = new THashSet<VariableConnectionPointDescriptor>(climbed.size());
-        for(VariableConnectionPointDescriptor top : climbed) {
+
+        /*
+         * There were some descriptors that require drill
+         */
+        for(VariableConnectionPointDescriptor top : needDrill) {
                Collection<VariableConnectionPointDescriptor> drilled = drill(graph, top);
             if(drilled != null) {
                for(VariableConnectionPointDescriptor drill : drilled) {
@@ -620,6 +654,8 @@ public class ConnectionBrowser {
                                if(!filterByRelationType(graph, drill, relationType))
                                        continue;
                        }
+                       if(result == null)
+                               result = new THashSet<VariableConnectionPointDescriptor>(climbed.size());
                        result.add(drill);
                }
             }
diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowserConnectionPointDescriptor.java
new file mode 100644 (file)
index 0000000..08a0a02
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.structural2.variables;
+
+import java.util.Collection;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.structural2.Functions.InterfaceResolution;
+
+/*
+ *  @author Antti Villberg
+ *  @since 1.36
+ */
+public interface ConnectionBrowserConnectionPointDescriptor {
+
+    public boolean isLeaf(ReadGraph graph) throws DatabaseException;
+    public Collection<InterfaceResolution> getInterfaceDescription(ReadGraph graph) throws DatabaseException;
+
+}
index 403280aea6eb0279841d21bbd0d12a4914f99c9d..c4a3fee48f448214f48415539b756ade1b07f272 100644 (file)
@@ -1,21 +1,16 @@
 package org.simantics.structural2.variables;
 
-import java.util.Collection;
-
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.variable.Variable;
-import org.simantics.structural2.Functions.InterfaceResolution;
 
-public interface VariableConnectionPointDescriptor {
+public interface VariableConnectionPointDescriptor extends ConnectionBrowserConnectionPointDescriptor {
        
        public boolean isFlattenedFrom(ReadGraph graph, Variable possiblyStructuralCp) throws DatabaseException;
        public Variable getVariable(ReadGraph graph) throws DatabaseException;
        public Resource getConnectionPointResource(ReadGraph graph) throws DatabaseException;
        public String getURI(ReadGraph graph) throws DatabaseException;
-       public Collection<InterfaceResolution> getInterfaceDescription(ReadGraph graph) throws DatabaseException;
-       public boolean isLeaf(ReadGraph graph) throws DatabaseException;
        public boolean hasClassification(ReadGraph graph, String classification) throws DatabaseException;
        public String getRelativeRVI(ReadGraph graph, Variable base) throws DatabaseException;