]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java
Replaceable Defined Component Types
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / variable / AbstractVariable.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.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.
 
 /**
  * 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);
     }
 
                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();
     }
     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);
         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);
             return null;
         }
         return graph.getPossibleObject(resource, Layer0.getInstance(graph).InstanceOf);
-       }
+    }
 
     public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException {
 
     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);
         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);
     }
 
             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) {
         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);
             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);
 
     public Map<String, Variable> collectDomainProperties(ReadGraph graph, String classification, Map<String, Variable> map) throws DatabaseException {
        Map<String,Variable> all = collectDomainProperties(graph, null);