From: jsimomaa Date: Fri, 1 Feb 2019 07:39:08 +0000 (+0200) Subject: Initial version of validating derived properties formulas X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=7331142ca75736ec52fc2ef8487a49915e61e70d;p=simantics%2Fplatform.git Initial version of validating derived properties formulas Note: untested the procedural use case and still the solution can be a bit hackish with e.g. constructing Variables and passing them along However, at least this does something instead of just silently failing gitlab #252 Conflicts: bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/client/Synchronizer.java Change-Id: I209d9d585379b7b987861355589427ee90375738 --- diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java index 582277c90..d0ab88907 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java @@ -24,6 +24,7 @@ import org.simantics.db.layer0.exception.VariableException; import org.simantics.db.layer0.function.All; import org.simantics.db.layer0.request.PropertyInfo; import org.simantics.db.layer0.request.PropertyInfoRequest; +import org.simantics.db.layer0.scl.SCLDatabaseException; import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.layer0.Layer0; import org.simantics.utils.Development; @@ -147,9 +148,11 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { try { - return (T)getValueAccessor(graph).getValue(graph, this, binding); - } catch (PendingVariableException e) { - throw e; + return (T) getValueAccessor(graph).getValue(graph, this, binding); + } catch (SCLDatabaseException e) { // these can be thrown when compiling e.g. derived properties + throw e; + } catch (MissingVariableValueException | PendingVariableException e) { + throw e; } catch (Throwable t) { throw new MissingVariableValueException(t); } diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java index b64380b28..bc7345ab1 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java @@ -3,6 +3,8 @@ package org.simantics.modeling.ui.componentTypeEditor; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,6 +47,7 @@ import org.simantics.layer0.Layer0; import org.simantics.modeling.userComponent.ComponentTypeCommands; import org.simantics.scl.runtime.function.Function2; import org.simantics.scl.runtime.function.Function4; +import org.simantics.utils.threads.ThreadUtils; import org.simantics.utils.ui.ErrorLogger; public class ComponentTypeViewerData { @@ -371,18 +374,32 @@ public class ComponentTypeViewerData { if (validator != null) { org.eclipse.swt.widgets.Listener validationListener = new org.eclipse.swt.widgets.Listener() { + + private ScheduledFuture future; + @Override public void handleEvent(Event e) { final String newValue = text.getText(); - String error = validator.apply(Simantics.getSession(), componentType, propertyInfo.resource, newValue); - if (error != null) { - text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED)); - text.setToolTipText(error); - return; - } else { - text.setBackground(null); - text.setToolTipText(null); - } + if (future != null && !future.isCancelled()) + future.cancel(true); + future = ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> { + String error = validator.apply(Simantics.getSession(), componentType, propertyInfo.resource, newValue); + if (!text.isDisposed()) { + text.getDisplay().asyncExec(() -> { + if (!text.isDisposed()) { + if (error != null) { + text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED)); + text.setToolTipText(error); + return; + } else { + text.setBackground(null); + text.setToolTipText(null); + } + } + + }); + } + }, 500, TimeUnit.MILLISECONDS); } }; text.addListener(SWT.Modify, validationListener); diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/DerivedPropertiesSection.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/DerivedPropertiesSection.java index 19d9e6f29..0d6ae80d8 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/DerivedPropertiesSection.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/DerivedPropertiesSection.java @@ -32,14 +32,25 @@ import org.simantics.db.ReadGraph; import org.simantics.db.RequestProcessor; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; -import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.request.UniqueRead; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PropertyInfo; +import org.simantics.db.layer0.request.PropertyInfoRequest; +import org.simantics.db.layer0.variable.StandardGraphChildVariable; +import org.simantics.db.layer0.variable.StandardGraphPropertyVariable; +import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; +import org.simantics.modeling.scl.CompileProceduralSCLMonitorRequest; +import org.simantics.modeling.scl.CompileSCLMonitorRequest; import org.simantics.modeling.userComponent.ComponentTypeCommands; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function1; import org.simantics.scl.runtime.function.Function4; import org.simantics.structural.stubs.StructuralResource2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DerivedPropertiesSection implements ComponentTypeViewerSection { private static final String[] COLUMN_NAMES = @@ -56,6 +67,8 @@ public class DerivedPropertiesSection implements ComponentTypeViewerSection { } }; + private static final Logger LOGGER = LoggerFactory.getLogger(DerivedPropertiesSection.class); + ComponentTypeViewerData data; Table table; TableColumn[] columns; @@ -261,23 +274,33 @@ public class DerivedPropertiesSection implements ComponentTypeViewerSection { StructuralResource2 STR = StructuralResource2.getInstance(graph); - Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(componentType)); - + // TODO: this is a bit hackish but should get the job done in most parts and + // importantly indicates something for the user + PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(relation), TransientCacheAsyncListener.instance()); + Variable parent = new StandardGraphChildVariable(null, null, componentType) { + + public Resource getType(ReadGraph graph) throws DatabaseException { + return componentType; + }; + + public Variable getPossibleProperty(ReadGraph graph, String name) throws DatabaseException { + Variable prop = super.getPossibleProperty(graph, name); + if (prop != null) { + return prop; + } else { + return getChild(graph, name); + } + }; + }; + for(Resource literal : graph.getAssertedObjects(componentType, relation)) { try { - // TODO validation + Variable context = new StandardGraphPropertyVariable(parent, null, null, info, literal); if(graph.isInstanceOf(componentType, STR.ProceduralComponentType)) { - //Layer0 L0 = Layer0.getInstance(graph); - //Resource environment = graph.getPossibleObject(literal, L0.SCLValue_environment); - //ContextModule context = graph.sync(new TypeMonitorContextRequest(componentType)); - //String SCLMain = graph.syncRequest(new SCLMainModuleRequest(indexRoot)); - //CompilationContext cc = new CompilationContext(environment, context, SCLMain); - //graph.syncRequest(new ActualCompileRequest(expression, cc), TransientCacheListener.instance()); + CompileProceduralSCLMonitorRequest.compileAndEvaluate(graph, context); } else { - //CompilationContext cc = new CompileSCLMonitorRequest(literal, componentType, indexRoot).getContext(graph); - //graph.syncRequest(new ActualCompileRequest(expression, cc), TransientCacheListener.instance()); - //graph.syncRequest(new CompileSCLMonitorRequest(graph, context)); + compileAndEvaluate(graph, context, expression); } } catch (Exception e) { @@ -286,22 +309,39 @@ public class DerivedPropertiesSection implements ComponentTypeViewerSection { if(index > 0) msg = msg.substring(index); return msg; } - } - return null; - } }); } catch (DatabaseException e) { - e.printStackTrace(); + LOGGER.error("Could not validate ", e); } - return null; - } + public static void compileAndEvaluate(ReadGraph graph, Variable context, String expression) throws DatabaseException { + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.get("graph"); + try { + CompileSCLMonitorRequest compileSCLMonitorRequest = new CompileSCLMonitorRequest(graph, context) { + @Override + protected String getExpressionText(ReadGraph graph) throws DatabaseException { + return expression; + } + }; + Function1 exp = graph.syncRequest(compileSCLMonitorRequest); + sclContext.put("graph", graph); + //return exp.apply(context.getParent(graph)); + } catch (DatabaseException e) { + throw (DatabaseException)e; + } catch (Throwable t) { + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); + } + } + @Override public void update(ComponentTypePropertiesResult result) { if (table.isDisposed()) diff --git a/bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/Synchronizer.java b/bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/Synchronizer.java index 9c7428416..8125a676c 100644 --- a/bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/Synchronizer.java +++ b/bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/Synchronizer.java @@ -124,7 +124,6 @@ public class Synchronizer { while((cur = cur.getCause()) != null) { if(!(cur instanceof MissingVariableValueException)) { handler.reportProblem(cur.getMessage()); - break; } } } catch (Exception e) { diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileStructuralValueRequest.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileStructuralValueRequest.java index 3b54c0f62..9b83a932b 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileStructuralValueRequest.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileStructuralValueRequest.java @@ -5,6 +5,7 @@ import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.IndexRoot; +import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; @@ -43,7 +44,14 @@ public class CompileStructuralValueRequest extends AbstractCompileStructuralValu sclContext.put("graph", graph); return exp.apply(context); } catch (Throwable t) { - throw new DatabaseException("Compiling structural value request for component=" + request.component + ", literal=" + request.literal + " and relation " + request.relation + " failed!", t); + String componentName = NameUtils.getSafeName(graph, request.component); + String literalName = NameUtils.getSafeName(graph, request.literal); + String relationName = NameUtils.getSafeName(graph, request.relation); + StringBuilder sb = new StringBuilder("Compiling structural value request for component ") + .append(componentName).append(" ").append(request.component).append(" , literal ") + .append(literalName).append(" ").append(request.literal).append(" and relation ") + .append(relationName).append(" ").append(request.relation).append(" failed!"); + throw new DatabaseException(sb.toString(), t); } finally { sclContext.put("graph", oldGraph); }