]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java
Document performance optimizations
[simantics/platform.git] / bundles / org.simantics.document.server / src / org / simantics / document / server / Functions.java
index 6ccffbe973ddecdeef07e4a8bcbdaebe3acf52e2..4915fc002ecdbc91b0a54806f796daa8f730b85e 100644 (file)
@@ -15,7 +15,6 @@ import org.simantics.databoard.Bindings;
 import org.simantics.databoard.Datatypes;
 import org.simantics.databoard.binding.Binding;
 import org.simantics.databoard.type.Datatype;
-import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.DirectStatements;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.RequestProcessor;
@@ -24,8 +23,10 @@ import org.simantics.db.Session;
 import org.simantics.db.Statement;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.primitiverequest.Adapter;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
-import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.BinaryRead;
+import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.common.request.UniqueRead;
 import org.simantics.db.common.request.WriteResultRequest;
 import org.simantics.db.common.utils.Logger;
@@ -38,18 +39,18 @@ import org.simantics.db.layer0.request.PropertyInfoRequest;
 import org.simantics.db.layer0.request.VariableProperty;
 import org.simantics.db.layer0.request.VariableRead;
 import org.simantics.db.layer0.request.VariableValueWithBinding;
+import org.simantics.db.layer0.scl.SCLDatabaseException;
 import org.simantics.db.layer0.variable.ConstantPropertyVariable;
 import org.simantics.db.layer0.variable.ProxyChildVariable;
 import org.simantics.db.layer0.variable.ProxySessionRequest;
+import org.simantics.db.layer0.variable.ProxyVariableSupport;
 import org.simantics.db.layer0.variable.ProxyVariables;
 import org.simantics.db.layer0.variable.StandardAssertedGraphPropertyVariable;
-import org.simantics.db.layer0.variable.StandardGraphChildVariable;
 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
 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.Variables;
-import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.service.DirectQuerySupport;
 import org.simantics.document.base.ontology.DocumentationResource;
 import org.simantics.document.server.bean.Command;
@@ -62,17 +63,20 @@ import org.simantics.document.server.io.CommandContextImpl;
 import org.simantics.document.server.io.CommandContextMutable;
 import org.simantics.document.server.io.CommandResult;
 import org.simantics.document.server.io.IConsole;
+import org.simantics.document.server.request.NodeRequest;
 import org.simantics.document.server.request.ServerSCLHandlerValueRequest;
 import org.simantics.document.server.request.ServerSCLValueRequest;
 import org.simantics.document.server.serverResponse.ServerResponse;
 import org.simantics.document.server.serverResponse.SuccessResponse;
+import org.simantics.document.server.state.StateNodeManager;
+import org.simantics.document.server.state.StateRealm;
+import org.simantics.document.server.state.StateSessionManager;
 import org.simantics.modeling.ModelingResources;
-import org.simantics.modeling.scl.SCLRealm;
-import org.simantics.modeling.scl.SCLSessionManager;
 import org.simantics.modeling.services.CaseInsensitiveComponentFunctionNamingStrategy;
 import org.simantics.modeling.services.ComponentNamingStrategy;
 import org.simantics.operation.Layer0X;
 import org.simantics.project.IProject;
+import org.simantics.scl.compiler.module.repository.ImportFailureException;
 import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.Type;
 import org.simantics.scl.compiler.types.Types;
