From: Antti Villberg Date: Wed, 31 Oct 2018 05:00:00 +0000 (+0200) Subject: Variable optimizations for documents (Simupedia) X-Git-Tag: v1.43.0~136^2~282^2 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=2d97029aeaaf5d6a965eae98c1646eef29ae2f8b;p=simantics%2Fplatform.git Variable optimizations for documents (Simupedia) * More control over computational values served by ReadGraph. * More cacheable Connections (Connection2) gitlab #169 Change-Id: I304de13f97c25661fed2905e33887e315144591e --- diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java index 02877596b..b3eba37fb 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java @@ -1,13 +1,12 @@ package org.simantics.db.common.request; +import org.simantics.db.ComputationalValue; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.utils.Functions; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.RuntimeDatabaseException; import org.simantics.layer0.Layer0; -import org.simantics.scl.reflection.ReflectionUtils; -import org.simantics.scl.reflection.ValueNotFoundException; import org.simantics.scl.runtime.function.FunctionImpl3; /** @@ -20,7 +19,7 @@ public class AdaptValue extends ResourceRead { super(resource); } - private static final FunctionImpl3 functionApplication = new FunctionImpl3() { + public static final FunctionImpl3 functionApplication = new FunctionImpl3() { @Override public Object apply(ReadGraph graph, Resource resource, Object context) { @@ -36,12 +35,10 @@ public class AdaptValue extends ResourceRead { @Override public Object perform(ReadGraph graph) throws DatabaseException { String uri = graph.getURI(resource); - try { - if(Layer0.URIs.Functions_functionApplication.equals(uri)) return functionApplication; - return ReflectionUtils.getValue(uri).getValue(); - } catch (ValueNotFoundException e) { - throw new DatabaseException("Couldn't adapt the value " + uri, e); - } + if(Layer0.URIs.Functions_functionApplication.equals(uri)) return functionApplication; + ComputationalValue ev = graph.adapt(resource, ComputationalValue.class); + return ev.getValue(graph, resource); + } } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java index 3feb22e00..2ef40c294 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java @@ -45,6 +45,7 @@ import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.binary.BinaryFile; import org.simantics.databoard.util.binary.RandomAccessBinary; import org.simantics.db.AsyncReadGraph; +import org.simantics.db.ComputationalValue; import org.simantics.db.DevelopmentKeys; import org.simantics.db.ExternalValueSupport; import org.simantics.db.ReadGraph; @@ -6102,12 +6103,18 @@ public class ReadGraphImpl implements AsyncReadGraph { return getValue(r, binding); } } else if(types.contains(L0.ExternalValue)) { - try { - return (T)ReflectionUtils.getValue(getURI(r)).getValue(); - } catch(ValueNotFoundException e) { - throw new DatabaseException(e); - } catch(ClassCastException e) { - throw new DatabaseException(e); + ComputationalValue cv = syncRequest(new PossibleAdapter(r, ComputationalValue.class), TransientCacheAsyncListener.instance()); + if(cv != null) { + return cv.getValue(this, r); + } else { + // This should not even be possible since L0 defines an adapter for all values + try { + return (T)ReflectionUtils.getValue(getURI(r)).getValue(); + } catch(ValueNotFoundException e) { + throw new DatabaseException(e); + } catch(ClassCastException e) { + throw new DatabaseException(e); + } } } else { diff --git a/bundles/org.simantics.db.layer0/adapters.xml b/bundles/org.simantics.db.layer0/adapters.xml index 9e85e9a1b..dfeb3cb0c 100644 --- a/bundles/org.simantics.db.layer0/adapters.xml +++ b/bundles/org.simantics.db.layer0/adapters.xml @@ -283,5 +283,16 @@ class="org.simantics.db.layer0.adapter.impl.ModelImportAdvisorFactory"> - + + + + + + + + + diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java new file mode 100644 index 000000000..517ce761e --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.db.layer0.adapter; + +import org.simantics.db.ConverterComputationalValue; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.RuntimeDatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.scl.runtime.function.FunctionImpl3; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public abstract class ContextualRelatedValue implements ConverterComputationalValue { + + @SuppressWarnings("unchecked") + @Override + public T getValue(ReadGraph graph, Resource resource) throws DatabaseException { + return (T) new FunctionImpl3() { + @Override + public Object apply(ReadGraph graph, Resource converter, Object context) { + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.get("graph"); + try { + if (context instanceof Variable) { + Variable variable = (Variable)context; + try { + Function1 fn = getFunction(graph, variable.getParent(graph).getRepresents(graph), variable.getRepresents(graph), variable.getPredicateResource(graph)); + sclContext.put("graph", graph); + return fn.apply(variable); + } catch (DatabaseException e) { + throw new RuntimeDatabaseException(e); + } + } if (context instanceof Resource) { + Resource resource = (Resource)context; + try { + // Here converter is the object and context is the subject + Function1 fn = getFunction(graph, resource, converter, null); + return fn.apply(resource); + } catch (DatabaseException e) { + throw new RuntimeDatabaseException(e); + } + } else { + throw new IllegalStateException("Unknown context " + context); + } + } finally { + sclContext.put("graph", oldGraph); + } + } + }; + } + +} diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ReflectionComputationalValue.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ReflectionComputationalValue.java new file mode 100644 index 000000000..66d4cefc7 --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ReflectionComputationalValue.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.db.layer0.adapter; + +import org.simantics.db.ComputationalValue; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.scl.reflection.ReflectionUtils; +import org.simantics.scl.reflection.ValueNotFoundException; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public class ReflectionComputationalValue implements ComputationalValue { + + @SuppressWarnings("unchecked") + @Override + public T getValue(ReadGraph graph, Resource resource) throws DatabaseException { + try { + return (T)ReflectionUtils.getValue(graph.getURI(resource)).getValue(); + } catch(ValueNotFoundException e) { + throw new DatabaseException(e); + } catch(ClassCastException e) { + throw new DatabaseException(e); + } + } + +} diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/SCLComputationalValue.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/SCLComputationalValue.java new file mode 100644 index 000000000..83382adb3 --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/SCLComputationalValue.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.db.layer0.adapter; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.scl.CompileResourceValueRequest; +import org.simantics.db.layer0.scl.CompileValueRequest; +import org.simantics.scl.runtime.function.Function1; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public class SCLComputationalValue extends ContextualRelatedValue { + + @Override + public Function1 getFunction(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + if (s != null && p != null && o != null) { + return CompileValueRequest.compile(graph, s, o, p); + } else if (o != null) { + return CompileResourceValueRequest.compile(graph, o); + } else { + throw new DatabaseException("Could not compile SCL expression: s=" + s + " p=" + p + " o=" + o); + } + } + +} diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/AbstractExpressionCompilationRequest.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/AbstractExpressionCompilationRequest.java index d40f82d4d..3a95f2530 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/AbstractExpressionCompilationRequest.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/AbstractExpressionCompilationRequest.java @@ -5,6 +5,7 @@ import java.util.List; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.RuntimeDatabaseException; import org.simantics.db.request.Read; @@ -34,6 +35,8 @@ import org.simantics.scl.compiler.types.util.MultiFunction; import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.function.Function1; import org.simantics.utils.datastructures.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import gnu.trove.map.hash.THashMap; @@ -62,6 +65,8 @@ import gnu.trove.map.hash.THashMap; public abstract class AbstractExpressionCompilationRequest implements Read> { + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractExpressionCompilationRequest.class); + protected static final Type RESOURCE = Types.con("Simantics/DB", "Resource"); protected static final Type VARIABLE = Types.con("Simantics/Variables", "Variable"); protected static Name PROPERTY_VALUE = Name.create("Simantics/Variables", "propertyValue"); @@ -143,12 +148,13 @@ implements Read> { return false; } + @SuppressWarnings("unchecked") private Function1 eval(ExpressionEvaluator evaluator, ReadGraph graph) throws DatabaseException { Object oldGraph = SCLContext.getCurrent().put("graph", graph); try { return (Function1)evaluator.eval(); } catch(RuntimeDatabaseException e) { - e.printStackTrace(); + LOGGER.error("Failed to evaluate SCL expression", e); if(e.getCause() instanceof DatabaseException) throw (DatabaseException)e.getCause(); else @@ -167,7 +173,7 @@ implements Read> { throw new SCLDatabaseException(b.toString()+b2.toString(), b2.toString(), e.getErrors()); } catch(Throwable e) { // Should not happen! - e.printStackTrace(); + LOGGER.error("This error should never happen", e); throw new RuntimeException(e); } finally { SCLContext.getCurrent().put("graph", oldGraph); @@ -186,12 +192,11 @@ implements Read> { return concreteEffects; } catch(MatchException e) { // Should not happen! - e.printStackTrace(); + LOGGER.error("Failed to get expression effects", e); throw new RuntimeException(e); } } - @SuppressWarnings("unchecked") @Override public Function1 perform(final ReadGraph graph) throws DatabaseException { CompilationContext context = getCompilationContext(graph); @@ -225,10 +230,10 @@ implements Read> { else return base; } - - protected static String resolveExpectedValueType(ReadGraph graph, org.simantics.db.layer0.variable.Variable context) throws DatabaseException { + + protected static String resolveExpectedValueType(ReadGraph graph, Resource predicate) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); - String valueType = graph.getPossibleRelatedValue(context.getPredicateResource(graph), L0.RequiresValueType, Bindings.STRING); - return valueType; + return graph.getPossibleRelatedValue(predicate, L0.RequiresValueType, Bindings.STRING); } + } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/CompileResourceValueRequest.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/CompileResourceValueRequest.java index c8d168f50..e56c3d5ce 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/CompileResourceValueRequest.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/CompileResourceValueRequest.java @@ -24,7 +24,7 @@ import org.simantics.scl.runtime.function.Function1; * * @author Antti Villberg */ -public class CompileResourceValueRequest extends AbstractExpressionCompilationRequest { +public class CompileResourceValueRequest extends AbstractExpressionCompilationRequest { public static class CompilationContext extends AbstractExpressionCompilationContext { public CompilationContext(RuntimeEnvironment runtimeEnvironment) { @@ -42,8 +42,8 @@ public class CompileResourceValueRequest extends AbstractExpressionCompilationRe SCLContext sclContext = SCLContext.getCurrent(); Object oldGraph = sclContext.get("graph"); try { - Function1 exp = graph.syncRequest(new CompileResourceValueRequest(literal), - TransientCacheListener.>instance()); + Function1 exp = graph.syncRequest(new CompileResourceValueRequest(literal), + TransientCacheListener.instance()); sclContext.put("graph", graph); return exp.apply(literal); } catch (DatabaseException e) { @@ -55,6 +55,10 @@ public class CompileResourceValueRequest extends AbstractExpressionCompilationRe } } + public static Function1 compile(ReadGraph graph, Resource literal) throws DatabaseException { + return graph.syncRequest(new CompileResourceValueRequest(literal), TransientCacheListener.instance()); + } + @Override protected String getExpressionText(ReadGraph graph) throws DatabaseException { diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/CompileValueRequest.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/CompileValueRequest.java index e1804d790..1eb01aa39 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/CompileValueRequest.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/scl/CompileValueRequest.java @@ -25,7 +25,7 @@ import org.simantics.scl.runtime.function.Function1; * * @author Tuukka Lehtonen */ -public class CompileValueRequest extends AbstractExpressionCompilationRequest { +public class CompileValueRequest extends AbstractExpressionCompilationRequest { public static class CompilationContext extends AbstractExpressionCompilationContext { public CompilationContext(RuntimeEnvironment runtimeEnvironment) { @@ -53,8 +53,8 @@ public class CompileValueRequest extends AbstractExpressionCompilationRequest exp = graph.syncRequest(new CompileValueRequest(graph, context), - TransientCacheListener.>instance()); + Function1 exp = graph.syncRequest(new CompileValueRequest(graph, context), + TransientCacheListener.instance()); sclContext.put("graph", graph); return exp.apply(context); } catch (DatabaseException e) { @@ -66,6 +66,23 @@ public class CompileValueRequest extends AbstractExpressionCompilationRequest compile(ReadGraph graph, Resource component, Resource literal, Resource predicate) throws DatabaseException { + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.get("graph"); + try { + Function1 exp = graph.syncRequest(new CompileValueRequest(component, literal, predicate), + TransientCacheListener.instance()); + sclContext.put("graph", graph); + return exp; + } catch (DatabaseException e) { + throw (DatabaseException)e; + } catch (Throwable t) { + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); + } + } + @Override protected String getExpressionText(ReadGraph graph) throws DatabaseException { diff --git a/bundles/org.simantics.db/src/org/simantics/db/ComputationalValue.java b/bundles/org.simantics.db/src/org/simantics/db/ComputationalValue.java new file mode 100644 index 000000000..647e49162 --- /dev/null +++ b/bundles/org.simantics.db/src/org/simantics/db/ComputationalValue.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.db; + +import org.simantics.db.exception.DatabaseException; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public interface ComputationalValue { + + public T getValue(ReadGraph graph, Resource resource) throws DatabaseException; + +} diff --git a/bundles/org.simantics.db/src/org/simantics/db/ConverterComputationalValue.java b/bundles/org.simantics.db/src/org/simantics/db/ConverterComputationalValue.java new file mode 100644 index 000000000..0adb6b56f --- /dev/null +++ b/bundles/org.simantics.db/src/org/simantics/db/ConverterComputationalValue.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.db; + +import org.simantics.db.exception.DatabaseException; +import org.simantics.scl.runtime.function.Function1; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public interface ConverterComputationalValue extends ComputationalValue { + + /** + * This computes the expression function that shall be called with given context + * as defined in + * {@link ReadGraph#getRelatedValue2(Resource, Resource, Object, org.simantics.databoard.binding.Binding)}. + * + *