@@ -95,29 +99,45 @@ import org.simantics.simulation.project.IExperimentManager;
 import org.simantics.structural2.variables.Connection;
 import org.simantics.structural2.variables.StandardProceduralChildVariable;
 import org.simantics.structural2.variables.VariableConnectionPointDescriptor;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.map.hash.THashMap;
 
 public class Functions {
 
-    private static class PrimitivePropertyStatementsProcedure implements AsyncProcedure<DirectStatements> {
-
-        public DirectStatements result;
-
-        @Override
-        public void execute(AsyncReadGraph graph, DirectStatements result) {
-            this.result = result;
-        }
-
-        @Override
-        public void exception(AsyncReadGraph graph, Throwable throwable) {
-        }
-
-    }
-
+    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(Functions.class);
+    
     @SCLValue(type = "VariableMap")
     public static VariableMap primitiveProperties = new VariableMapImpl() {
+       private void storePropertyValueAndExceptions(ReadGraph graph, Variable parent, String name, Variable property, Map<String, Variable> map) {
+               try {
+                       Object value = property.getValue(graph);
+                               map.put(name, new ConstantPropertyVariable(parent, name, value, null));
+               } catch (DatabaseException e) {
+                       Variable propertyExceptions = map.get(NodeRequest.PROPERTY_VALUE_EXCEPTIONS);
+                       Map<String, Exception> exceptionMap;
+                       if (propertyExceptions == null) {
+                               exceptionMap = new TreeMap<String, Exception>();
+                               propertyExceptions = new ConstantPropertyVariable(parent, NodeRequest.PROPERTY_VALUE_EXCEPTIONS, exceptionMap, null);
+                               map.put(NodeRequest.PROPERTY_VALUE_EXCEPTIONS, propertyExceptions);
+                       } else {
+                               try {
+                                               exceptionMap = propertyExceptions.getValue(graph);
+                                       } catch (DatabaseException e1) {
+                                               Logger.defaultLogError(e1);
+                                               return;
+                                       }
+                       }
+                       String label = name;
+                       try {
+                               label = property.getLabel(graph);
+                       } catch (DatabaseException e2) {
 
+                       }
+                       exceptionMap.put(label, e);
+               }
+       }
+       
         @Override
         public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
             return All.getStandardPropertyDomainPropertyVariableFromValue(graph, context, name);
@@ -126,6 +146,8 @@ public class Functions {
         @Override
         public Map<String, Variable> getVariables(final ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
 
+            if(map == null) map = new HashMap<String,Variable>();
+
             Variable parent = context.getParent(graph);
 
             DocumentationResource DOC = DocumentationResource.getInstance(graph);
@@ -136,9 +158,8 @@ public class Functions {
                 for(Variable property : procedural.getProperties(graph/*, DocumentationResource.URIs.Document_AttributeRelation*/)) {
                     if(property instanceof StandardAssertedGraphPropertyVariable) {
                         StandardAssertedGraphPropertyVariable ass = (StandardAssertedGraphPropertyVariable)property;
-                        if("datadefinitions".equals(ass.property.name) || "commands".equals(ass.property.name)  || "pollingFunction".equals(ass.property.name)) {
-                            Object value = property.getPossibleValue(graph);
-                            if(value != null) map.put(ass.property.name, new ConstantPropertyVariable(parent, ass.property.name, value, null));
+                        if("dataDefinitions".equals(ass.property.name) || "commands".equals(ass.property.name)  || "pollingFunction".equals(ass.property.name)) {
+                               storePropertyValueAndExceptions(graph, parent, ass.property.name, property, map);
                         }
                         continue;
                     }
@@ -146,62 +167,144 @@ public class Functions {
                     if(predicate != null) {
                         PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate));
                         if(info.hasClassification(DocumentationResource.URIs.Document_AttributeRelation)) {
-                            Variable prop = parent.getProperty(graph, predicate);
-                            Object value = prop.getValue(graph);
-                            if(map == null) map = new HashMap<String,Variable>();
-                            map.put(info.name, new ConstantPropertyVariable(parent, info.name, value, null));
+                               Variable prop = parent.getProperty(graph, predicate);
+                            storePropertyValueAndExceptions(graph, parent, info.name, prop, map);
                         }
                     }
                 }
 
             } else {
 
+                Resource parentRes = parent.getRepresents(graph);
+                {
+                       Variable prop = new StandardGraphPropertyVariable(graph, parent, DOC.Properties_commands);
+                       storePropertyValueAndExceptions(graph, parent, "commands", prop, map);
+                }
+
+                if (graph.getPossibleObject(parentRes, DOC.Properties_dataDefinitions) != null) {
+                       Variable prop = new StandardGraphPropertyVariable(graph, parent, DOC.Properties_dataDefinitions);
+                       storePropertyValueAndExceptions(graph, parent, "dataDefinitions", prop, map);
+                }
+                
                 DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
-                PrimitivePropertyStatementsProcedure foo = new PrimitivePropertyStatementsProcedure();
+                //PrimitivePropertyStatementsProcedure foo = new PrimitivePropertyStatementsProcedure();
 
-                dqs.forEachDirectPersistentStatement(graph, parent.getRepresents(graph), foo);
+                DirectStatements ds = dqs.getDirectPersistentStatements(graph, parentRes);
 
-                for(Statement stm : foo.result) {
+                for(Statement stm : ds) {
                     Resource predicate = stm.getPredicate();
                     PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate));
 
                     if(info.isHasProperty && info.hasClassification(DocumentationResource.URIs.Document_AttributeRelation)) {
-                        if(map == null) map = new HashMap<String,Variable>();
-                        Variable prop = new StandardGraphPropertyVariable(graph, parent, predicate);
-                        Object value = prop.getValue(graph);
-                        map.put(info.name, new ConstantPropertyVariable(parent, info.name, value, null));
+                       Variable prop = new StandardGraphPropertyVariable(graph, parent, predicate);
+                       storePropertyValueAndExceptions(graph, parent, info.name, prop, map);
                     } else {
                         Resource definition = graph.getPossibleObject(predicate, DOC.Document_definesAttributeRelation);
                         if(definition != null) {
-                            if(map == null) map = new HashMap<String,Variable>();
-                            try {
-                                PropertyInfo info2 = graph.syncRequest(new PropertyInfoRequest(definition));
-                                Variable prop = new StandardGraphPropertyVariable(graph, parent, definition);
-                                map.put(info2.name, new PrimitiveValueVariable(parent, info2.name, prop));
-                            } catch (DatabaseException e) {
-                                Logger.defaultLogError(e);
-                            }
+                               PropertyInfo info2 = graph.syncRequest(new PropertyInfoRequest(definition));
+                               Variable prop = new StandardGraphPropertyVariable(graph, parent, definition);
+                            map.put(info2.name, new PrimitiveValueVariable(parent, info2.name, prop));
                         }
                     }
                 }
+            }
+            return map;
+
+        }
+
+    };
 
-                Variable prop = new StandardGraphPropertyVariable(graph, parent, DOC.Properties_dataDefinitions);
-                Object value = prop.getPossibleValue(graph);
-                if(value != null) map.put("dataDefinitions", new ConstantPropertyVariable(parent, "dataDefinitions", value, null));
-                prop = new StandardGraphPropertyVariable(graph, parent, DOC.Properties_commands);
-                value = prop.getPossibleValue(graph);
-                if(value != null) map.put("commands", new ConstantPropertyVariable(parent, "commands", value, null));
+    static class DocumentPropertyKeys extends ResourceRead<List<String>> {
 
+        protected DocumentPropertyKeys(Resource resource) {
+            super(resource);
+        }
+
+        @Override
+        public List<String> perform(ReadGraph graph) throws DatabaseException {
+
+            List<String> result = new ArrayList<>();
+
+            DocumentationResource DOC = DocumentationResource.getInstance(graph);
+
+            if(graph.hasStatement(resource, DOC.Properties_commands))
+                result.add("commands");
+            if(graph.hasStatement(resource, DOC.Properties_dataDefinitions))
+                result.add("dataDefinitions");
+
+            DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
+            DirectStatements ds = dqs.getDirectPersistentStatements(graph, resource);
+
+            for(Statement stm : ds) {
+
+                Resource predicate = stm.getPredicate();
+                PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate));
+
+                if(info.isHasProperty && info.hasClassification(DocumentationResource.URIs.Document_AttributeRelation)) {
+                    result.add(info.name);
+                } else {
+                    Resource definition = graph.getPossibleObject(predicate, DOC.Document_definesAttributeRelation);
+                    if(definition != null) {
+                        PropertyInfo info2 = graph.syncRequest(new PropertyInfoRequest(definition));
+                        result.add(info2.name);
+                    }
+                }
             }
 
-            if(map == null) return Collections.emptyMap();
+            return result;
 
-            return map;
+        }
+
+    }
+
+    static class StandardDocumentProperties implements DocumentProperties {
+
+        @Override
+        public Collection<String> getKeys(ReadGraph graph, Variable parent) throws DatabaseException {
+
+            if(parent instanceof StandardProceduralChildVariable) {
+
+                StandardProceduralChildVariable procedural = (StandardProceduralChildVariable)parent;
+                List<String> result = new ArrayList<>();
+                for(Variable property : procedural.getProperties(graph)) {
+                    if(property instanceof StandardAssertedGraphPropertyVariable) {
+                        StandardAssertedGraphPropertyVariable ass = (StandardAssertedGraphPropertyVariable)property;
+                        if("dataDefinitions".equals(ass.property.name) || "commands".equals(ass.property.name)  || "pollingFunction".equals(ass.property.name)) {
+                            result.add(ass.property.name);
+                        }
+                        continue;
+                    }
+                    Resource predicate = property.getPossiblePredicateResource(graph);
+                    if(predicate != null) {
+                        PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(predicate));
+                        if(info.hasClassification(DocumentationResource.URIs.Document_AttributeRelation)) {
+                            result.add(info.name);
+                        }
+                    }
+                }
+
+                return result;
+
+            } else {
+
+                Resource parentRes = parent.getRepresents(graph);
+                return graph.syncRequest(new DocumentPropertyKeys(parentRes), TransientCacheAsyncListener.instance());
+
+            }
 
         }
 
-    };
+        @Override
+        public Object getValue(ReadGraph graph, Variable context, String key) throws DatabaseException {
+            return context.getPropertyValue(graph, key);
+        }
 
+    }
+    
+    public static DocumentProperties primitiveProperties() throws DatabaseException {
+        return new StandardDocumentProperties();
+    }
+    
     @SCLValue(type = "VariableMap")
     public static VariableMap inputSpaceChildren = new VariableMapImpl() {
 
@@ -230,7 +333,7 @@ public class Functions {
 
     };
 
-    static class DocumentProxyChildVariable extends ProxyChildVariable {
+    static class DocumentProxyChildVariable extends ProxyChildVariable implements ProxyVariableSupport {
 
         public DocumentProxyChildVariable(Variable base, Variable parent, Variable other, String name) {
             super(base, parent, other, name);
@@ -247,42 +350,26 @@ public class Functions {
                if(other instanceof ProxyChildVariable) {
                        // The context is also a proxy - let it do the job
                     return super.getPossibleChild(graph, name);
-               } else {
-                       return new RootVariable(this, base.getRepresents(graph));
-               }
-               }
-
-            return super.getPossibleChild(graph, name);
-
-        }
-
-        public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
-
-            Collection<Variable> result = super.getChildren(graph);
-            if(!(base instanceof ProxyChildVariable)) {
-               result.add(new RootVariable(this, base.getRepresents(graph)));
+                } else {
+                    return ProxyVariables.tryToOwnRenamed(graph, this, base, CONTEXT_END);
+                }
             }
-            return result;
 
-        }
-
-    }
-
-    static class RootVariable extends StandardGraphChildVariable {
+            return super.getPossibleChild(graph, name);
 
-        public RootVariable(DocumentProxyChildVariable parent, Resource resource) {
-            super(parent, null, resource);
         }
 
         @Override
-        public String getName(ReadGraph graph) throws DatabaseException {
-            return ProxyChildVariable.CONTEXT_END;
+        public Variable attachTo(ReadGraph graph, Variable parent) {
+            return attachToRenamed(graph, parent, name);
         }
-
-        @SuppressWarnings("deprecation")
+        
         @Override
-        public Variable getNameVariable(ReadGraph graph) throws DatabaseException {
-            return new ConstantPropertyVariable(this, Variables.NAME, ProxyChildVariable.CONTEXT_END, Bindings.STRING);
+        public Variable attachToRenamed(ReadGraph graph, Variable parent, String name) {
+            if(this.parent.equals(base))
+                return new DocumentProxyChildVariable(parent, parent, other, name);
+            else
+                return new DocumentProxyChildVariable(base, parent, other, name);
         }
 
     }
@@ -557,6 +644,7 @@ public class Functions {
        }
     }
 
+    @Deprecated
     public static AbstractEventHandler emptyOnClick(ReadGraph graph) throws DatabaseException {
         return new EventHandler() {
             @Override
@@ -566,6 +654,7 @@ public class Functions {
         };
     }
 
+    @Deprecated
     public static AbstractEventHandler writeEventHandler(ReadGraph graph, final Variable variable, final Function fn) {
 
        final Session session = graph.getSession();
@@ -598,15 +687,11 @@ public class Functions {
                                                        return (String)response;
                                                    }
                                                    return null;
-                                               } catch (Throwable t) {
-                                                   t.printStackTrace();
                                                } finally {
                                                        sclContext.put("graph", oldGraph);
                                                        sclContext.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter);
                                                }
 
-                                               return null;
-
                                            }
 
                                        });