+ * Context can be Resource (literal) or Variable. With Resource context this + * gets called with (null, null, literal resource). With Variable + * property context this gets called with + * (represents of parent, represents, predicate resource). + */ + Function1 getFunction(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException; + +} diff --git a/bundles/org.simantics.document.server/adapters.xml b/bundles/org.simantics.document.server/adapters.xml index 7a1476025..cd1621168 100644 --- a/bundles/org.simantics.document.server/adapters.xml +++ b/bundles/org.simantics.document.server/adapters.xml @@ -15,4 +15,12 @@ + + + + + + \ No newline at end of file diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/HandlerSCLComputationalValue.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/HandlerSCLComputationalValue.java new file mode 100644 index 000000000..6eb2186c6 --- /dev/null +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/HandlerSCLComputationalValue.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.document.server; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ContextualRelatedValue; +import org.simantics.document.server.request.ServerSCLHandlerValueRequest; +import org.simantics.scl.runtime.function.Function1; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public class HandlerSCLComputationalValue extends ContextualRelatedValue { + + @Override + public Function1 getFunction(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + return ServerSCLHandlerValueRequest.compile(graph, s, o, p); + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/SCLComputationalValue.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/SCLComputationalValue.java new file mode 100644 index 000000000..4c07f7c6e --- /dev/null +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/SCLComputationalValue.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.document.server; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ContextualRelatedValue; +import org.simantics.document.server.request.ServerSCLValueRequest; +import org.simantics.scl.runtime.function.Function1; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public class SCLComputationalValue extends ContextualRelatedValue { + + @Override + public Function1 getFunction(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + return ServerSCLValueRequest.compile(graph, s, o, p); + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java index 4a4164303..ab5e7a8e4 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java @@ -8,12 +8,14 @@ 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.request.PossibleTypedParent; +import org.simantics.db.common.request.UnaryRead; import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.request.VariableRead; import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; import org.simantics.db.layer0.variable.Variable; +import org.simantics.document.base.ontology.DocumentationResource; import org.simantics.document.server.request.ServerSCLHandlerValueRequest.CompilationContext; import org.simantics.layer0.Layer0; import org.simantics.scl.compiler.elaboration.expressions.EApply; @@ -35,9 +37,8 @@ import org.simantics.structural2.scl.FindPossibleComponentTypeRequest; import org.simantics.structural2.scl.ReadComponentTypeInterfaceRequest; import org.simantics.utils.datastructures.Pair; -public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationRequest { +public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationRequest { - private final Variable context; private final Pair componentTypeAndRoot; private final Resource literal; protected String possibleExpectedValueType; @@ -52,16 +53,19 @@ public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationR } } - private ServerSCLHandlerValueRequest(Variable context, Pair componentTypeAndRoot, Resource literal, String possibleExpectedValueType) { + private ServerSCLHandlerValueRequest(Pair componentTypeAndRoot, Resource literal, String possibleExpectedValueType) { assert(literal != null); - this.context = context; this.literal = literal; this.componentTypeAndRoot = componentTypeAndRoot; this.possibleExpectedValueType = possibleExpectedValueType; } public ServerSCLHandlerValueRequest(ReadGraph graph, Variable context) throws DatabaseException { - this(context, getComponentTypeAndRoot(graph, context), context.getRepresents(graph), resolveExpectedValueType(graph, context)); + this(getComponentTypeAndRoot(graph, context), context.getRepresents(graph), resolveExpectedValueType(graph, context.getPredicateResource(graph))); + } + + public ServerSCLHandlerValueRequest(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + this(getComponentTypeAndRoot(graph, s), o, resolveExpectedValueType(graph, p)); } private static Pair getComponentTypeAndRoot(ReadGraph graph, Variable property) throws DatabaseException { @@ -79,6 +83,21 @@ public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationR return Pair.make(parent.getType(graph), root); } + private static Pair getComponentTypeAndRoot(ReadGraph graph, Resource component) throws DatabaseException { + if(component != null) { + Resource type = graph.syncRequest(new FindPossibleComponentTypeRequest(component)); + if(type != null) { + Resource root = graph.syncRequest(new IndexRoot(type)); + return Pair.make(type, root); + } else { + Resource doc = graph.syncRequest(new PossibleTypedParent(component, DocumentationResource.getInstance(graph).Document)); + Resource componentType = graph.getSingleType(doc); + Resource root = graph.syncRequest(new IndexRoot(doc)); + return Pair.make(componentType, root); + } + } + throw new IllegalStateException(); + } public static List getEffects(ReadGraph graph, Variable context) throws DatabaseException { try { @@ -95,8 +114,8 @@ public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationR SCLContext sclContext = SCLContext.getCurrent(); Object oldGraph = sclContext.get("graph"); try { - Function1 exp = graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context), - TransientCacheListener.>instance()); + Function1 exp = graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context), + TransientCacheListener.instance()); sclContext.put("graph", graph); return exp.apply(context); } catch (DatabaseException e) { @@ -108,6 +127,14 @@ public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationR } } + public static Function1 compile(ReadGraph graph, Variable context) throws DatabaseException { + return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context), TransientCacheListener.instance()); + } + + public static Function1 compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, s, o, p), TransientCacheListener.>instance()); + } + @Override protected String getExpressionText(ReadGraph graph) throws DatabaseException { @@ -127,30 +154,16 @@ public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationR @Override protected CompilationContext getCompilationContext(ReadGraph graph) throws DatabaseException { - - return graph.syncRequest(new VariableRead(context) { - + return graph.syncRequest(new UnaryRead,CompilationContext>(componentTypeAndRoot) { @Override public CompilationContext perform(ReadGraph graph) throws DatabaseException { - - Pair parameter = getComponentTypeAndRoot(graph, variable); RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second)); - Map propertyMap = graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()), TransientCacheListener.>instance()); - -// Map result = new HashMap(propertyMap); -// for(DataDefinition dd : Functions.dataDefinitions(graph, variable)) { -// result.put(dd.target, null); -// } - return new CompilationContext(runtimeEnvironment, propertyMap); - } - }); - } @Override @@ -229,10 +242,7 @@ public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationR @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((context == null) ? 0 : context.hashCode()); - return result; + return 31*(31*getClass().hashCode() + literal.hashCode()) + componentTypeAndRoot.hashCode(); } @Override @@ -244,27 +254,7 @@ public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationR if (getClass() != obj.getClass()) return false; ServerSCLHandlerValueRequest other = (ServerSCLHandlerValueRequest) obj; - if (context == null) { - if (other.context != null) - return false; - } else if (!context.equals(other.context)) - return false; - return true; + return literal.equals(other.literal) && componentTypeAndRoot.equals(other.componentTypeAndRoot); } -// @Override -// public int hashCode() { -// return 31*(31*getClass().hashCode() + literal.hashCode()) + componentTypeAndRoot.hashCode(); -// } -// -// @Override -// public boolean equals(Object obj) { -// if(this == obj) -// return true; -// if(obj == null || obj.getClass() != getClass()) -// return false; -// ServerSCLHandlerValueRequest other = (ServerSCLHandlerValueRequest)obj; -// return literal.equals(other.literal) && componentTypeAndRoot.equals(other.componentTypeAndRoot); -// } - } diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java index f9181d271..09f1523a2 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java @@ -7,12 +7,14 @@ 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.request.PossibleTypedParent; import org.simantics.db.common.request.UnaryRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; import org.simantics.db.layer0.variable.Variable; +import org.simantics.document.base.ontology.DocumentationResource; import org.simantics.document.server.request.ServerSCLValueRequest.CompilationContext; import org.simantics.layer0.Layer0; import org.simantics.scl.compiler.common.names.Name; @@ -40,7 +42,7 @@ import org.simantics.utils.datastructures.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest { +public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest { private final Pair componentTypeAndRoot; private final Resource literal; @@ -64,7 +66,11 @@ public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest< } public ServerSCLValueRequest(ReadGraph graph, Variable context) throws DatabaseException { - this(getComponentTypeAndRoot(graph, context), context.getRepresents(graph), resolveExpectedValueType(graph, context)); + this(getComponentTypeAndRoot(graph, context), context.getRepresents(graph), resolveExpectedValueType(graph, context.getPredicateResource(graph))); + } + + public ServerSCLValueRequest(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + this(getComponentTypeAndRoot(graph, s), o, resolveExpectedValueType(graph, p)); } private static Pair getComponentTypeAndRoot(ReadGraph graph, Variable property) throws DatabaseException { @@ -82,11 +88,35 @@ public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest< return Pair.make(parent.getType(graph), root); } + private static Pair getComponentTypeAndRoot(ReadGraph graph, Resource component) throws DatabaseException { + if(component != null) { + Resource type = graph.syncRequest(new FindPossibleComponentTypeRequest(component)); + if(type != null) { + Resource root = graph.syncRequest(new IndexRoot(type)); + // System.err.println("getComponentTypeAndRoot3 " + graph.getPossibleURI(component) + " => " + graph.getPossibleURI(type) + " " + graph.getPossibleURI(root)); + return Pair.make(type, root); + } else { + Resource doc = graph.syncRequest(new PossibleTypedParent(component, DocumentationResource.getInstance(graph).Document)); + if(doc != null) { + Resource componentType = graph.getSingleType(doc); + Resource root = graph.syncRequest(new IndexRoot(doc)); + return Pair.make(componentType, root); + } else { + System.err.println("component = " + component); + Resource root = graph.syncRequest(new IndexRoot(component)); +// Resource componentType = graph.getSingleType(doc); + return Pair.make(null, root); + } + } + } + throw new IllegalStateException(); + } + public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException { SCLContext sclContext = SCLContext.getCurrent(); Object oldGraph = sclContext.get("graph"); try { - Function1 exp = compile(graph, context); + Function1 exp = compile(graph, context); sclContext.put("graph", graph); return exp.apply(context); } catch (DatabaseException e) { @@ -97,9 +127,13 @@ public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest< sclContext.put("graph", oldGraph); } } - - public static Function1 compile(ReadGraph graph, Variable context) throws DatabaseException { - return graph.syncRequest(new ServerSCLValueRequest(graph, context), TransientCacheListener.>instance()); + + public static Function1 compile(ReadGraph graph, Variable context) throws DatabaseException { + return graph.syncRequest(new ServerSCLValueRequest(graph, context), TransientCacheListener.instance()); + } + + public static Function1 compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + return graph.syncRequest(new ServerSCLValueRequest(graph, s, o, p), TransientCacheListener.instance()); } @Override @@ -223,8 +257,8 @@ public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest< return literal.equals(other.literal) && componentTypeAndRoot.equals(other.componentTypeAndRoot); } - public static Function1 validate(ReadGraph graph, Variable context) throws DatabaseException { - return graph.syncRequest(new ServerSCLValueValidationRequest(graph, context), TransientCacheListener.>instance()); + public static Function1 validate(ReadGraph graph, Variable context) throws DatabaseException { + return graph.syncRequest(new ServerSCLValueValidationRequest(graph, context), TransientCacheListener.instance()); } public static class ServerSCLValueValidationRequest extends ServerSCLValueRequest { diff --git a/bundles/org.simantics.layer0/graph/Layer0SCL.pgraph b/bundles/org.simantics.layer0/graph/Layer0SCL.pgraph index 783f4f401..ec31d0350 100644 --- a/bundles/org.simantics.layer0/graph/Layer0SCL.pgraph +++ b/bundles/org.simantics.layer0/graph/Layer0SCL.pgraph @@ -10,7 +10,12 @@ L0.Functions.entityLabel : L0.ExternalValue L0.Functions.listResources : L0.ExternalValue L0.Functions.resourceAsValue : L0.ExternalValue L0.Functions.functionApplication : L0.ExternalValue + +// This was replaced by L0.Functions.sclValue to make things more uniform L0.Functions.computeExpression : L0.ExternalValue + @L0.tag L0.Deprecated + +L0.Functions.sclValue : L0.ExternalValue L0.Functions.composedPropertyValue : L0.ExternalValue L0.Functions.standardValueAccessor : L0.ExternalValue diff --git a/bundles/org.simantics.layer0/graph/Layer0Values.pgraph b/bundles/org.simantics.layer0/graph/Layer0Values.pgraph index 16f01a7be..358aaa7e9 100644 --- a/bundles/org.simantics.layer0/graph/Layer0Values.pgraph +++ b/bundles/org.simantics.layer0/graph/Layer0Values.pgraph @@ -28,7 +28,7 @@ L0.SCLValue -- L0.SCLValue.expression --> L0.String -- L0.SCLValue.environment --> L0.SCLValue.Environment -- L0.SCLValueType.validator ==> "Variable -> String" + + + + + \ No newline at end of file diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLComputationalValue.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLComputationalValue.java new file mode 100644 index 000000000..b64a4b809 --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLComputationalValue.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.modeling; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.adapter.ContextualRelatedValue; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.structural2.scl.CompileStructuralValueRequest; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public class SCLComputationalValue extends ContextualRelatedValue { + + @Override + public Function1 getFunction(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + return CompileStructuralValueRequest.compile(graph, s, o, p); + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLQueryRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLQueryRequest.java index 8fed128d6..1cef75ddf 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLQueryRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLQueryRequest.java @@ -38,8 +38,8 @@ public class CompileSCLQueryRequest extends CompileStructuralValueRequest { SCLContext sclContext = SCLContext.getCurrent(); Object oldGraph = sclContext.get("graph"); try { - Function1 exp = graph.syncRequest(new CompileSCLQueryRequest(graph, context), - TransientCacheListener.>instance()); + Function1 exp = graph.syncRequest(new CompileSCLQueryRequest(graph, context), + TransientCacheListener.>instance()); sclContext.put("graph", graph); return exp.apply(context); } catch (DatabaseException e) { diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLValueRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLValueRequest.java index bfd12fbe1..9c97017cc 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLValueRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLValueRequest.java @@ -19,8 +19,8 @@ public class CompileSCLValueRequest extends CompileStructuralValueRequest { SCLContext sclContext = SCLContext.getCurrent(); Object oldGraph = sclContext.get("graph"); try { - Function1 exp = graph.syncRequest(new CompileSCLValueRequest(graph, context), - TransientCacheListener.>instance()); + Function1 exp = graph.syncRequest(new CompileSCLValueRequest(graph, context), + TransientCacheListener.instance()); sclContext.put("graph", graph); return exp.apply(context); } catch (DatabaseException e) { diff --git a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/function/CompileSCLValueRequest.java b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/function/CompileSCLValueRequest.java index 736c0396f..45e4d2d16 100644 --- a/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/function/CompileSCLValueRequest.java +++ b/bundles/org.simantics.spreadsheet.graph/src/org/simantics/spreadsheet/graph/function/CompileSCLValueRequest.java @@ -29,8 +29,8 @@ public class CompileSCLValueRequest extends CompileStructuralValueRequest { SCLContext sclContext = SCLContext.getCurrent(); Object oldGraph = sclContext.get("graph"); try { - Function1 exp = graph.syncRequest(new CompileSCLValueRequest(graph, context), - TransientCacheListener.>instance()); + Function1 exp = graph.syncRequest(new CompileSCLValueRequest(graph, context), + TransientCacheListener.instance()); sclContext.put("graph", graph); return exp.apply(context); } catch (DatabaseException e) { diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl.java new file mode 100644 index 000000000..6f977ba7d --- /dev/null +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - 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.Connection2; +import org.simantics.structural2.variables.ConnectionBrowser; +import org.simantics.structural2.variables.VariableConnectionPointDescriptor; + +import gnu.trove.set.hash.THashSet; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public class ConnectionImpl implements Connection { + + private final Variable component; + private final Resource predicate; + + public ConnectionImpl(Variable component, Resource predicate) { + this.component = component; + this.predicate = predicate; + } + + @Override + public Collection getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException { + Set result = new THashSet(); + for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, predicate, relationType)) { + result.add(desc.getVariable(graph)); + } + return result; + } + + @Override + public Collection getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException { + Set result = new THashSet(); + for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, predicate, relationType)) { + result.add(desc.getURI(graph)); + } + return result; + } + + @Override + public Collection getConnectionPointDescriptors(ReadGraph graph, + Resource relationType) throws DatabaseException { + return ConnectionBrowser.flatten(graph, component, predicate, relationType); + } + + @Override + public Connection2 getConnection2() { + return new ConnectionImpl2(predicate); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((component == null) ? 0 : component.hashCode()); + 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; + ConnectionImpl other = (ConnectionImpl) obj; + if (component == null) { + if (other.component != null) + return false; + } else if (!component.equals(other.component)) + return false; + if (predicate == null) { + if (other.predicate != null) + return false; + } else if (!predicate.equals(other.predicate)) + return false; + return true; + } + +} \ 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 index e4b898a6b..af17eeebb 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl2.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/ConnectionImpl2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * Copyright (c) 2007, 2018 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 @@ -19,21 +19,20 @@ 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.Connection2; import org.simantics.structural2.variables.ConnectionBrowser; import org.simantics.structural2.variables.VariableConnectionPointDescriptor; import gnu.trove.set.hash.THashSet; -public class ConnectionImpl2 implements Connection { +public class ConnectionImpl2 implements Connection, Connection2 { - private final Variable component; private final Resource predicate; - - public ConnectionImpl2(Variable component, Resource predicate) { - this.component = component; + + public ConnectionImpl2(Resource predicate) { this.predicate = predicate; } - + @Override public int hashCode() { final int prime = 31; @@ -60,26 +59,50 @@ public class ConnectionImpl2 implements Connection { } @Override - public Collection getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException { - Set result = new THashSet(); + public Collection getConnectionPointURIs(ReadGraph graph, Variable component, Resource relationType) + throws DatabaseException { + Set result = new THashSet(); for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, predicate, relationType)) { - result.add(desc.getVariable(graph)); + result.add(desc.getURI(graph)); } return result; } - + @Override - public Collection getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException { - Set result = new THashSet(); + public Collection getConnectionPoints(ReadGraph graph, Variable component, Resource relationType) + throws DatabaseException { + Set result = new THashSet(); for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, predicate, relationType)) { - result.add(desc.getURI(graph)); + result.add(desc.getVariable(graph)); } return result; } @Override - public Collection getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException { + public Collection getConnectionPointDescriptors(ReadGraph graph, + Variable component, Resource relationType) throws DatabaseException { return ConnectionBrowser.flatten(graph, component, predicate, relationType); } + @Override + public Collection getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException { + throw new IllegalStateException(); + } + + @Override + public Collection getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException { + throw new IllegalStateException(); + } + + @Override + public Collection getConnectionPointDescriptors(ReadGraph graph, + Resource relationType) throws DatabaseException { + throw new IllegalStateException(); + } + + @Override + public Connection2 getConnection2() { + return this; + } + } \ No newline at end of file diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java index f429fdc91..36461419d 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java @@ -180,7 +180,7 @@ public class Functions { @Override public Object getValue(ReadGraph graph, Variable context) throws DatabaseException { StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context; - return new ConnectionImpl2(context.getParent(graph), variable.property.predicate); + return new ConnectionImpl(context.getParent(graph), variable.property.predicate); } @Override @@ -846,12 +846,12 @@ public class Functions { SCLContext sclContext = SCLContext.getCurrent(); Object oldGraph = sclContext.get("graph"); try { - Function1 exp = graph.syncRequest(new CompileStructuralValueRequest(graph, context) { + Function1 exp = graph.syncRequest(new CompileStructuralValueRequest(graph, context) { protected String getExpressionText(ReadGraph graph) throws DatabaseException { return expression; } }, - TransientCacheListener.>instance()); + TransientCacheListener.instance()); sclContext.put("graph", graph); return exp.apply(context); } catch (DatabaseException e) { diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java index 283e1b5dd..c4b4e341f 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java @@ -14,7 +14,6 @@ import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; -import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EConstant; @@ -34,7 +33,7 @@ import org.simantics.structural2.scl.AbstractCompileStructuralValueRequest.Compi * * @author Antti Villberg */ -abstract public class AbstractCompileStructuralValueRequest extends AbstractExpressionCompilationRequest { +public abstract class AbstractCompileStructuralValueRequest extends AbstractExpressionCompilationRequest { protected final Resource relation; diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileProceduralExpressionValueRequest.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileProceduralExpressionValueRequest.java index fa0676e7d..d9ce13d59 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileProceduralExpressionValueRequest.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/CompileProceduralExpressionValueRequest.java @@ -31,8 +31,8 @@ public class CompileProceduralExpressionValueRequest extends AbstractCompileStru SCLContext sclContext = SCLContext.getCurrent(); Object oldGraph = sclContext.get("graph"); try { - Function1 exp = graph.syncRequest(new CompileProceduralExpressionValueRequest(graph, expression, context), - TransientCacheListener.>instance()); + Function1 exp = graph.syncRequest(new CompileProceduralExpressionValueRequest(graph, expression, context), + TransientCacheListener.instance()); sclContext.put("graph", graph); return exp.apply(context); } catch (DatabaseException 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..7a8eb715f 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 @@ -39,7 +39,7 @@ public class CompileStructuralValueRequest extends AbstractCompileStructuralValu Object oldGraph = sclContext.get("graph"); CompileStructuralValueRequest request = new CompileStructuralValueRequest(graph, context); try { - Function1 exp = graph.syncRequest(request, TransientCacheListener.>instance()); + Function1 exp = graph.syncRequest(request, TransientCacheListener.instance()); sclContext.put("graph", graph); return exp.apply(context); } catch (Throwable t) { @@ -49,6 +49,10 @@ public class CompileStructuralValueRequest extends AbstractCompileStructuralValu } } + public static Function1 compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { + return graph.syncRequest(new CompileStructuralValueRequest(s, o, p), TransientCacheListener.instance()); + } + @Override protected String getExpressionText(ReadGraph graph) throws DatabaseException { diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/Connection.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/Connection.java index b404932e7..4521ec90c 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/Connection.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/Connection.java @@ -22,4 +22,6 @@ public interface Connection { Collection getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException; + Connection2 getConnection2(); + } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/Connection2.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/Connection2.java new file mode 100644 index 000000000..920052477 --- /dev/null +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/Connection2.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +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; + +/** + * Improves query result cacheability over {@link Connection}. + * + * @author Antti Villberg + * @since 1.36.0 + * @see Connection + */ +public interface Connection2 { + + /** + * Return absolute URIs of the connection points. An optional (may be null) relationType may be used + * to filter the returned connection points. + */ + Collection getConnectionPointURIs(ReadGraph graph, Variable component, Resource relationType) throws DatabaseException; + + /** + * Return the connection points. An optional (may be null) relationType may be used + * to filter the returned connection points. + */ + Collection getConnectionPoints(ReadGraph graph, Variable component, Resource relationType) throws DatabaseException; + + Collection getConnectionPointDescriptors(ReadGraph graph, Variable component, Resource relationType) throws DatabaseException; + +} diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java index b2b92039f..60fee19b2 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/ConnectionBrowser.java @@ -17,7 +17,6 @@ import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.request.BinaryRead; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.common.request.TransientUnaryRead; -import org.simantics.db.common.utils.CommonDBUtils; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.common.utils.NearestOwnerFinder; import org.simantics.db.exception.DatabaseException; @@ -36,8 +35,6 @@ 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; @@ -338,14 +335,9 @@ public class ConnectionBrowser { Variable conn = child.getPossibleProperty(graph, cp); FixedConnection fc = (FixedConnection)conn.getValue(graph); - Set result = new THashSet(1+fc.cps.size()); - result.add(new ComponentConnectionDescriptor(child, cp));// (graph, STR, curConfiguration, "/" + c.name + "#" + conn.getName(graph))); - for(Pair cpzz : fc.cps) { - if(cpzz.first == null) { - throw new DatabaseException("Lifted connection was not resolved."); - } - result.add(new PairConnectionDescriptor(curConfiguration, cpzz)); - } + Set result = new THashSet(1+fc.size()); + result.add(new ComponentConnectionDescriptor(child, cp)); + fc.addConnectionDescriptors(graph, curConfiguration, result); return result; } else { diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/FixedConnection.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/FixedConnection.java new file mode 100644 index 000000000..7257ca4c5 --- /dev/null +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/FixedConnection.java @@ -0,0 +1,209 @@ +/******************************************************************************* + * Copyright (c) 2018 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.structural2.variables; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +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.utils.datastructures.Pair; +import org.slf4j.LoggerFactory; + +import gnu.trove.set.hash.THashSet; + +/** + * @author Antti Villberg + * @since 1.36.0 + */ +public class FixedConnection implements Connection, Connection2 { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(FixedConnection.class); + + /* + * This is the parent of the component to be connected + */ + private final Variable procedural; + + private final Collection> cps = new ArrayList>(); + + public FixedConnection(Variable procedural) { + this.procedural = procedural; + } + + public void addAll(List> cps) throws DatabaseException { + /* + * For interface connections the name is null + */ + for (Pair cp : cps) { + this.cps.add(cp); + } + } + + public int size() { + return cps.size(); + } + + public void addConnectionDescriptors(ReadGraph graph, Variable curConfiguration, + Collection result) throws DatabaseException { + for (Pair cpzz : cps) { + // This is a connection to an interface terminal. It is handled by + // ConnectionBrowser in separate logic. We should never have gotten this far + if (cpzz.first == null) { + String message = "Lifted connection was not resolved. Child = " + procedural.getURI(graph); + throw new DatabaseException(message); + } + result.add(new PairConnectionDescriptor(curConfiguration, cpzz)); + } + } + + @Override + public Collection getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException { + Set result = new THashSet(); + for (Pair cp : cps) { + Variable component = cp.first == null ? procedural : procedural.getChild(graph, cp.first); + Variable cp2 = component.getPossibleProperty(graph, cp.second); + if (cp2 != null) + for (VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, + relationType)) { + result.add(desc.getVariable(graph)); + } + else + LOGGER.warn("no cp " + cp.first + " for " + component.getURI(graph)); + } + return result; + } + + @Override + public Collection getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException { + Set result = new THashSet(); + for (Pair cp : cps) { + Variable component = cp.first == null ? procedural : procedural.getChild(graph, cp.first); + Variable cp2 = component.getPossibleProperty(graph, cp.second); + if (cp2 != null) + for (VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, + relationType)) { + result.add(desc.getURI(graph)); + } + else + LOGGER.warn("no cp " + cp.first + " for " + component.getURI(graph)); + } + return result; + } + + @Override + public Collection getConnectionPointDescriptors(ReadGraph graph, + Resource relationType) throws DatabaseException { + Set result = new THashSet(); + for (Pair cp : cps) { + Variable component = cp.first == null ? procedural : procedural.getChild(graph, cp.first); + Variable cp2 = component.getPossibleProperty(graph, cp.second); + if (cp2 != null) + result.addAll(ConnectionBrowser.flatten(graph, component, cp.second, relationType)); + else + LOGGER.warn("no cp " + cp.first + " for " + component.getURI(graph)); + } + return result; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((cps == null) ? 0 : cps.hashCode()); + result = prime * result + ((procedural == null) ? 0 : procedural.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; + FixedConnection other = (FixedConnection) obj; + if (cps == null) { + if (other.cps != null) + return false; + } else if (!cps.equals(other.cps)) + return false; + if (procedural == null) { + if (other.procedural != null) + return false; + } else if (!procedural.equals(other.procedural)) + return false; + return true; + } + + @Override + public Collection getConnectionPointDescriptors(ReadGraph graph, + Variable component, Resource relationType) throws DatabaseException { + Set result = new THashSet(); + for (Pair cp : cps) { + Variable base = cp.first == null ? component.getParent(graph) : component; + Variable cp2 = base.getPossibleProperty(graph, cp.second); + if (cp2 != null) + result.addAll(ConnectionBrowser.flatten(graph, base, cp.second, relationType)); + else + LOGGER.warn("no cp " + cp.first + " for " + base.getURI(graph)); + } + return result; + } + + @Override + public Collection getConnectionPoints(ReadGraph graph, Variable component, Resource relationType) + throws DatabaseException { + Set result = new THashSet(); + for (Pair cp : cps) { + Variable base = cp.first == null ? component.getParent(graph) : component; + Variable cp2 = base.getPossibleProperty(graph, cp.second); + if (cp2 != null) + for (VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, base, cp.second, + relationType)) { + result.add(desc.getVariable(graph)); + } + else + LOGGER.warn("no cp " + cp.first + " for " + base.getURI(graph)); + } + return result; + } + + @Override + public Collection getConnectionPointURIs(ReadGraph graph, Variable component, Resource relationType) + throws DatabaseException { + Set result = new THashSet(); + for (Pair cp : cps) { + Variable base = cp.first == null ? component.getParent(graph) : component; + Variable cp2 = base.getPossibleProperty(graph, cp.second); + if (cp2 != null) + for (VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, base, cp.second, + relationType)) { + result.add(desc.getURI(graph)); + } + else + LOGGER.warn("no cp " + cp.first + " for " + base.getURI(graph)); + } + return result; + } + + @Override + public Connection2 getConnection2() { + return this; + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/StandardProceduralChildVariable.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/StandardProceduralChildVariable.java index f133adee0..e96fd050a 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/StandardProceduralChildVariable.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/StandardProceduralChildVariable.java @@ -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; @@ -16,7 +13,6 @@ 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.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.NoSingleResultException; import org.simantics.db.layer0.function.All; @@ -39,9 +35,12 @@ import org.simantics.structural2.procedural.Terminal; import org.simantics.utils.datastructures.Pair; import org.slf4j.LoggerFactory; +import gnu.trove.map.hash.THashMap; + public class StandardProceduralChildVariable extends AbstractChildVariable { - private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StandardProceduralChildVariable.class); + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StandardProceduralChildVariable.class); + /* * Extension points * @@ -64,102 +63,6 @@ public class StandardProceduralChildVariable extends AbstractChildVariable { final private Map properties; final private List propertyIdentity; - public static class FixedConnection implements org.simantics.structural2.variables.Connection { - - final public Collection> cps = new ArrayList>(); - - final private Variable parent; - - public FixedConnection(Variable parent) { - this.parent = parent; - } - - @Override - public Collection getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException { - - Set result = new THashSet(); - for(Pair cp : cps) { - Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first); - Variable cp2 = component.getPossibleProperty(graph, cp.second); - if(cp2 != null) - for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, relationType)) { - result.add(desc.getVariable(graph)); - } - else - LOGGER.warn("no cp " + cp.first + " for " + component.getURI(graph)); - } - return result; - - } - - @Override - public Collection getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException { - - Set result = new THashSet(); - for(Pair cp : cps) { - Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first); - Variable cp2 = component.getPossibleProperty(graph, cp.second); - if(cp2 != null) - for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, relationType)) { - result.add(desc.getURI(graph)); - } - else - LOGGER.warn("no cp " + cp.first + " for " + component.getURI(graph)); - } - return result; - - } - - @Override - public Collection getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException { - - Set result = new THashSet(); - for(Pair cp : cps) { - Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first); - Variable cp2 = component.getPossibleProperty(graph, cp.second); - if(cp2 != null) - result.addAll(ConnectionBrowser.flatten(graph, component, cp.second, relationType)); - else - LOGGER.warn("no cp " + cp.first + " for " + component.getURI(graph)); - } - return result; - - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((cps == null) ? 0 : cps.hashCode()); - result = prime * result - + ((parent == null) ? 0 : parent.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; - FixedConnection other = (FixedConnection) obj; - if (cps == null) { - if (other.cps != null) - return false; - } else if (!cps.equals(other.cps)) - return false; - if (parent == null) { - if (other.parent != null) - return false; - } else if (!parent.equals(other.parent)) - return false; - return true; - } - - } - public StandardProceduralChildVariable(ReadGraph graph, Variable parent, VariableNode node, String name, Resource type, List properties, Collection conns) throws DatabaseException { super(node); assert name != null; @@ -208,7 +111,7 @@ public class StandardProceduralChildVariable extends AbstractChildVariable { for(Property p : properties) { String pn = graph.getRelatedValue(p.relation, L0.HasName, Bindings.STRING); if(p.value == null) { - Logger.defaultLogError("StandardProceduralChildVariable " + getURI(graph) + ": null value for property " + pn); + LOGGER.error("StandardProceduralChildVariable " + getURI(graph) + ": null value for property " + pn); } else if (p.value instanceof Expression) { Expression expression = (Expression)p.value; this.properties.put(pn, new StructuralProceduralExpressionPropertyVariable(graph, this, p.relation, expression.text) ); @@ -242,7 +145,7 @@ public class StandardProceduralChildVariable extends AbstractChildVariable { fc = new FixedConnection(parent); map.put(p, fc); } - fc.cps.addAll(cps); + fc.addAll(cps); } } for(Map.Entry entry : map.entrySet()) {