@@ -623,6 +708,7 @@ public class Functions {
         };
     }
 
+    @Deprecated
     public static AbstractEventHandler readEventHandler(ReadGraph graph, final Variable variable, final Function fn) {
 
        final Session session = graph.getSession();
@@ -655,15 +741,11 @@ public class Functions {
                                                        return (String)response;
                                                    }
                                                    return null;
-                                               } catch (Throwable t) {
-                                                   t.printStackTrace();
                                                } finally {
                                                        sclContext.put("graph", oldGraph);
                                                        sclContext.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter);
                                                }
 
-                                               return null;
-
                                            }
 
                                        });
@@ -680,6 +762,7 @@ public class Functions {
         };
     }
 
+    @Deprecated
     public static AbstractEventHandler readEventHandler2(ReadGraph graph, final Function fn) {
 
        final Session session = graph.getSession();
@@ -706,15 +789,11 @@ public class Functions {
                                                        return (CommandResult)response;
                                                    }
                                                    return null;
-                                               } catch (Throwable t) {
-                                                   t.printStackTrace();
                                                } finally {
                                                        sclContext.put("graph", oldGraph);
                                                        sclContext.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter);
                                                }
 
-                                               return null;
-
                                            }
 
                                        });
@@ -738,12 +817,12 @@ public class Functions {
 
         final List<TCon> effects = ServerSCLHandlerValueRequest.getEffects(graph, anyFunction);
 
-       final Function1<CommandContext, CommandResult> fn = anyFunction.getValue(graph);
-        String expression = anyFunction.getPropertyValue(graph, "expression");
+       Function1<CommandContext, CommandResult> fn = anyFunction.getValue(graph);
+        //String expression = anyFunction.getPropertyValue(graph, "expression");
 
        final Session session = graph.getSession();
 
-        return new AbstractResponseHandler(expression) {
+        return new AbstractResponseHandler(fn) {
 
                private String formatError(RequestProcessor proc, Throwable t) {
 
@@ -804,10 +883,7 @@ public class Functions {
                                                Object oldGraph = sclContext.put("graph", graph);
                                                Object oldPrinter = sclContext.put(SCLReportingHandler.REPORTING_HANDLER, printer);
                                                try {
-                                                       Object response = fn.apply(parameters);
-                                                       return response;
-                                               } catch (Throwable t) {
-                                                       return new org.simantics.document.server.serverResponse.Error(formatError(graph, t));
+                                                       return fn.apply(parameters);
                                                } finally {
                                                        sclContext.put("graph", oldGraph);
                                                        sclContext.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter);
@@ -828,10 +904,7 @@ public class Functions {
                                                Object oldPrinter = sclContext.put(SCLReportingHandler.REPORTING_HANDLER, printer);
 
                                                try {
-                                                       Object response = fn.apply(parameters);
-                                                       return response;
-                                               } catch (Throwable t) {
-                                                       return new org.simantics.document.server.serverResponse.Error(formatError(graph, t));
+                                                       return fn.apply(parameters);
                                                } finally {
                                                        sclContext.put("graph", oldGraph);
                                                        sclContext.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter);
@@ -873,6 +946,7 @@ public class Functions {
         };
     }
 
+    @Deprecated
     public static AbstractEventHandler writeEventHandler2(ReadGraph graph, final Function fn) {
 
        final Session session = graph.getSession();
@@ -899,15 +973,11 @@ public class Functions {
                                                        return (CommandResult)response;
                                                    }
                                                    return null;
-                                               } catch (Throwable t) {
-                                                   t.printStackTrace();
                                                } finally {
                                                        sclContext.put("graph", oldGraph);
                                                        sclContext.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter);
                                                }
 
-                                               return null;
-
                                            }
 
                                        });
@@ -924,6 +994,8 @@ public class Functions {
         };
     }
 
+
+    @Deprecated
     public static AbstractEventHandler eventHandler2(ReadGraph graph, final Function fn) {
 
         return new AbstractEventHandler() {
@@ -943,14 +1015,10 @@ public class Functions {
                                        return (CommandResult)response;
                                }
                                return null;
-                       } catch (Throwable t) {
-                               t.printStackTrace();
                        } finally {
                                sclContext.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter);
                        }
 
-                       return null;
-
                                } catch (Throwable e) {
                                        Logger.defaultLogError(e);
                                        return new org.simantics.document.server.serverResponse.Error(e.getMessage()); 
@@ -961,6 +1029,7 @@ public class Functions {
         };
     }
 
+    @Deprecated
     public static AbstractEventHandler eventHandler(ReadGraph graph, final Function fn) {
 
         return new AbstractEventHandler() {
@@ -987,8 +1056,6 @@ public class Functions {
                                    if(response instanceof String) {
                                        result = (String)response;
                                    }
-                               } catch (Throwable t) {
-                                   t.printStackTrace();
                                } finally {
                                        sclContext.put(SCLReportingHandler.REPORTING_HANDLER, oldPrinter);
                                }
@@ -1141,11 +1208,6 @@ public class Functions {
 
        } else {
 
-               String id = sclStateKey(graph, base, self, ref);
-
-               SCLRealm realm = SCLSessionManager.getOrCreateSCLRealm(base.getURI(graph) + "/__scl__");
-               realm.getConnection().setVariable(id, getSCLType(defaultValue), defaultValue);
-
                return defaultValue;
 
        }
@@ -1155,9 +1217,9 @@ public class Functions {
 
        String id = sclStateKey(graph, base, self, ref);
 
-       SCLRealm realm = SCLSessionManager.getOrCreateSCLRealm(base.getURI(graph)+"/__scl__");
-       realm.getConnection().setVariable(id, getSCLType(value), value);
-       realm.refreshVariablesSync();
+               StateRealm realm = (StateRealm) StateSessionManager.getInstance().getOrCreateRealm(graph, base.getURI(graph)+"/__scl__");
+               StateNodeManager nodeManager = (StateNodeManager) realm.getNodeManager();
+               nodeManager.setState(id, value);
 
     }
 
@@ -1250,11 +1312,11 @@ public class Functions {
                                                return true;
                                        }
                                } else {
-                                       Variable parentCp = graph.sync(new UnaryRead<Connection, Variable>(conn) {
+                                       Variable parentCp = graph.sync(new BinaryRead<Variable, Connection, Variable>(widget, conn) {
                                    @Override
                                    public Variable perform(ReadGraph graph) throws DatabaseException {
                                        DocumentationResource DOC = DocumentationResource.getInstance(graph);
-                                       Collection<VariableConnectionPointDescriptor> descs = parameter.getConnectionPointDescriptors(graph, null);
+                                       Collection<VariableConnectionPointDescriptor> descs = parameter2.getConnection2().getConnectionPointDescriptors(graph, parameter, null);
 
                                                for(VariableConnectionPointDescriptor desc : descs) {
                                                        if (DOC.Relations_partN.equals(desc.getConnectionPointResource(graph))) {
@@ -1284,4 +1346,27 @@ public class Functions {
        return graph.syncRequest(new PathExistsRequest(context));
     }
 
+    public static String compileDocumentSCLValueExpression(ReadGraph graph, Variable context) {
+        try {
+            ServerSCLValueRequest.validate(graph, context);
+            return "";
+        } catch (Exception e) {
+            return resolveIssueMessage(e);
+        }
+    }
+    
+    private static String resolveIssueMessage(Exception e) {
+        if (e instanceof ImportFailureException)
+            return "";
+        if (e.getCause() != null && e.getCause() instanceof ImportFailureException)
+            return "";
+        if (e instanceof SCLDatabaseException) {
+            SCLDatabaseException ee = (SCLDatabaseException) e;
+            return ee.getMessage();
+        }
+        if (LOGGER.isDebugEnabled())
+            LOGGER.debug("", e);
+        return e.getMessage();
+    }
+
 }
\ No newline at end of file