]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Playground for Antti. 12/3112/1 private/antin_tyomaa
authorAntti Villberg <antti.villberg@semantum.fi>
Sun, 18 Aug 2019 09:09:15 +0000 (12:09 +0300)
committerAntti Villberg <antti.villberg@semantum.fi>
Sun, 18 Aug 2019 09:09:15 +0000 (12:09 +0300)
These shall be smuggled into master in small pieces.

Change-Id: I91e16a145d59c785fb421418dc7e5b5487c6fb13

80 files changed:
bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java
bundles/org.simantics.db.common/META-INF/MANIFEST.MF
bundles/org.simantics.db.common/src/org/simantics/db/common/SimanticsInternal.java [new file with mode: 0644]
bundles/org.simantics.db.common/src/org/simantics/db/common/request/RuntimeEnvironmentRequest.java [new file with mode: 0644]
bundles/org.simantics.db.common/src/org/simantics/db/common/utils/CommonDBUtils.java
bundles/org.simantics.db.common/src/org/simantics/db/common/validation/L0Validations.java
bundles/org.simantics.db.layer0/scl/Simantics/Layer0.scl [new file with mode: 0644]
bundles/org.simantics.db.layer0/scl/Simantics/Validation.scl [new file with mode: 0644]
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/internal/SimanticsInternal.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfo.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/PropertyInfoRequest.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/validation/ValidationUtils.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/ResourceX.java [new file with mode: 0644]
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableOrResource.java [new file with mode: 0644]
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableX.java [new file with mode: 0644]
bundles/org.simantics.db.management/META-INF/MANIFEST.MF
bundles/org.simantics.db.management/src/org/simantics/db/management/SessionContext.java
bundles/org.simantics.db.management/src/org/simantics/db/management/internal/SessionManagerProvider.java
bundles/org.simantics.db.services/META-INF/MANIFEST.MF
bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/AdapterRegistry2.java
bundles/org.simantics.db.services/src/org/simantics/db/services/adaption/reflection/ReflectionAdapter2.java
bundles/org.simantics.document.base.ontology/graph/Documentation.pgraph
bundles/org.simantics.document.server/scl/Document/All.scl
bundles/org.simantics.document.server/src/org/simantics/document/server/IEventCommand.java
bundles/org.simantics.document.server/src/org/simantics/document/server/bean/Command.java
bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetData.java
bundles/org.simantics.document.server/src/org/simantics/document/server/client/WidgetManager.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocument.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTDocumentClient.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/SWTViews.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/AbstractEventCommand.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PostEventCommand.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/base/PropertyWidgetManager.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonSelectionListener.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ButtonWidget.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/CommandEventWidget.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/Explorer.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ExplorerListener.java [new file with mode: 0644]
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/FillComposite.java
bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/GridComposite.java
bundles/org.simantics.document.swt.ontology/graph/Components.pgraph
bundles/org.simantics.issues.common/META-INF/MANIFEST.MF
bundles/org.simantics.issues.common/adapters.xml
bundles/org.simantics.issues.common/src/org/simantics/issues/common/AllActiveIssues.java
bundles/org.simantics.issues.common/src/org/simantics/issues/common/AllVisibleIssues.java
bundles/org.simantics.issues.common/src/org/simantics/issues/common/BatchValidations.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/ConstraintIssueSource.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/Messages.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/ModelVisibleIssues.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/RunActiveValidations.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/messages.properties [new file with mode: 0644]
bundles/org.simantics.issues.ontology/graph/Issue.pgraph
bundles/org.simantics.issues.ontology/graph/Layer0Sources.pgraph [new file with mode: 0644]
bundles/org.simantics.issues.ui/scl/Simantics/IssueUI.scl [new file with mode: 0644]
bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/handler/ConfigureIssueSources.java
bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/handler/RunActiveValidations.java
bundles/org.simantics.layer0.utils/META-INF/MANIFEST.MF
bundles/org.simantics.layer0/graph/Layer0.pgraph
bundles/org.simantics.layer0/graph/Layer0Constraints.pgraph
bundles/org.simantics.layer0/graph/Layer0Templates.pgraph
bundles/org.simantics.layer0/graph/Layer0Validations.pgraph
bundles/org.simantics.modeling.ontology/graph/ModelingViewpoint.pgraph
bundles/org.simantics.modeling.ui/scl/Simantics/Testing/BrowseContext.scl
bundles/org.simantics.modeling/adapters.xml
bundles/org.simantics.modeling/scl/Simantics/Issue.scl
bundles/org.simantics.modeling/scl/Simantics/Ontologies.scl
bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SCLCheckedStateRule.java [new file with mode: 0644]
bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SCLChildRule.java
bundles/org.simantics.platform.ui.ontology/META-INF/MANIFEST.MF
bundles/org.simantics.platform.ui.ontology/build.properties
bundles/org.simantics.platform.ui.ontology/graph/PlatformUI.pgraph
bundles/org.simantics.platform.ui.ontology/graph/ValidationView.pgraph [new file with mode: 0644]
bundles/org.simantics.platform.ui.ontology/scl/Simantics/PlatformUI.scl [moved from bundles/org.simantics.platform.ui.ontology/graph/scl/SCLMain.scl with 61% similarity]
bundles/org.simantics.scl.db/scl/Simantics/Variables.scl
bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java
bundles/org.simantics.structural.ontology/graph/Structural.pgraph
bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java
bundles/org.simantics/src/org/simantics/SimanticsPlatform.java

index 2f52153a1192b45e2a6c33e42afd2da58a86e1a1..d27eeaa79244a5785070cbb0da57b6bebe52ecda 100644 (file)
@@ -427,6 +427,10 @@ public class GraphExplorerComposite extends Composite implements Widget, IAdapta
         ((Control)explorer.getControl()).addListener(eventType, listener);
     }
 
+    public void removeListenerFromControl(int eventType, Listener listener) {
+        ((Control)explorer.getControl()).removeListener(eventType, listener);
+    }
+
     public void finish() {
         created = true;
         createControls(site);
index c45b276d72eb7db405710daec9e89341c28af58f..27e43385191e53f6038eda67523c87df3594f5f4 100644 (file)
@@ -15,7 +15,9 @@ Require-Bundle: org.simantics.db;bundle-version="1.1.0";visibility:=reexport,
  org.simantics.user.ontology;bundle-version="1.0.0",
  org.simantics.layer0x.ontology;bundle-version="1.0.0",
  org.simantics.issues.ontology;bundle-version="1.2.0",
- org.slf4j.api
+ org.slf4j.api,
+ org.simantics.db.management;bundle-version="1.1.0",
+ org.simantics.scl.osgi
 Export-Package: org.simantics.db.common,
  org.simantics.db.common.adaption,
  org.simantics.db.common.auth,
diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/SimanticsInternal.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/SimanticsInternal.java
new file mode 100644 (file)
index 0000000..e59e36f
--- /dev/null
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.common;
+
+import java.util.concurrent.TimeUnit;
+
+import org.simantics.db.Session;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.management.ISessionContext;
+import org.simantics.db.management.ISessionContextProvider;
+import org.simantics.db.management.ISessionContextProviderSource;
+import org.simantics.db.request.ReadInterface;
+import org.simantics.db.request.WriteInterface;
+import org.simantics.layer0.Layer0;
+import org.simantics.operation.Layer0X;
+import org.simantics.utils.threads.ThreadUtils;
+
+/**
+ * An internal facade for accessing basic Simantics platform services.
+ * Usable without a graphical UI, i.e. in headless contexts.
+ * 
+ * Use org.simantics.Simantics instead where ever possible.
+ */
+public class SimanticsInternal {
+
+    private static ISessionContextProviderSource providerSource = null;
+
+    /**
+     * Queue execution of a runnable. 
+     * 
+     * @param runnable
+     */
+    public static void async(Runnable runnable) {
+        ThreadUtils.getBlockingWorkExecutor().execute(runnable);
+    }
+
+    public static void async(Runnable runnable, int delay, TimeUnit unit) {
+        ThreadUtils.getTimer().schedule(runnable, delay, unit);
+    }
+    
+    /**
+     * Queue execution of a non-blocking runnable. Use this method with caution. 
+     * A non-blocking runnable nevers locks anything, No Locks, No semaphores,
+     * No Object.wait(), No synchronized() {} blocks.   
+     * 
+     * @param runnable a non-blocking runnable
+     */
+    public static void asyncNonblocking(Runnable runnable) {
+        ThreadUtils.getNonBlockingWorkExecutor().execute(runnable);
+    }
+
+    /**
+     * Schedule execution of a non-blocking runnable. Use this method with caution. 
+     * A non-blocking runnable never locks anything, No Locks, No semaphores,
+     * No Object,wait(), No synchronized() {} blocks.   
+     * 
+     * @param runnable a non-blocking runnable
+     * @param initialDelay
+     * @param period
+     */
+    public static void asyncNonblocking(Runnable runnable, int initialDelay, int period) {
+        ThreadUtils.getNonBlockingWorkExecutor().scheduleAtFixedRate(runnable, initialDelay, period, TimeUnit.MILLISECONDS);
+    }
+    
+    public static synchronized ISessionContext setSessionContext(ISessionContext ctx) {
+        return getSessionContextProvider().setSessionContext(ctx);
+    }
+
+    public static void setSessionContextProviderSource(ISessionContextProviderSource source) {
+        if (source == null)
+            throw new IllegalArgumentException("null provider source");
+        providerSource = source;
+    }
+
+    public static ISessionContextProviderSource getProviderSource() {
+        if (providerSource == null)
+            throw new IllegalStateException(
+            "providerSource must be initialized by the application before using class Simantics");
+        return providerSource;
+    }
+
+    public static ISessionContextProvider getSessionContextProvider() {
+        return getProviderSource().getActive();
+    }
+
+    /**
+     * Returns the database session context associated with the currently active
+     * context. This method should be used to retrieve session contexts only
+     * when the client is sure that the correct context is active.
+     * 
+     * @return the session context associated with the currently active context
+     *         or <code>null</code> if the context has no session context
+     */
+    public static ISessionContext getSessionContext() {
+        ISessionContextProvider provider = getSessionContextProvider();
+        return provider != null ? provider.getSessionContext() : null;
+    }
+
+    /**
+     * Returns the database Session bound to the currently active context.
+     * 
+     * <p>
+     * The method always returns a non-null Session or produces an
+     * IllegalStateException if a Session was not attainable.
+     * </p>
+     * 
+     * @return the Session bound to the currently active workbench window
+     * @throws IllegalStateException if no Session was available
+     */
+    public static Session getSession() {
+        ISessionContext ctx = getSessionContext();
+        if (ctx == null)
+            throw new IllegalStateException("Session unavailable, no database session open");
+        return ctx.getSession();
+    }
+
+    /**
+     * Returns the database Session bound to the currently active context.
+     * Differently from {@link #getSession()}, this method returns
+     * <code>null</code> if there is no current Session available.
+     * 
+     * @see #getSession()
+     * @return the Session bound to the currently active context or
+     *         <code>null</code>
+     */
+    public static Session peekSession() {
+        ISessionContext ctx = getSessionContext();
+        return ctx == null ? null : ctx.peekSession();
+    }
+
+    public static Layer0 getLayer0() throws DatabaseException {
+        return Layer0.getInstance(getSession());
+    }
+
+    public static Layer0X getLayer0X() throws DatabaseException {
+        return Layer0X.getInstance(getSession());
+    }
+
+    
+    public static <T> T sync(ReadInterface<T> r) throws DatabaseException {
+       return getSession().sync(r);
+    }
+    
+    public static <T> T sync(WriteInterface<T> r) throws DatabaseException {
+       return getSession().sync(r);
+    }
+    
+}
diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/RuntimeEnvironmentRequest.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/RuntimeEnvironmentRequest.java
new file mode 100644 (file)
index 0000000..24a5c10
--- /dev/null
@@ -0,0 +1,153 @@
+package org.simantics.db.common.request;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.SimanticsInternal;
+import org.simantics.db.common.utils.CommonDBUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.Listener;
+import org.simantics.db.request.Read;
+import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
+import org.simantics.scl.compiler.module.repository.ImportFailureException;
+import org.simantics.scl.compiler.module.repository.UpdateListener;
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.runtime.SCLContext;
+
+/**
+ * Finds the runtime environment of a model or other index root.
+ * 
+ * @author Hannu Niemist&ouml;
+ * @author Antti Villberg
+ */
+public class RuntimeEnvironmentRequest extends UnaryRead<Resource, RuntimeEnvironment> {
+
+    public RuntimeEnvironmentRequest(Resource parameter) {
+        super(parameter);
+    }
+
+    protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
+    }
+
+    static class UpdateListenerImpl extends UpdateListener {
+
+        final EnvironmentSpecification environmentSpecification;
+        final Listener<RuntimeEnvironment> callback;
+
+        UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
+            this.environmentSpecification = environmentSpecification;
+            this.callback = callback;
+        }
+
+        @Override
+        public void notifyAboutUpdate() {
+            if(callback.isDisposed()) {
+                stopListening();
+                return;
+            }
+            getRuntimeEnvironment(environmentSpecification, callback, this);
+        }
+    };
+
+    public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
+
+        try {
+
+            SCLContext context = SCLContext.getCurrent();
+
+            RuntimeEnvironment env;
+            Object graph = context.get("graph");
+            if(graph == null)
+                try {
+                    env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
+                        @Override
+                        public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
+
+                            SCLContext sclContext = SCLContext.getCurrent();
+                            Object oldGraph = sclContext.get("graph");
+                            try {
+                                sclContext.put("graph", graph);
+                                return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
+                                        environmentSpecification,
+                                        callback.getClass().getClassLoader(), listener);
+                            } catch (ImportFailureException e) {
+                                throw new DatabaseException(e);
+                            } catch (Throwable t) {
+                                throw new DatabaseException(t);
+                            } finally {
+                                sclContext.put("graph", oldGraph);
+                            }
+                        }
+                    });
+                } catch (DatabaseException e) {
+                    callback.exception(e);
+                    return;
+                }
+            else 
+                env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
+                        environmentSpecification,
+                        callback.getClass().getClassLoader(), listener);
+            callback.execute(env);
+        } catch (ImportFailureException e) {
+            callback.exception(new DatabaseException(e));
+        }
+
+    }
+
+    @Override
+    public RuntimeEnvironment perform(ReadGraph graph)
+            throws DatabaseException {
+        final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
+                "Builtin", "",
+                "StandardLibrary", "",
+                "Simantics/All", "");
+        fillEnvironmentSpecification(environmentSpecification);
+
+        Resource mainModule = CommonDBUtils.getPossibleChild(graph, parameter, "SCLMain");
+        String mainModuleUri;
+        if(mainModule != null) {
+            mainModuleUri = graph.getURI(mainModule);
+            environmentSpecification.importModule(mainModuleUri, "");
+        }
+        else
+            mainModuleUri = graph.getURI(parameter) + "/#"; // Add something dummy to the model uri that cannot be in a real URI
+
+        return graph.syncRequest(new ParametrizedPrimitiveRead<String, RuntimeEnvironment>(mainModuleUri) {
+
+            UpdateListenerImpl sclListener;
+
+            @Override
+            public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
+
+                SCLContext context = SCLContext.getCurrent();
+                Object oldGraph = context.put("graph", graph);
+                try {
+
+                    if(procedure.isDisposed()) {
+                        getRuntimeEnvironment(environmentSpecification, procedure, null);
+                    } else {
+                        sclListener = new UpdateListenerImpl(environmentSpecification, procedure);
+                        sclListener.notifyAboutUpdate();
+                    }
+
+                } finally {
+                    context.put("graph", oldGraph);
+                }
+
+            }
+
+            @Override
+            public void unregistered() {
+                if(sclListener != null)
+                    sclListener.stopListening();
+            }
+
+        });
+    }
+
+    @Override
+    public int hashCode() {
+        return 31*getClass().hashCode() + super.hashCode();
+    }
+
+}
index a07d42519c45741c1cd5c8c038502ca06c4fab4e..dcd3939a4f2e64d73ed288a1856b471c1ab8fd46 100644 (file)
@@ -4,7 +4,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
@@ -16,8 +15,10 @@ import org.simantics.db.WriteGraph;
 import org.simantics.db.common.procedure.adapter.DirectStatementProcedure;
 import org.simantics.db.common.request.IsParent;
 import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.PossibleChild;
 import org.simantics.db.common.request.PossibleObjectWithType;
 import org.simantics.db.common.request.PossibleOwner;
+import org.simantics.db.common.request.RuntimeEnvironmentRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.InvalidResourceReferenceException;
 import org.simantics.db.service.ClusterUID;
@@ -26,6 +27,10 @@ import org.simantics.db.service.DirectQuerySupport;
 import org.simantics.db.service.SerialisationSupport;
 import org.simantics.db.service.XSupport;
 import org.simantics.layer0.Layer0;
+import org.simantics.scl.compiler.environment.Environments;
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
+import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
+import org.simantics.scl.compiler.types.Type;
 import org.simantics.utils.datastructures.collections.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -313,5 +318,32 @@ public class CommonDBUtils {
        return xs.isClusterLoaded(clusterUID);
     }
     
+    public static Type getSCLType(ReadGraph graph, RuntimeEnvironment runtimeEnvironment, String typeText) throws DatabaseException {
+        try {
+            return Environments.getType(runtimeEnvironment.getEnvironment(), typeText);
+        } catch (SCLExpressionCompilationException e) {
+            throw new DatabaseException(e);
+        }
+    }
+
+    public static Type getSCLType(ReadGraph graph, Resource resource, String typeText) throws DatabaseException {
+        try {
+            RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(resource));
+            return Environments.getType(runtimeEnvironment.getEnvironment(), typeText);
+        } catch (SCLExpressionCompilationException e) {
+            throw new DatabaseException(e);
+        }
+    }
+
+    public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException {
+        return graph.sync(new PossibleChild(resource, name));
+    }
+
+    public static Resource getPossibleChild(ReadGraph graph, Resource resource, Resource type, String name) throws DatabaseException {
+        Resource child = graph.sync(new PossibleChild(resource, name));
+        if(child == null) return null;
+        if(!graph.isInstanceOf(child, type)) return null;
+        return child;
+    }
     
 }
index a1ed10e77626c56c063aecbabfaa9fd313a2c642..99ef91b7aa0040815b23a4dae559fa1ad3d7d6dd 100644 (file)
@@ -3,41 +3,50 @@ package org.simantics.db.common.validation;
 import org.simantics.databoard.Bindings;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
+import org.simantics.db.common.utils.CommonDBUtils;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.layer0.Layer0;
+import org.simantics.scl.compiler.types.Type;
 
 public class L0Validations {
 
        public static String checkValueType(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {
+               
                if (subject == null)
                        return null;
                if (predicate == null)
                        return null;
 
                Layer0 L0 = Layer0.getInstance(graph);
-           if(graph.isSubrelationOf(predicate, L0.HasProperty)) {
+               if(graph.isSubrelationOf(predicate, L0.HasProperty)) {
                        Resource object = graph.getPossibleObject(subject, predicate);
                        if(object == null) return null;
-               String valueType = graph.getPossibleRelatedValue(predicate, L0.RequiresValueType, Bindings.STRING);
-               if(valueType != null) {
-                       String valueType2 = graph.getPossibleRelatedValue(object, L0.HasValueType, Bindings.STRING);
-                       if(!valueType.equals(valueType2)) {
-                                       StringBuilder sb = new StringBuilder()
-                                       .append("The value type ")
-                                       .append(valueType)
-                                       .append(" of predicate ")
-                                       .append(NameUtils.getSafeName(graph, predicate, true))
-                                       .append(" does not match the value type ")
-                                       .append(valueType2)
-                                       .append(" of object ")
-                                       .append(NameUtils.getSafeName(graph, object, true))
-                                       .append(".");
-                                       return sb.toString();
-                       }
-               }
-           }
-           return null;
+                       String valueTypeText = graph.getPossibleRelatedValue(predicate, L0.RequiresValueType, Bindings.STRING);
+                       if(valueTypeText != null) {
+                               Type valueType = CommonDBUtils.getSCLType(graph, subject, valueTypeText);
+                               String valueTypeText2 = graph.getPossibleRelatedValue(object, L0.HasValueType, Bindings.STRING);
+                               if(valueTypeText2 != null) {
+                                       Type valueType2 = CommonDBUtils.getSCLType(graph, subject, valueTypeText2);
+                                       if(!valueType.equals(valueType2)) {
+                                               StringBuilder sb = new StringBuilder()
+                                                               .append("The value type ")
+                                                               .append(valueType)
+                                                               .append(" of predicate ")
+                                                               .append(NameUtils.getSafeName(graph, predicate, true))
+                                                               .append(" does not match the value type ")
+                                                               .append(valueType2)
+                                                               .append(" of object ")
+                                                               .append(NameUtils.getSafeName(graph, object, true))
+                                                               .append(".");
+                                               return sb.toString();
+                                       }
+                               }
+                       }
+               }
+               
+               return null;
+               
        }
        
 }
diff --git a/bundles/org.simantics.db.layer0/scl/Simantics/Layer0.scl b/bundles/org.simantics.db.layer0/scl/Simantics/Layer0.scl
new file mode 100644 (file)
index 0000000..0b034a1
--- /dev/null
@@ -0,0 +1,9 @@
+include "Simantics/DB"
+include "Simantics/Issue"
+
+importJava "org.simantics.db.layer0.function.All" where
+  uriValidator :: Resource -> <ReadGraph> [Issue]
+  valueValidator :: Resource -> <ReadGraph> [Issue]
+  relationValidator :: Resource -> <ReadGraph> [Issue]
+  propertyValidator :: Resource -> <ReadGraph> [Issue]
+  clusterValidator :: Resource -> <ReadGraph> [Issue]
\ No newline at end of file
diff --git a/bundles/org.simantics.db.layer0/scl/Simantics/Validation.scl b/bundles/org.simantics.db.layer0/scl/Simantics/Validation.scl
new file mode 100644 (file)
index 0000000..0a62e0b
--- /dev/null
@@ -0,0 +1,3 @@
+import "Simantics/DB"
+import "Simantics/Issue"
+
index 8ae309e6825c9d01af3ded4c754db378a42d55e9..6ad324c28e38c9db5cf242afda9659ed5f860aae 100644 (file)
 package org.simantics.db.layer0.internal;
 
 import java.io.File;
-import java.util.concurrent.TimeUnit;
 
 import org.eclipse.core.runtime.Platform;
 import org.simantics.db.Resource;
-import org.simantics.db.Session;
-import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.util.SimanticsClipboard;
 import org.simantics.db.layer0.util.SimanticsKeys;
 import org.simantics.db.management.ISessionContext;
-import org.simantics.db.management.ISessionContextProvider;
-import org.simantics.db.management.ISessionContextProviderSource;
-import org.simantics.db.request.ReadInterface;
-import org.simantics.db.request.WriteInterface;
-import org.simantics.layer0.Layer0;
-import org.simantics.operation.Layer0X;
-import org.simantics.utils.threads.ThreadUtils;
 
 /**
  * An internal facade for accessing basic Simantics platform services.
@@ -35,112 +25,7 @@ import org.simantics.utils.threads.ThreadUtils;
  * 
  * Use org.simantics.Simantics instead where ever possible.
  */
-public class SimanticsInternal {
-
-    private static ISessionContextProviderSource providerSource = null;
-
-    /**
-     * Queue execution of a runnable. 
-     * 
-     * @param runnable
-     */
-    public static void async(Runnable runnable) {
-        ThreadUtils.getBlockingWorkExecutor().execute(runnable);
-    }
-
-    public static void async(Runnable runnable, int delay, TimeUnit unit) {
-        ThreadUtils.getTimer().schedule(runnable, delay, unit);
-    }
-    
-    /**
-     * Queue execution of a non-blocking runnable. Use this method with caution. 
-     * A non-blocking runnable nevers locks anything, No Locks, No semaphores,
-     * No Object.wait(), No synchronized() {} blocks.   
-     * 
-     * @param runnable a non-blocking runnable
-     */
-    public static void asyncNonblocking(Runnable runnable) {
-        ThreadUtils.getNonBlockingWorkExecutor().execute(runnable);
-    }
-
-    /**
-     * Schedule execution of a non-blocking runnable. Use this method with caution. 
-     * A non-blocking runnable never locks anything, No Locks, No semaphores,
-     * No Object,wait(), No synchronized() {} blocks.   
-     * 
-     * @param runnable a non-blocking runnable
-     * @param initialDelay
-     * @param period
-     */
-    public static void asyncNonblocking(Runnable runnable, int initialDelay, int period) {
-        ThreadUtils.getNonBlockingWorkExecutor().scheduleAtFixedRate(runnable, initialDelay, period, TimeUnit.MILLISECONDS);
-    }
-    
-    public static synchronized ISessionContext setSessionContext(ISessionContext ctx) {
-        return getSessionContextProvider().setSessionContext(ctx);
-    }
-
-    public static void setSessionContextProviderSource(ISessionContextProviderSource source) {
-        if (source == null)
-            throw new IllegalArgumentException("null provider source");
-        providerSource = source;
-    }
-
-    public static ISessionContextProviderSource getProviderSource() {
-        if (providerSource == null)
-            throw new IllegalStateException(
-            "providerSource must be initialized by the application before using class Simantics");
-        return providerSource;
-    }
-
-    public static ISessionContextProvider getSessionContextProvider() {
-        return getProviderSource().getActive();
-    }
-
-    /**
-     * Returns the database session context associated with the currently active
-     * context. This method should be used to retrieve session contexts only
-     * when the client is sure that the correct context is active.
-     * 
-     * @return the session context associated with the currently active context
-     *         or <code>null</code> if the context has no session context
-     */
-    public static ISessionContext getSessionContext() {
-        ISessionContextProvider provider = getSessionContextProvider();
-        return provider != null ? provider.getSessionContext() : null;
-    }
-
-    /**
-     * Returns the database Session bound to the currently active context.
-     * 
-     * <p>
-     * The method always returns a non-null Session or produces an
-     * IllegalStateException if a Session was not attainable.
-     * </p>
-     * 
-     * @return the Session bound to the currently active workbench window
-     * @throws IllegalStateException if no Session was available
-     */
-    public static Session getSession() {
-        ISessionContext ctx = getSessionContext();
-        if (ctx == null)
-            throw new IllegalStateException("Session unavailable, no database session open");
-        return ctx.getSession();
-    }
-
-    /**
-     * Returns the database Session bound to the currently active context.
-     * Differently from {@link #getSession()}, this method returns
-     * <code>null</code> if there is no current Session available.
-     * 
-     * @see #getSession()
-     * @return the Session bound to the currently active context or
-     *         <code>null</code>
-     */
-    public static Session peekSession() {
-        ISessionContext ctx = getSessionContext();
-        return ctx == null ? null : ctx.peekSession();
-    }
+public class SimanticsInternal extends org.simantics.db.common.SimanticsInternal {
 
     /**
      * @return the currently open and active project as an IProject
@@ -163,7 +48,7 @@ public class SimanticsInternal {
         ISessionContext ctx = getSessionContext();
         return ctx != null ? (Resource) ctx.getHint(SimanticsKeys.KEY_PROJECT) : null;
     }
-
+       
     private static SimanticsClipboard clipboard = SimanticsClipboard.EMPTY;
 
     /**
@@ -179,23 +64,6 @@ public class SimanticsInternal {
         return clipboard;
     }
 
-    public static Layer0 getLayer0() throws DatabaseException {
-        return Layer0.getInstance(getSession());
-    }
-
-    public static Layer0X getLayer0X() throws DatabaseException {
-        return Layer0X.getInstance(getSession());
-    }
-
-    
-    public static <T> T sync(ReadInterface<T> r) throws DatabaseException {
-       return getSession().sync(r);
-    }
-    
-    public static <T> T sync(WriteInterface<T> r) throws DatabaseException {
-       return getSession().sync(r);
-    }
-    
     public static File getTemporaryDirectory() {
         File workspace = Platform.getLocation().toFile();
         File temp = new File(workspace, "tempFiles");
index f3753ce80bfc3949c84914c234c14f76520c29e4..a219a4ed1ab33996be31c3341869512737913170 100644 (file)
@@ -20,6 +20,7 @@ public class PropertyInfo {
        public final Resource predicate;
        public final String name;
        public final boolean isHasProperty;
+       public final boolean isFunctional;
        public final Set<String> classifications;
        public final VariableBuilder builder;
        public final Resource literalRange;
@@ -30,9 +31,10 @@ public class PropertyInfo {
        public final Map<String,Pair<Resource, ChildReference>> subliteralPredicates;
        public final ValueAccessor valueAccessor;
        public final boolean hasEnumerationRange;
-       public PropertyInfo(Resource predicate, String name, boolean isHasProperty, Set<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Binding defaultBinding, Map<String,Pair<Resource, ChildReference>> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) {
+       public PropertyInfo(Resource predicate, String name, boolean isFunctional, boolean isHasProperty, Set<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Binding defaultBinding, Map<String,Pair<Resource, ChildReference>> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) {
                this.predicate = predicate;
                this.name = name;
+               this.isFunctional = isFunctional;
                this.isHasProperty = isHasProperty;
                this.classifications = classifications;
                this.builder = builder;
@@ -45,7 +47,7 @@ public class PropertyInfo {
                this.valueAccessor = valueAccessor;
                this.hasEnumerationRange = hasEnumerationRange;
        }
-       public static PropertyInfo make(ReadGraph graph, Resource predicate, String name, boolean isHasProperty, Set<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Map<String,Pair<Resource, ChildReference>> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) throws DatabaseException {
+       public static PropertyInfo make(ReadGraph graph, Resource predicate, String name, boolean isFunctional, boolean isHasProperty, Set<String> classifications, VariableBuilder builder, Resource literalRange, Datatype requiredDatatype, String definedUnit, String requiredValueType, Map<String,Pair<Resource, ChildReference>> subliteralPredicates, ValueAccessor valueAccessor, boolean hasEnumerationRange) throws DatabaseException {
 
                Layer0 L0 = Layer0.getInstance(graph);
                if(literalRange != null) {
@@ -58,7 +60,7 @@ public class PropertyInfo {
                
                Binding defaultBinding = requiredDatatype != null ? Bindings.getBinding(requiredDatatype) : null;
                
-               return new PropertyInfo(predicate, name, isHasProperty, classifications, builder, literalRange, requiredDatatype, definedUnit, requiredValueType, defaultBinding, subliteralPredicates, valueAccessor, hasEnumerationRange);
+               return new PropertyInfo(predicate, name, isFunctional, isHasProperty, classifications, builder, literalRange, requiredDatatype, definedUnit, requiredValueType, defaultBinding, subliteralPredicates, valueAccessor, hasEnumerationRange);
 
        }
        public boolean hasClassification(String classification) {
@@ -75,6 +77,8 @@ public class PropertyInfo {
                .append(requiredValueType)
                .append(", predicate=")
                .append(predicate)
+        .append(", isFunctional=")
+        .append(isFunctional)
                .append(", isHasProperty=")
                .append(isHasProperty)
                .append(", hasEnumerationRange=")
index 2a181674c49a3cdf06f0317bcb382c5bbe002221..90e63e29f639c10cc7d4ec04caf053c0909116e6 100644 (file)
@@ -41,6 +41,8 @@ final public class PropertyInfoRequest extends ResourceRead<PropertyInfo> {
                String name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING);
                if(name != null) name = name.intern();
                
+               boolean isFunctional = graph.isInstanceOf(resource, L0.FunctionalRelation);
+               
                Set<String> classifications = graph.sync(new ClassificationsRequest(graph.getPrincipalTypes(resource)));
                VariableBuilder<?> variableBuilder = graph.getPossibleAdapter(resource, VariableBuilder.class);
                
@@ -88,13 +90,13 @@ final public class PropertyInfoRequest extends ResourceRead<PropertyInfo> {
                                                }
                                        }
                                        
-                                       return PropertyInfo.make(graph, resource, name, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, map, accessor, hasEnumerationRange);
+                                       return PropertyInfo.make(graph, resource, name, isFunctional, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, map, accessor, hasEnumerationRange);
                                        
                                }
                        }
                }
                
-               return PropertyInfo.make(graph, resource, name, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, Collections.<String,Pair<Resource,ChildReference>>emptyMap(), accessor, hasEnumerationRange);
+               return PropertyInfo.make(graph, resource, name, isFunctional, isHasProperty, classifications, variableBuilder, literalRange, requiredDataType, definedUnit, requiredValueType, Collections.<String,Pair<Resource,ChildReference>>emptyMap(), accessor, hasEnumerationRange);
                
        }
        
index 62c7093da11e999d7e22b60a17ccb1221088fe18..7c7412d18bbd17e273541a6cac0c0478e6d37246 100644 (file)
@@ -74,6 +74,7 @@ import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.request.PossibleChild;
 import org.simantics.db.common.request.PossibleIndexRoot;
 import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.utils.CommonDBUtils;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.event.ChangeListener;
 import org.simantics.db.exception.CancelTransactionException;
@@ -353,13 +354,9 @@ public class Layer0Utils {
                throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);
        }
 
-
+       @Deprecated
        public static Type getSCLType(ReadGraph graph, RuntimeEnvironment runtimeEnvironment, String typeText) throws DatabaseException {
-        try {
-                       return Environments.getType(runtimeEnvironment.getEnvironment(), typeText);
-               } catch (SCLExpressionCompilationException e) {
-                       throw new DatabaseException(e);
-               }
+           return CommonDBUtils.getSCLType(graph, runtimeEnvironment, typeText);
        }
 
        public static Type getSCLType(ReadGraph graph, Variable property) throws DatabaseException {
@@ -646,15 +643,14 @@ public class Layer0Utils {
                return graph.getPossibleResource(graph.getURI(root) + suffix);
        }
 
+       @Deprecated
        public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException {
-               return graph.sync(new PossibleChild(resource, name));
+               return CommonDBUtils.getPossibleChild(graph, resource, name);
        }
 
+       @Deprecated
        public static Resource getPossibleChild(ReadGraph graph, Resource resource, Resource type, String name) throws DatabaseException {
-               Resource child = graph.sync(new PossibleChild(resource, name));
-               if(child == null) return null;
-               if(!graph.isInstanceOf(child, type)) return null;
-               return child;
+               return CommonDBUtils.getPossibleChild(graph, resource, type, name);
        }
 
        public static RelationContext relationContext(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {
@@ -1385,7 +1381,31 @@ public class Layer0Utils {
        }
        return result;
     }
+    
+    public static Resource possibleObjectForType(ReadGraph graph, Resource type, Resource relation) throws DatabaseException {
+        PropertyInfo pi = graph.syncRequest(new PropertyInfoRequest(relation));
+        return possibleObjectForType(graph, type, relation, pi.isFunctional);
+    }
 
+    public static Resource possibleObjectForType(ReadGraph graph, Resource type, Resource relation, boolean functional) throws DatabaseException {
+        if(functional) {
+            Layer0 L0 = Layer0.getInstance(graph);
+            Resource result = graph.getPossibleObject(type, relation);
+            if(result != null) return result;
+            for(Resource su : graph.getObjects(L0.Inherits, type)) {
+                Resource r = possibleObjectForType(graph, su, relation);
+                if(r != null) {
+                    if(result != null) return null;
+                    result = r;
+                }
+            }
+            return result;
+        } else {
+            throw new UnsupportedOperationException("asd");
+        }
+    }
+
+    
     public static Resource getPossiblePredicateByNameFromType(ReadGraph graph, Resource type, String name) throws DatabaseException {
        Map<String,Resource> domain = getDomainOf(graph, type);
        return domain.get(name); 
index 673eeaee5847e0bbc2c9dfba59f0038cc2143e0d..47c829cd86443ae0d04bfaf5803da028dabbc5d7 100644 (file)
@@ -1,7 +1,6 @@
 package org.simantics.db.layer0.validation;
 
-import gnu.trove.set.hash.THashSet;
-
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -18,6 +17,8 @@ import org.simantics.db.layer0.util.DomainProcessor3;
 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
 import org.simantics.layer0.Layer0;
 
+import gnu.trove.set.hash.THashSet;
+
 public class ValidationUtils {
 
     /**
@@ -62,7 +63,7 @@ public class ValidationUtils {
         return validateConstraints(graph, r, null);
     }
 
-    public static Set<Issue> validateConstraintsForDomain(ReadGraph graph, Resource r) throws DatabaseException {
+    public static List<Issue> validateConstraintsForDomain(ReadGraph graph, Resource r) throws DatabaseException {
         Set<Issue> result = null;
 
         DomainProcessor3 dp = ModelTransferableGraphSourceRequest.getDomainOnly(graph, null, r);
@@ -75,7 +76,7 @@ public class ValidationUtils {
             }
         }
 
-        return result != null ? result : Collections.<Issue>emptySet();
+        return result != null ? new ArrayList(result) : Collections.<Issue>emptyList();
     }
 
 }
diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/ResourceX.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/ResourceX.java
new file mode 100644 (file)
index 0000000..db3bd01
--- /dev/null
@@ -0,0 +1,33 @@
+package org.simantics.db.layer0.variable;
+
+import org.simantics.db.Resource;
+
+public class ResourceX implements VariableOrResource {
+    
+    public final Resource value;
+
+    public ResourceX(Resource value) {
+        this.value = value;
+    }
+    
+    @Override
+    public String toString() {
+        return "ResourceX " + value;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if(this == obj)
+            return true;
+        if(obj == null || obj.getClass() != getClass())
+            return false;
+        ResourceX other = (ResourceX)obj;
+        return value == null ? other.value == null : value.equals(other.value);
+    }
+    
+    @Override
+    public int hashCode() {
+        return 31 * (value == null ? 0 : value.hashCode()) + 13532;
+    }
+    
+}
index ed58556c7e570814bd4ce25e5473a6821f2c33bc..7927614cd37f9779292ee4ace98e5fd4ba7f00f0 100644 (file)
@@ -38,7 +38,7 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
     private static final Logger LOGGER = LoggerFactory.getLogger(StandardGraphPropertyVariable.class);
     
        protected static final PropertyInfo NO_PROPERTY = new PropertyInfo(null, null,
-                       false, Collections.<String> emptySet(), null, null, null, null, null, null,
+                       false, false, Collections.<String> emptySet(), null, null, null, null, null, null,
                        Collections.<String, Pair<Resource, ChildReference>> emptyMap(),
                        null, false);
 
diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableOrResource.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableOrResource.java
new file mode 100644 (file)
index 0000000..cdcfd8b
--- /dev/null
@@ -0,0 +1,23 @@
+package org.simantics.db.layer0.variable;
+
+import org.simantics.db.Resource;
+
+public interface VariableOrResource {
+
+    public static VariableOrResource make(Resource value) {
+        return new ResourceX(value);
+    }
+    
+    public static VariableOrResource make(Variable value) {
+        return new VariableX(value);
+    }
+
+    public static VariableOrResource make(Object value) {
+        if(value instanceof Resource)
+            return make((Resource)value);
+        if(value instanceof Variable)
+            return make((Variable)value);
+        throw new IllegalArgumentException("VariableOrResource acccepts only Variable or Resource, got " + value + " with class " + value.getClass().getName());
+    }
+
+}
diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableX.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/VariableX.java
new file mode 100644 (file)
index 0000000..24d775a
--- /dev/null
@@ -0,0 +1,31 @@
+package org.simantics.db.layer0.variable;
+
+public class VariableX implements VariableOrResource {
+    
+    public final Variable value;
+
+    public VariableX(Variable value) {
+        this.value = value;
+    }
+    
+    @Override
+    public String toString() {
+        return "VariableX " + value;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if(this == obj)
+            return true;
+        if(obj == null || obj.getClass() != getClass())
+            return false;
+        VariableX other = (VariableX)obj;
+        return value == null ? other.value == null : value.equals(other.value);
+    }
+    
+    @Override
+    public int hashCode() {
+        return 31 * (value == null ? 0 : value.hashCode()) + 13532;
+    }
+    
+}
index ecf2439e8be4fdbbd352a8c17f125f9cae7141e7..75fdb8b6f209d4850f4bf5fa55b4b1ce2872ef6f 100644 (file)
@@ -5,9 +5,9 @@ Bundle-SymbolicName: org.simantics.db.management
 Bundle-Version: 1.1.0.qualifier
 Bundle-Activator: org.simantics.db.management.internal.Activator
 Bundle-Vendor: VTT Technical Research Centre of Finland
-Require-Bundle: org.simantics.db.services;bundle-version="0.8.0",
- org.simantics.db.procore;bundle-version="0.8.0",
- org.eclipse.core.runtime;bundle-version="3.5.0"
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0",
+ org.simantics.utils;bundle-version="1.1.0",
+ org.simantics.layer0;bundle-version="1.1.0"
 Bundle-ActivationPolicy: lazy
 Export-Package: org.simantics.db.management,
  org.simantics.db.management.discovery
index dae8bea7545184cbf7faf82dbc76f6ababa8ab35..79df14026cc6a9c646ec1871b6433ebc8ab11e1f 100644 (file)
@@ -16,19 +16,14 @@ import java.util.Arrays;
 import java.util.UUID;
 import java.util.concurrent.TimeoutException;
 
-import org.eclipse.core.runtime.IStatus;
 import org.simantics.db.Disposable;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Session;
 import org.simantics.db.VirtualGraph;
-import org.simantics.db.common.processor.MergingDelayedWriteProcessor;
-import org.simantics.db.common.processor.MergingGraphRequestProcessor;
-import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.management.internal.Activator;
+import org.simantics.db.request.Read;
 import org.simantics.db.service.LifecycleSupport;
 import org.simantics.db.service.VirtualGraphSupport;
-import org.simantics.db.services.GlobalServiceInitializer;
 import org.simantics.layer0.Layer0;
 import org.simantics.utils.datastructures.disposable.DisposeState;
 import org.simantics.utils.datastructures.disposable.IDisposable;
@@ -52,10 +47,6 @@ public class SessionContext extends HintContext implements ISessionContext, Disp
 
     private Session                 session;
 
-    private boolean                 servicesRegistered       = false;
-
-    private IStatus                 servicesRegisteredStatus = null;
-
     public static SessionContext create(Session session, boolean initialize) throws DatabaseException {
         return new SessionContext(session, initialize);
     }
@@ -67,33 +58,19 @@ public class SessionContext extends HintContext implements ISessionContext, Disp
     }
 
     private void initializeSession(Session s) throws DatabaseException {
-        s.registerService(MergingGraphRequestProcessor.class, new MergingGraphRequestProcessor("SessionService", s, 20));
-        s.registerService(MergingDelayedWriteProcessor.class, new MergingDelayedWriteProcessor(s, 20));
         s.registerService(VirtualGraph.class, s.getService(VirtualGraphSupport.class).getMemoryPersistent(UUID.randomUUID().toString()));
 
         // Builtins needs to be initialized for the new session before
         // anything useful can be done with it.
-        s.syncRequest(new ReadRequest() {
+        s.syncRequest(new Read<Object>() {
             @Override
-            public void run(ReadGraph g) {
+            public Object perform(ReadGraph g) {
                 // Registers Builtins with the ServiceLocator of the Graph's session.
                Layer0.getInstance(g);
+               return null;
             }
         });
-    }
-
-    public void registerServices() {
-        if (servicesRegistered)
-            return;
-
-        // Register any services available for the SessionLocator of the new
-        // Session.
-        servicesRegisteredStatus = new GlobalServiceInitializer().initialize(session);
-        if (!servicesRegisteredStatus.isOK()) {
-            Activator.getDefault().getLog().log(servicesRegisteredStatus);
-        }
-
-        servicesRegistered = true;
+        
     }
 
 //    @Override
index 81967124d6562b78919ea8e994219eb7ebc7a57b..8691c0a03f28695f2eb4ecdca4d4b44738e887bf 100644 (file)
@@ -11,7 +11,6 @@
  *******************************************************************************/
 package org.simantics.db.management.internal;
 
-import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.Properties;
@@ -21,8 +20,6 @@ import org.osgi.framework.Bundle;
 import org.simantics.db.SessionManager;
 import org.simantics.utils.FileUtils;
 
-import fi.vtt.simantics.procore.SessionManagerSource;
-
 /**
  * Complete hack for the time being. Simply provides the SessionManager behind
  * procore's SessionManagerSource with proper initialization.
@@ -40,12 +37,12 @@ public final class SessionManagerProvider {
         return provider;
     }
 
-    public SessionManager getSessionManager() throws IOException {
-        if (sessionManager == null) {
-            sessionManager = SessionManagerSource.getSessionManager(loadProperties());
-        }
-        return sessionManager;
-    }
+//    public SessionManager getSessionManager() throws IOException {
+//        if (sessionManager == null) {
+//            sessionManager = SessionManagerSource.getSessionManager(loadProperties());
+//        }
+//        return sessionManager;
+//    }
 
     private Properties loadProperties() {
         Bundle procore = Platform.getBundle("org.simantics.db.procore");
index 7403f3d7004f475e4de2bd17d7006cef5739d349..bb78bf41ee57507907c197c3fa84286e0bcded56 100644 (file)
@@ -6,9 +6,13 @@ Bundle-Version: 1.1.0.qualifier
 Bundle-Vendor: VTT Technical Research Centre of Finland
 Require-Bundle: org.eclipse.core.runtime,
  gnu.trove3,
- org.simantics.layer0.utils;bundle-version="1.1.0",
  org.simantics.layer0x.ontology;bundle-version="1.0.0",
- org.slf4j.api;bundle-version="1.7.25"
+ org.slf4j.api;bundle-version="1.7.25",
+ org.simantics.utils;bundle-version="1.1.0",
+ org.simantics.db;bundle-version="1.1.0",
+ org.simantics.scl.reflection,
+ org.simantics.db.common;bundle-version="1.1.0",
+ org.simantics.layer0.utils
 Export-Package: org.simantics.db.services,
  org.simantics.db.services.activation,
  org.simantics.db.services.adaption
index 578b42a61d885d13cfb06e20e7c31436d00a6af2..fe9bab55201f188be514d33c2d21e702586be0a1 100644 (file)
@@ -36,6 +36,7 @@ import org.simantics.db.adaption.AdapterInstaller;
 import org.simantics.db.adaption.AdaptionService;
 import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Read;
 import org.simantics.db.services.adaption.reflection.AdaptingDynamicAdapter2;
 import org.simantics.db.services.adaption.reflection.AtMostOneRelatedResource2;
 import org.simantics.db.services.adaption.reflection.ConstantAdapter;
@@ -337,9 +338,9 @@ public class AdapterRegistry2 {
     }
 
     public void updateAdaptionService(Session s, final AdaptionService service) throws DatabaseException {
-        s.syncRequest(new ReadRequest() {
+        s.syncRequest(new Read() {
             @Override
-            public void run(ReadGraph g) {
+            public Object perform(ReadGraph g) {
                 for(AdapterInstaller t : installerSources.keySet()) {
                     try {
                         t.install(g, service);
@@ -347,6 +348,7 @@ public class AdapterRegistry2 {
                         AdapterRegistry2.this.handleException(e, t);
                     }
                 }
+                return null;
             }
         });
     }
index 187fc52199a390f37b68b3a48a940d20faa4d359..870b17e78e6132439e450b27ef42053bf03d99f0 100644 (file)
@@ -18,9 +18,9 @@ import java.util.Arrays;
 import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.adaption.Adapter;
-import org.simantics.db.common.request.AsyncReadRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.request.AsyncRead;
 
 public class ReflectionAdapter2<T> implements Adapter<T, Resource> {
 
@@ -78,35 +78,36 @@ public class ReflectionAdapter2<T> implements Adapter<T, Resource> {
                
        } else {
        
-            g.asyncRequest(new AsyncReadRequest() {
-    
+            g.asyncRequest(new AsyncRead() {
+                
                 @Override
-                public void run(AsyncReadGraph graph) {
-                       
+                public void perform(AsyncReadGraph graph, AsyncProcedure p) {
+                    
                     Object[] args = new Object[parameters.length];
                     try {
-                       for(int i=0;i<parameters.length;++i)
-                               args[i] = parameters[i].adapt(graph, r);
-                       procedure.execute(graph, constructor.newInstance(args));
-                               } catch (IllegalArgumentException e) {
-                                   procedure.exception(g, e);
-                                       e.printStackTrace();
-                               } catch (InstantiationException e) {
-                        procedure.exception(g, e);
-                                       e.printStackTrace();
-                               } catch (IllegalAccessException e) {
-                        procedure.exception(g, e);
-                                       e.printStackTrace();
-                               } catch (InvocationTargetException e) {
-                        procedure.exception(g, e.getCause());
-                                       e.getCause().printStackTrace();
-                               } catch (DatabaseException e) {
-                        procedure.exception(g, e);
-                                       e.printStackTrace();
-                               } catch (Throwable t) {
-                                   procedure.exception(g, t);
-                                   t.printStackTrace();
-                               }
+                        for(int i=0;i<parameters.length;++i)
+                            args[i] = parameters[i].adapt(graph, r);
+                        p.execute(graph, constructor.newInstance(args));
+                    } catch (IllegalArgumentException e) {
+                        p.exception(g, e);
+                        e.printStackTrace();
+                    } catch (InstantiationException e) {
+                        p.exception(g, e);
+                        e.printStackTrace();
+                    } catch (IllegalAccessException e) {
+                        p.exception(g, e);
+                        e.printStackTrace();
+                    } catch (InvocationTargetException e) {
+                        p.exception(g, e.getCause());
+                        e.getCause().printStackTrace();
+                    } catch (DatabaseException e) {
+                        p.exception(g, e);
+                        e.printStackTrace();
+                    } catch (Throwable t) {
+                        p.exception(g, t);
+                        t.printStackTrace();
+                    }
+                    
                 }
                 
                 @Override
@@ -114,7 +115,7 @@ public class ReflectionAdapter2<T> implements Adapter<T, Resource> {
                        return "ReflectionAdapter$1" + constructor + "$" + Arrays.toString(parameters);
                 }
                 
-            });
+            }, procedure);
         
        }
         
index 4845558ea2b21bb1a72545af5b2957f347f22496..56b2695d883ef4fcb5823e874cc7d03f9d1d8d00 100644 (file)
@@ -100,6 +100,65 @@ Documentation.child10 : L0.Template
       Documentation.Relations.parent %connection
     %connection : STR.Connection
 
+Documentation.child1_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part1.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
+
+Documentation.child2_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part2.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
+
+Documentation.child3_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part3.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
+
+Documentation.child4_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part4.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
+
+Documentation.child5_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part5.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
+
+Documentation.child6_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part6.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
+
+Documentation.child7_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part7.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
+
+Documentation.child8_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part8.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
+
+Documentation.child9_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part9.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
+
+Documentation.child10_ : L0.Template
+  @template %parent %child
+    _ : STR.Connection
+     Documentation.Relations.part10.Inverse %parent
+     Documentation.Relations.parent.Inverse %child
 
 Documentation.singleData : L0.Template
   @template %commandEvent %defVar %dataSource %eventSource %eventRelation %sourceName %targetName %DataSourceConn %DataTargetConn %EventConn
index a90a24bcb62c30c55cad163eb3d242f869bec690..d676e2a3b2a296bacb86094ebec20bb6695ec510 100644 (file)
@@ -122,9 +122,9 @@ importJava "org.simantics.document.server.Functions" where
     readEventHandler :: Variable -> (Variable -> (String -> Maybe String) -> <ReadGraph> String) -> <ReadGraph> AbstractEventHandler
     eventHandler :: ((String -> Maybe String) -> String) -> <ReadGraph> AbstractEventHandler
 
-    readEventHandler2 :: (CommandContext -> <ReadGraph> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
-    writeEventHandler2 :: (CommandContext -> <WriteGraph> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
-    eventHandler2 :: (CommandContext -> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
+    readEventHandler2 :: (CommandContext -> <ReadGraph,Proc> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
+    writeEventHandler2 :: (CommandContext -> <WriteGraph,Proc> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
+    eventHandler2 :: (CommandContext -> <Proc> Maybe CommandResult) -> <ReadGraph> AbstractEventHandler
     
     responseHandler :: Variable -> String -> <ReadGraph> AbstractEventHandler
 
@@ -147,6 +147,9 @@ importJava "org.simantics.document.server.Functions" where
     compileDocumentSCLHandlerValueExpression :: Variable -> <ReadGraph> String
 
     primitiveProperties :: <Proc> DocumentProperties
+
+contextVariable :: Variable -> <ReadGraph> Variable
+contextVariable var = propertyValue (variableParent var) "input"
     
 propertyValueCached :: Serializable a => Typeable a => Variable -> String -> <ReadGraph> a
 propertyValueCached var prop = propertyValueCached_ var prop binding
index b971fef4c6b6ca8540d8cc257c7166db1d0c7f04..5a024ec393090d58d28b7014048b5935e3580371 100644 (file)
@@ -1,11 +1,14 @@
 package org.simantics.document.server;
 
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextMutable;
+
 public interface IEventCommand {
     
     public void setNext(IEventCommand command);
     public IEventCommand getNext();    
-    public void handleCommand();
-    public void commandSuccess();
+    public CommandContext handleCommand(CommandContextMutable context);
+    public CommandContext commandSuccess(CommandContextMutable context);
     public void commandError(String errorMessage);
 
 }
index f47c0c5c38ff53eade8eaa9834d641aa4e0cba06..ddfb6ea9ed89b91ebb4ac31a37c6c9ea2c7340c1 100644 (file)
@@ -12,6 +12,10 @@ public class Command implements ICommand {
 
     public Command() {}
     
+    public Command(String command) {
+        this.command = command;
+    }
+
     public Command(String targetId, String trigger, String command, CommandContext constants) {
         this.targetId = targetId;
         this.trigger = trigger;
index 1235d527c4fdac3e2b2dea298734780bd49e1124..92e8b293db06f00e82571716d7e34190bc241242 100644 (file)
@@ -5,6 +5,8 @@ import java.util.TreeMap;
 
 import org.simantics.document.server.IEventCommand;
 import org.simantics.document.server.JSONObject;
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.ICommand;
 
 public class WidgetData {
        
@@ -67,12 +69,12 @@ public class WidgetData {
     }
     
     @SuppressWarnings({ "unchecked", "rawtypes" })
-    public IEventCommand eventCommand(String command) {
+    public IEventCommand eventCommand(ICommand command, CommandContext c) {
         if(object == null)
             return null;
         WidgetManager manager = document.getManager(object);
         if(manager != null)
-            return manager.eventCommand(document, object, widget, command); 
+            return manager.eventCommand(document, object, widget, command, c); 
         else
             return null;
     }
index 8474bfd15b1b14e3dcbda4f74c38fdc2d8955662..09338b50df288663e2d9e979aa6c1e6267ea3ad4 100644 (file)
@@ -4,6 +4,8 @@ import java.util.TreeMap;
 
 import org.simantics.document.server.IEventCommand;
 import org.simantics.document.server.JSONObject;
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.ICommand;
 
 public interface WidgetManager<D extends Document, W> {
 
@@ -13,7 +15,7 @@ public interface WidgetManager<D extends Document, W> {
        
        public void updateChildren(D document, JSONObject object, W widget, TreeMap<String, WidgetData> childMap);
        
-    public IEventCommand eventCommand(D document, JSONObject object, W widget, String command);
+    public IEventCommand eventCommand(D document, JSONObject object, W widget, ICommand command, CommandContext context);
        
        public String getProperty(D document, JSONObject object, W widget, String property);
        
index 41183050f2c969c4833994eddc4509a508afdaaa..e0db02e8bba21146ecd22ca678e88e0cde815f4b 100644 (file)
@@ -1,6 +1,7 @@
 package org.simantics.document.swt.core;
 
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.jface.viewers.ISelectionProvider;
@@ -8,8 +9,12 @@ import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.ui.IWorkbenchSite;
 import org.simantics.document.server.client.Document;
-import org.simantics.document.server.handler.AbstractEventHandler;
+import org.simantics.document.server.client.WidgetData;
+import org.simantics.document.server.io.AbstractEventHandler;
 import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextMutable;
+import org.simantics.document.server.io.ICommand;
+import org.simantics.utils.datastructures.Pair;
 
 public interface SWTDocument extends Document {
 
@@ -19,7 +24,8 @@ public interface SWTDocument extends Document {
        ISelectionProvider getSelectionProvider();
        Color getColor(org.simantics.datatypes.literal.RGB.Integer bean);
        Font getFont(org.simantics.datatypes.literal.Font bean);
-       void post(AbstractEventHandler handler, CommandContext parameters);
+    void post(AbstractEventHandler handler, CommandContextMutable context);
+    CommandContext handleCommands(List<Pair<WidgetData, ICommand>> data, CommandContextMutable context, Object component);
        void layout();
        
     void displayError(String error);
index 58c280595b0ac8fd31de57ca3d5cd6a45fdbaebd..090448db5d6a1e43eaf606589a337ef174bb5c8c 100644 (file)
@@ -1,8 +1,10 @@
 package org.simantics.document.swt.core;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.jface.layout.GridDataFactory;
@@ -15,16 +17,21 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.IWorkbenchSite;
 import org.simantics.db.common.utils.Logger;
+import org.simantics.document.server.IEventCommand;
 import org.simantics.document.server.JSONObject;
 import org.simantics.document.server.client.DocumentClient;
 import org.simantics.document.server.client.WidgetData;
 import org.simantics.document.server.client.WidgetMapping;
-import org.simantics.document.server.handler.AbstractEventHandler;
+import org.simantics.document.server.io.AbstractEventHandler;
 import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextMutable;
+import org.simantics.document.server.io.ICommand;
+import org.simantics.document.server.io.JSONObjectUtils;
 import org.simantics.document.swt.core.base.WidgetContainer;
 import org.simantics.document.swt.core.widget.FillComposite;
 import org.simantics.ui.colors.Colors;
 import org.simantics.ui.fonts.Fonts;
+import org.simantics.utils.datastructures.Pair;
 import org.simantics.utils.threads.IThreadWorkQueue;
 import org.simantics.utils.threads.SWTThread;
 
@@ -99,9 +106,10 @@ public class SWTDocumentClient extends DocumentClient implements SWTDocument {
        }
        
        @Override
-       public void post(final AbstractEventHandler handler, CommandContext parameters) {
+       public void post(AbstractEventHandler handler, CommandContextMutable parameters) {
                handler.handle(parameters);
        }
+       
 
        @Override
        protected void updateDocument(Collection<JSONObject> objects) {
@@ -141,6 +149,36 @@ public class SWTDocumentClient extends DocumentClient implements SWTDocument {
                
        }
        
+       @Override
+       public CommandContext handleCommands(List<Pair<WidgetData, ICommand>> data, CommandContextMutable context, Object component) {   
+
+           // Build a linked list of commands
+
+           ArrayList<IEventCommand> commands = new ArrayList<IEventCommand>();
+           for(Pair<WidgetData, ICommand> pair : data) {
+               WidgetData d = pair.first;
+
+               ICommand c = pair.second;
+               IEventCommand p = d.eventCommand(c, null);
+//             if(component != null && p != null)
+//                 p.setTrigger(component);
+               if(p != null) {
+                   if(!commands.isEmpty())
+                       commands.get(commands.size()-1).setNext(p);
+                   commands.add(p);
+               }
+           }
+
+           // Execute the first command, the linked list handles the rest of them
+           if(!commands.isEmpty()) {
+               try {
+                   commands.get(0).handleCommand(context);
+               } finally {
+               }
+           }
+           return context;
+       }
+
        @Override
        public void layout() {
                requireLayout = true;
index 468bf7bdaec4295d561e25b2f32e1212dcc06eef..9b81f9eea61e9ec835c58f045808d4196e1c318a 100644 (file)
@@ -1,6 +1,9 @@
 package org.simantics.document.swt.core;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.swt.widgets.Composite;
@@ -8,8 +11,11 @@ import org.eclipse.swt.widgets.Control;
 import org.simantics.document.server.JSONObject;
 import org.simantics.document.server.client.CommandMapping;
 import org.simantics.document.server.client.CommandMappingImpl;
+import org.simantics.document.server.client.Document;
+import org.simantics.document.server.client.WidgetData;
 import org.simantics.document.server.client.WidgetMapping;
 import org.simantics.document.server.client.WidgetMappingImpl;
+import org.simantics.document.server.io.ICommand;
 import org.simantics.document.swt.core.base.ScrolledCompositeContent;
 import org.simantics.document.swt.core.widget.BrowserWidget;
 import org.simantics.document.swt.core.widget.ButtonWidget;
@@ -23,6 +29,7 @@ import org.simantics.document.swt.core.widget.LabelWidget;
 import org.simantics.document.swt.core.widget.SCLTextEditor;
 import org.simantics.document.swt.core.widget.ScrolledCompositeWidget;
 import org.simantics.document.swt.core.widget.TrackedTextWidget;
+import org.simantics.utils.datastructures.Pair;
 
 public class SWTViews {
 
@@ -58,6 +65,7 @@ public class SWTViews {
             
             commandMapping = new CommandMappingImpl();
             commandMapping.register("Button", new ButtonWidget.ButtonCommandManager());
+            commandMapping.register("Explorer", new Explorer.ExplorerCommandManager());
             
         }
         
@@ -65,6 +73,22 @@ public class SWTViews {
         
     }
 
+    public static List<Pair<WidgetData, ICommand>> getTriggeredCommands(Document document, Collection<ICommand> commands, String trigger) {
+        // Nulls should not get this far
+        assert(commands != null);
+        List<Pair<WidgetData, ICommand>> data = new ArrayList<Pair<WidgetData, ICommand>>();
+        for(ICommand c : commands) {
+            if(c.getCommand() == null || c.getTargetId() == null || c.getTrigger() == null)
+                continue;
+            if(trigger.equals(c.getTrigger())) {
+                WidgetData wd = document.getWidgetData().get(c.getTargetId());
+                if(wd != null)
+                    data.add(new Pair<WidgetData, ICommand>(wd, c));
+            }
+        }
+        return data;
+    }
+
        public static void notifyScrolledComposite(Control c) {
                if(c instanceof ScrolledCompositeContent) {
                        ScrolledCompositeContent content = (ScrolledCompositeContent)c;
index 3bd0364e7e7c19a27e7661b4bf299d9797a6c47a..57a2fbbe8312e0e3bb397b194d7f2248172e10b6 100644 (file)
@@ -1,6 +1,8 @@
 package org.simantics.document.swt.core.base;
 
 import org.simantics.document.server.IEventCommand;
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextMutable;
 import org.simantics.document.swt.core.SWTDocument;
 
 public abstract class AbstractEventCommand implements IEventCommand {
@@ -23,9 +25,10 @@ public abstract class AbstractEventCommand implements IEventCommand {
     }
     
     @Override
-    public void commandSuccess() {
+    public CommandContext commandSuccess(CommandContextMutable context) {
         if(next != null)
-            next.handleCommand();
+            return next.handleCommand(context);
+        return context;
     }
 
     @Override
index ff6d4fd13d5aa6d20e0894339c02bee95fc68569..2537f9de946a0714b3ce866083aa0bf14d622f0f 100644 (file)
@@ -1,40 +1,37 @@
 package org.simantics.document.swt.core.base;
 
-import java.util.Map;
-
-import org.simantics.document.server.handler.AbstractEventHandler;
+import org.simantics.document.server.io.AbstractEventHandler;
 import org.simantics.document.server.io.CommandContext;
-import org.simantics.document.server.io.CommandContextImpl;
+import org.simantics.document.server.io.CommandContextMutable;
 import org.simantics.document.swt.core.SWTDocument;
 
 public class PostEventCommand extends AbstractEventCommand {
     
     private AbstractEventHandler handler;
-    private CommandContextImpl parameters;
+    private CommandContextMutable context;
     
-    public PostEventCommand(SWTDocument document, AbstractEventHandler handler, Map<String, String> parameters) {
-        this(document, handler, parameters, null);
+    public PostEventCommand(SWTDocument document, AbstractEventHandler handler, CommandContextMutable context) {
+        this(document, handler, context, null);
     }
     
-    public PostEventCommand(SWTDocument document, AbstractEventHandler handler, Map<String, String> parameters, PostEventCommand next) {
+    public PostEventCommand(SWTDocument document, AbstractEventHandler handler, CommandContextMutable context, PostEventCommand next) {
         super(document);
         this.handler = handler;
-        this.parameters = new CommandContextImpl();
-        for(Map.Entry<String, String> entry : parameters.entrySet()) {
-               this.parameters.putString(entry.getKey(), entry.getValue());
-        }
+        this.context = context;
         this.next = next;
     }
 
     @Override
-    public void handleCommand() {
-        document.post(handler, parameters);
+    public CommandContext handleCommand(CommandContextMutable context) {
+        document.post(handler, context);
+        return context;
     }
 
     @Override
-    public void commandSuccess() {
+    public CommandContext commandSuccess(CommandContextMutable context) {
         if(next != null)
-            next.handleCommand();
+            return next.handleCommand(context);
+        return context;
     }
 
     @Override
index 1c329706107d98a4eada3e872ebb116c340541da..c8593c604e3a5f50daee13c8f718c72a116812c3 100644 (file)
@@ -1,9 +1,23 @@
 package org.simantics.document.swt.core.base;
 
+import java.awt.Component;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
 import org.simantics.document.server.IEventCommand;
 import org.simantics.document.server.JSONObject;
+import org.simantics.document.server.client.Document;
+import org.simantics.document.server.client.WidgetData;
 import org.simantics.document.server.client.WidgetManager;
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextImpl;
+import org.simantics.document.server.io.CommandContextMutable;
+import org.simantics.document.server.io.ICommand;
+import org.simantics.document.server.io.JSONObjectUtils;
 import org.simantics.document.swt.core.SWTDocument;
+import org.simantics.document.swt.core.SWTViews;
+import org.simantics.utils.datastructures.Pair;
 
 public abstract class PropertyWidgetManager<W> implements WidgetManager<SWTDocument, W> {
        
@@ -13,8 +27,24 @@ public abstract class PropertyWidgetManager<W> implements WidgetManager<SWTDocum
        }
        
        @Override
-       public IEventCommand eventCommand(SWTDocument document, JSONObject object, W widget, String command) {
+       public IEventCommand eventCommand(SWTDocument document, JSONObject object, W widget, ICommand command, CommandContext context) {
            return null;
        }
 
+//    public static CommandContext sendEvent(SWTDocument document, Object source, String event, Object target, CommandContextMutable context) {
+//        return sendEvent(document, document.find(source), event, target, context);
+//    }
+    
+    public static CommandContext sendEvent(SWTDocument document, WidgetData wd, String event, Object target, CommandContextMutable context) {
+        Collection<ICommand> commands = JSONObjectUtils.getCommands(wd.object);
+
+        if(context == null) context = new CommandContextImpl();
+        context.putValue("event", event);
+        
+        List<Pair<WidgetData, ICommand>> data = SWTViews.getTriggeredCommands(document, commands, "eventOut");
+    
+        return document.handleCommands(data, context, wd.widget);
+
+    }
+       
 }
index 303460deab8fc6b1474887e4bc73c0453a08d7e5..2f9a33bfa628bfd7b4a83847c9396ac1a7193331 100644 (file)
@@ -1,19 +1,25 @@
 package org.simantics.document.swt.core.widget;
 
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
+import java.util.List;
 
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.events.SelectionListener;
-import org.simantics.document.server.IEventCommand;
 import org.simantics.document.server.client.WidgetData;
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextImpl;
+import org.simantics.document.server.io.CommandContextMutable;
+import org.simantics.document.server.io.ICommand;
 import org.simantics.document.swt.core.SWTDocument;
+import org.simantics.document.swt.core.base.PropertyWidgetManager;
+import org.simantics.utils.datastructures.Pair;
 
 public class ButtonSelectionListener implements SelectionListener {
     
-    private LinkedHashMap<WidgetData, String> data;
+    private WidgetData wd;
+    private List<Pair<WidgetData, ICommand>> data;
     
-    public ButtonSelectionListener(LinkedHashMap<WidgetData, String> data) {
+    public ButtonSelectionListener(WidgetData wd, List<Pair<WidgetData, ICommand>> data) {
+        this.wd = wd;
         this.data = data;
     }
 
@@ -24,27 +30,37 @@ public class ButtonSelectionListener implements SelectionListener {
 
     @Override
     public void widgetDefaultSelected(SelectionEvent e) {
-        SWTDocument document = null;
-        // Build a linked list of commands
-        ArrayList<IEventCommand> commands = new ArrayList<IEventCommand>();
-        for(WidgetData d : data.keySet()) {
-            document = (SWTDocument)d.document; // assume that all widgets are from the same document
-            IEventCommand p = d.eventCommand(data.get(d));
-            if(p != null) {
-                if(!commands.isEmpty())
-                    commands.get(commands.size()-1).setNext(p);
-                commands.add(p);
+//        SWTDocument document = null;
+//        // Build a linked list of commands
+//        ArrayList<IEventCommand> commands = new ArrayList<IEventCommand>();
+//        for(WidgetData d : data.keySet()) {
+//            document = (SWTDocument)d.document; // assume that all widgets are from the same document
+//            IEventCommand p = d.eventCommand(data.get(d));
+//            if(p != null) {
+//                if(!commands.isEmpty())
+//                    commands.get(commands.size()-1).setNext(p);
+//                commands.add(p);
+//            }
+            
+            CommandContextMutable context = new CommandContextImpl();
+            context.putValue("event", "onPress");
+            
+            if(!data.isEmpty()) {
+                ((SWTDocument)wd.document).handleCommands(data, context, e.widget);
             }
-        }
+            
+            CommandContext ret = PropertyWidgetManager.sendEvent((SWTDocument)wd.document, wd, "onPress", e.widget, context);
+
+//        }
 
         // empty errors
 //        if(document != null)
 //            document.displayError("");
 
         // Execute the first command, the linked list handles the rest of them
-        if(!commands.isEmpty())
-            commands.get(0).handleCommand();
-    
+//        if(!commands.isEmpty())
+//            commands.get(0).handleCommand();
+//    
     }
     
 }
\ No newline at end of file
index 384ef88cd8638f23e0f17dec7005cedc52b7ca49..0142fdf6b6fdcb8b260891e513151a8fba4950d0 100644 (file)
@@ -1,11 +1,9 @@
 package org.simantics.document.swt.core.widget;
 
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionListener;
@@ -17,11 +15,18 @@ import org.simantics.document.server.bean.Command;
 import org.simantics.document.server.client.CommandManager;
 import org.simantics.document.server.client.WidgetData;
 import org.simantics.document.server.handler.AbstractEventHandler;
-import org.simantics.document.server.handler.EventHandler;
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextImpl;
+import org.simantics.document.server.io.CommandContextMutable;
+import org.simantics.document.server.io.ICommand;
+import org.simantics.document.server.io.JSONObjectUtils;
 import org.simantics.document.swt.core.SWTDocument;
+import org.simantics.document.swt.core.SWTViews;
 import org.simantics.document.swt.core.base.LeafWidgetManager;
 import org.simantics.document.swt.core.base.PostEventCommand;
 import org.simantics.document.swt.core.base.WidgetContainer;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.ui.SWTUtils;
 
 public class ButtonWidget extends LeafWidgetManager<Button> {
 
@@ -55,23 +60,13 @@ public class ButtonWidget extends LeafWidgetManager<Button> {
         public Collection<Object> updateCommandListeners(final SWTDocument document, final JSONObject object,
                 WidgetContainer<Button> container) {
             
-            List<Command> commands = object.getJSONField("commands");
+            WidgetData wd = document.getWidget(JSONObjectUtils.getId(object));
+            List<ICommand> commands = object.getJSONField("commands");
             HashSet<Object> listeners = new HashSet<Object>();
-            LinkedHashMap<WidgetData, String> data = new LinkedHashMap<WidgetData, String>();
-            if(commands != null) {
-                   for(Command c : commands) {
-                       if(c.getCommand() == null || c.getTargetId() == null || c.getTrigger() == null)
-                           continue;
-                       String trigger = c.getTrigger();
-                       if("click".equals(trigger)) {
-                           WidgetData wd = document.getWidgetData().get(c.getTargetId());
-                           if(wd != null)
-                               data.put(wd, c.getCommand());
-                       }
-                   }
-            }
-            data.put(document.getWidgetData().get(object.getId()), "onPress");
-            SelectionListener listener = new ButtonSelectionListener(data);
+            List<Pair<WidgetData, ICommand>> data = new ArrayList<>();
+            data.addAll(SWTViews.getTriggeredCommands(document, commands, "eventOut"));
+            data.add(new Pair<WidgetData, ICommand>(wd, new Command("onPress")));
+            SelectionListener listener = new ButtonSelectionListener(wd, data);
             Button button = container.getControl();
             if(!button.isDisposed()) {
                button.addSelectionListener(listener);
@@ -92,11 +87,11 @@ public class ButtonWidget extends LeafWidgetManager<Button> {
     }
 
     @Override
-    public IEventCommand eventCommand(SWTDocument document, JSONObject object, WidgetContainer widget, String command) {
-        if("onPress".equals(command)) {
+    public IEventCommand eventCommand(SWTDocument document, JSONObject object, WidgetContainer widget, ICommand command, CommandContext p) {
+        if("onPress".equals(command.getCommand())) {
+            CommandContextMutable context = new CommandContextImpl().merge(p);
             AbstractEventHandler onPress = object.getJSONField("onPress");
-            Map<String, String> data = Collections.emptyMap();
-            return new PostEventCommand(document, onPress, data);
+            return new PostEventCommand(document, onPress, context);
         }
         return null;
     }  
index 23311d93c18a00757af97dfea980ea379c513fcc..6eb69541860798def6fd472443cc8595a9cbece6 100644 (file)
@@ -1,6 +1,5 @@
 package org.simantics.document.swt.core.widget;
 
-import java.util.HashMap;
 import java.util.List;
 import java.util.TreeMap;
 
@@ -10,6 +9,10 @@ import org.simantics.document.server.bean.DataDefinition;
 import org.simantics.document.server.client.WidgetData;
 import org.simantics.document.server.client.WidgetManager;
 import org.simantics.document.server.handler.AbstractEventHandler;
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextImpl;
+import org.simantics.document.server.io.CommandContextMutable;
+import org.simantics.document.server.io.ICommand;
 import org.simantics.document.swt.core.SWTDocument;
 import org.simantics.document.swt.core.base.PostEventCommand;
 import org.simantics.document.swt.core.base.PropertyWidgetManager;
@@ -33,10 +36,11 @@ public class CommandEventWidget  extends PropertyWidgetManager<Object> {
     }
 
     @Override
-    public IEventCommand eventCommand(SWTDocument document, JSONObject object, Object component, String command) {
-        if("event".equals(command)) {
+    public IEventCommand eventCommand(SWTDocument document, JSONObject object, Object component, ICommand command, CommandContext p) {
+        if("event".equals(command.getCommand())) {
             List<DataDefinition> dataDefinitions = object.getJSONField("dataDefinitions");
-            HashMap<String, String> data = new HashMap<String, String>();
+            CommandContextMutable context = new CommandContextImpl();
+            context.merge(p);
             for(DataDefinition dd : dataDefinitions) {
                 WidgetData wd = document.getWidgetData().get(dd.getElementId());
                 if(wd != null && wd.object != null) {
@@ -45,12 +49,12 @@ public class CommandEventWidget  extends PropertyWidgetManager<Object> {
                     if(manager != null) {
                         @SuppressWarnings("unchecked")
                         String result = manager.getProperty(document, wd.object, wd.widget, dd.getProperty());
-                        data.put(dd.getTarget(), result);
+                        context.putValue(dd.getTarget(), result);
                     }
                 }
             }
             AbstractEventHandler handler = object.getJSONField("SCLFunction");
-            return new PostEventCommand(document, handler, data);
+            return new PostEventCommand(document, handler, context);
         } else {
             return null;
         }
index deabd7573d3196eb9a0cd2a059f1c1bb20c64ae4..e85d08f47f926282e2d70a3d1a4758390a961347 100644 (file)
@@ -1,16 +1,24 @@
 package org.simantics.document.swt.core.widget;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
 import org.eclipse.ui.IWorkbenchSite;
 import org.simantics.Simantics;
 import org.simantics.browsing.ui.Column;
@@ -22,15 +30,28 @@ import org.simantics.browsing.ui.swt.widgets.ModelBrowser;
 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;
 import org.simantics.db.layer0.variable.VariableBean;
 import org.simantics.db.management.ISessionContext;
+import org.simantics.document.server.IEventCommand;
 import org.simantics.document.server.JSONObject;
+import org.simantics.document.server.bean.Command;
+import org.simantics.document.server.client.CommandManager;
+import org.simantics.document.server.client.WidgetData;
+import org.simantics.document.server.handler.AbstractEventHandler;
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextImpl;
+import org.simantics.document.server.io.CommandContextMutable;
+import org.simantics.document.server.io.ICommand;
+import org.simantics.document.server.io.JSONObjectUtils;
 import org.simantics.document.swt.core.SWTDocument;
 import org.simantics.document.swt.core.SWTViews;
 import org.simantics.document.swt.core.base.LeafWidgetManager;
+import org.simantics.document.swt.core.base.PostEventCommand;
 import org.simantics.document.swt.core.base.WidgetContainer;
 import org.simantics.document.swt.core.bean.ColumnBean;
 import org.simantics.document.swt.core.bean.ColumnsBean;
 import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.function.Function2;
 import org.simantics.ui.selection.WorkbenchSelectionUtils;
+import org.simantics.utils.datastructures.Pair;
 
 public class Explorer extends LeafWidgetManager<ModelBrowser> {
 
@@ -74,9 +95,15 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
         if(Boolean.TRUE.equals(noscroll))
             style |= SWT.NO_SCROLL;
                
-               StatePersistor persistor = object.getJSONField("persistor");
+        Boolean check = object.getJSONFieldDefault("Check", false);
+        if(Boolean.TRUE.equals(check))
+            style |= SWT.CHECK;
+
+        StatePersistor persistor = object.getJSONField("persistor");
                final Function1<Object, Boolean> selectionListener = object.getJSONField("selectionListener");
 
+               final Function2<Object, Boolean, Boolean> checkStateListener = object.getJSONField("checkStateListener");
+
                DragSourceListenerFactory dragSourceListenerFactory = object.getJSONField("dragSourceListenerFactory");
                
                final IWorkbenchSite site = document.getSite();
@@ -147,6 +174,17 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
 
                        @Override
                        public void handleEvent(Event event) {
+                           
+                           switch (event.type) {
+                           case SWT.Selection:
+                               if (event.detail == SWT.CHECK && event.item != null) {
+                                   TreeItem item = (TreeItem) event.item;
+                                   boolean checked = item.getChecked();
+                               if(checkStateListener != null)
+                                   selectionListener.apply(event);
+                               }
+                               break;
+                           }
 
                                if(selectionListener != null)
                                        selectionListener.apply(event);
@@ -183,4 +221,46 @@ public class Explorer extends LeafWidgetManager<ModelBrowser> {
            return null;
        }
 
+    public static class ExplorerCommandManager implements CommandManager<SWTDocument, WidgetContainer<ModelBrowser>> {
+
+        @Override
+        public Collection<Object> updateCommandListeners(final SWTDocument document, final JSONObject object,
+                WidgetContainer<ModelBrowser> container) {
+            
+            WidgetData wd = document.getWidget(JSONObjectUtils.getId(object));
+            List<ICommand> commands = object.getJSONField("commands");
+            HashSet<Object> listeners = new HashSet<Object>();
+            List<Pair<WidgetData, ICommand>> data = new ArrayList<>();
+            data.addAll(SWTViews.getTriggeredCommands(document, commands, "eventOut"));
+            data.add(new Pair<WidgetData, ICommand>(wd, new Command("onCheck")));
+            Listener listener = new ExplorerListener(wd, data);
+            ModelBrowser browser = container.getControl();
+            if(!browser.isDisposed()) {
+                browser.addListenerToControl(SWT.Selection, listener); 
+                listeners.add(listener);
+            }
+            
+            return listeners;
+            
+        }
+
+        @Override
+        public void removeListener(WidgetContainer<ModelBrowser> container, Object listener) {
+            if(container.getControl().isDisposed()) return;
+            if(listener instanceof ExplorerListener)
+                container.getControl().removeListenerFromControl(SWT.Selection, (Listener)listener);
+        }
+
+    }
+
+    @Override
+    public IEventCommand eventCommand(SWTDocument document, JSONObject object, WidgetContainer widget, ICommand command, CommandContext p) {
+        if("onCheck".equals(command.getCommand())) {
+            CommandContextMutable context = new CommandContextImpl().merge(p);
+            AbstractEventHandler onCheck = object.getJSONField("onCheck");
+            return new PostEventCommand(document, onCheck, context);
+        }
+        return null;
+    }   
+       
 }
diff --git a/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ExplorerListener.java b/bundles/org.simantics.document.swt.core/src/org/simantics/document/swt/core/widget/ExplorerListener.java
new file mode 100644 (file)
index 0000000..5d38c8b
--- /dev/null
@@ -0,0 +1,60 @@
+package org.simantics.document.swt.core.widget;
+
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.TreeItem;
+import org.simantics.browsing.ui.BuiltinKeys;
+import org.simantics.browsing.ui.NodeContext;
+import org.simantics.document.server.client.WidgetData;
+import org.simantics.document.server.io.CommandContext;
+import org.simantics.document.server.io.CommandContextImpl;
+import org.simantics.document.server.io.CommandContextMutable;
+import org.simantics.document.server.io.ICommand;
+import org.simantics.document.swt.core.SWTDocument;
+import org.simantics.document.swt.core.base.PropertyWidgetManager;
+import org.simantics.utils.datastructures.Pair;
+
+public class ExplorerListener implements Listener {
+    
+    private WidgetData wd;
+    private List<Pair<WidgetData, ICommand>> data;
+    
+    public ExplorerListener(WidgetData wd, List<Pair<WidgetData, ICommand>> data) {
+        this.wd = wd;
+        this.data = data;
+    }
+
+    @Override
+    public void handleEvent(Event event) {
+        
+        switch (event.type) {
+        case SWT.Selection:
+            if (event.detail == SWT.CHECK && event.item != null) {
+
+                TreeItem item = (TreeItem) event.item;
+                NodeContext ctx = (NodeContext)item.getData();
+                Object value = ctx.getConstant(BuiltinKeys.INPUT);
+                
+                boolean checked = item.getChecked();
+
+                CommandContextMutable context = new CommandContextImpl();
+                context.putValue("event", "onCheck");
+                context.putValue("checked", checked);
+                context.putValue("item", value);
+
+                if(!data.isEmpty()) {
+                    ((SWTDocument)wd.document).handleCommands(data, context, event.widget);
+                }
+                
+                CommandContext ret = PropertyWidgetManager.sendEvent((SWTDocument)wd.document, wd, "onCheck", event.widget, context);
+
+            }
+            break;
+        }
+
+    }
+    
+}
\ No newline at end of file
index 998be35727487003ea3ca1036557d0aa4b64a1f5..4eb186d16015a5c20b2dc9368aebc7b3e480cb10 100644 (file)
@@ -43,9 +43,4 @@ public class FillComposite extends HasWidgetsWidgetManager<Composite> {
                
        }
        
-       @Override
-       public IEventCommand eventCommand(SWTDocument document, JSONObject object, WidgetContainer widget, String command) {
-           return null;
-       }
-       
 }
index ce2538c03e9eefb82aa9645c523a7cd6ec36c14b..7beb69f255bb09c068025f0fd6bed973994171da 100644 (file)
@@ -19,7 +19,7 @@ public class GridComposite extends HasWidgetsWidgetManager<Composite> {
        protected Composite doCreateControl(SWTDocument document, Composite parent, JSONObject object) {
                
                MarginsBean extendedMargins = object.getBeanJSONFieldDefault("extendedMargins", MarginsBean.BINDING, new MarginsBean(0, 0, 0, 0));
-               RGB.Integer background = object.getBeanJSONFieldDefault("background", RGB.Integer.BINDING, new RGB.Integer(255,0, 0));
+               RGB.Integer background = object.getBeanJSONFieldDefault("background", RGB.Integer.BINDING, new RGB.Integer(255, 255, 255));
                Integer numColumns = object.getJSONFieldDefault("numColumns", 1);
                
                Composite result = new Composite(parent, SWT.NONE);
index e577e6c5dadda5e00469d9acdf757ad6b10e2af8..60ddd4fb1395880b9abc6beb877732fedc42b408 100644 (file)
@@ -47,6 +47,8 @@ COMPONENTS.Component <T DOC.Components.PrimitiveComponent
     @SWT.defAttribute L0.Value "Boolean"
   >-- COMPONENTS.Component.NoScroll
     @SWT.defAttribute L0.Value "Boolean"
+  >-- COMPONENTS.Component.Check
+    @SWT.defAttribute L0.Value "Boolean"
   >-- COMPONENTS.Component.alignment
     @SWT.defAttribute L0.Value "String"
         
@@ -190,6 +192,8 @@ COMPONENTS.Explorer <T COMPONENTS.Component
     @SWT.defAttribute L0.Value "String"
   >-- COMPONENTS.Explorer.dragSourceListenerFactory
     @SWT.defAttribute L0.Value "DragSourceListenerFactory"
+  >-- COMPONENTS.Explorer.onCheck
+    @SWT.defAttribute L0.Value "AbstractEventHandler"
 
   @attribute COMPONENTS.Explorer.browseContext
     ""
@@ -200,6 +204,7 @@ COMPONENTS.Explorer <T COMPONENTS.Component
   @attribute COMPONENTS.Explorer.explorerInput
     FUNCTIONS.explorerInput
 
+
 SWT.explorer : L0.Template
     @template %instance %displayFilter %displayHeader %browseContext %contextMenuId %columns
         %instance : COMPONENTS.Explorer
index dce26de31ec484f5cbc21be57d0353aaf9b2b6a6..7fe964225269c0531b04e4426edb703abc548844 100644 (file)
@@ -12,7 +12,9 @@ Require-Bundle: org.simantics.issues;bundle-version="1.1.0",
  org.simantics.db.services;bundle-version="0.6.2",
  org.simantics;bundle-version="1.0.0",
  org.simantics.issues.ui.ontology;bundle-version="1.0.0",
- org.slf4j.api
+ org.slf4j.api,
+ org.simantics.scl.db;bundle-version="0.1.3",
+ org.simantics.scl.runtime
 Export-Package: org.simantics.issues.common,
  org.simantics.issues.common.preferences
 Bundle-Vendor: VTT Technical Research Centre of Finland
index 5cf4730d26f0f167eadfb11ea7b37c488446b448..905c8d4bd1a53704a7eed50790d1651e9bac29f9 100644 (file)
                        class="org.simantics.issues.common.DependencyTrackerBatchIssueSource">
                        <this />
                </type>
+               <type
+                       uri="http://www.simantics.org/Issue-0.0/Sources/ConstraintIssueSource"
+                       class="org.simantics.issues.common.ConstraintIssueSource">
+                       <this />
+               </type>
        </target>
 
        <target interface="org.simantics.issues.common.IssueSource">
index 72728018561bcb598967ca78fe8b4abebda74c5d..989bf6c3a037cb140dc905e051454b965338e5fd 100644 (file)
@@ -11,8 +11,7 @@
  *******************************************************************************/
 package org.simantics.issues.common;
 
-import gnu.trove.set.hash.THashSet;
-
+import java.util.List;
 import java.util.Set;
 
 import org.simantics.db.ReadGraph;
@@ -20,12 +19,13 @@ import org.simantics.db.Resource;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.request.ResourceRead;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.adapter.Instances;
-import org.simantics.issues.ontology.IssueResource;
-import org.simantics.layer0.Layer0;
 import org.simantics.operation.Layer0X;
+import org.simantics.scl.db.SCLFunctions;
+import org.simantics.scl.runtime.tuple.Tuple0;
 import org.simantics.simulation.ontology.SimulationResource;
 
+import gnu.trove.set.hash.THashSet;
+
 /**
  * @author Antti Villberg
  */
@@ -37,20 +37,23 @@ public class AllActiveIssues extends ResourceRead<Set<Resource>> {
 
     @Override
     public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
-        Layer0 L0 = Layer0.getInstance(graph);
+        
         Layer0X L0X = Layer0X.getInstance(graph);
-        IssueResource ISSUE = IssueResource.getInstance(graph);
         SimulationResource SIMU = SimulationResource.getInstance(graph);
         Set<Resource> result = new THashSet<Resource>();
-        Instances indexedIssues = graph.getPossibleAdapter(ISSUE.Issue, Instances.class);
+        
         for (Resource model : graph.syncRequest(new ObjectsWithType(resource, L0X.Activates, SIMU.Model))) {
-            for (Resource issue : graph.syncRequest(new ObjectsWithType(model, L0.ConsistsOf, ISSUE.Issue))) {
-                result.add(issue);
-            }
-            if (indexedIssues != null)
-                result.addAll(indexedIssues.find(graph, model));
+            result.addAll(graph.syncRequest(new AllModelIssues(model, false)));
+        }
+        
+        List<Resource> libraries = SCLFunctions.evaluateDB("Simantics/SharedOntologies", "getSharedOntologies", Tuple0.INSTANCE); 
+        
+        for (Resource library : libraries) {
+            result.addAll(graph.syncRequest(new AllModelIssues(library, false)));
         }
+        
         return result;
+        
     }
 
 }
index 35ad0235190e951072228153d14574771d356c5a..a3e9f5f7e7fe64b4951f07ddb6da71571f8924b5 100644 (file)
  *******************************************************************************/
 package org.simantics.issues.common;
 
-import gnu.trove.map.hash.TObjectByteHashMap;
-import gnu.trove.set.hash.THashSet;
-
-import java.util.Collection;
-import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
-import org.simantics.Simantics;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.BinaryRead;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.layer0.adapter.Instances;
 import org.simantics.db.layer0.variable.Variable;
-import org.simantics.db.layer0.variable.Variables;
-import org.simantics.issues.common.preferences.IssuePrefs;
-import org.simantics.issues.ontology.IssueResource;
-import org.simantics.layer0.Layer0;
 import org.simantics.operation.Layer0X;
+import org.simantics.scl.db.SCLFunctions;
+import org.simantics.scl.runtime.tuple.Tuple0;
 import org.simantics.simulation.ontology.SimulationResource;
 
+import gnu.trove.set.hash.THashSet;
+
 /**
  * @author Tuukka Lehtonen
  */
@@ -48,73 +42,22 @@ public class AllVisibleIssues extends BinaryRead<Resource, Boolean, Set<Variable
 
     @Override
     public Set<Variable> perform(ReadGraph graph) throws DatabaseException {
-        Layer0 L0 = Layer0.getInstance(graph);
+        
         Layer0X L0X = Layer0X.getInstance(graph);
-        IssueResource ISSUE = IssueResource.getInstance(graph);
         SimulationResource SIMU = SimulationResource.getInstance(graph);
-
-        Resource project = Simantics.getProjectResource();
-        boolean showHidden = false;
-        boolean showNormal = true;
-        boolean showUser = true;
-        if (project != null) {
-            showHidden = IssuePrefs.showHiddenIssues(graph, project);
-            showNormal = IssuePrefs.showNormalIssues(graph, project);
-            showUser = IssuePrefs.showUserIssues(graph, project);
-        }
-
-        Instances issueIndex = graph.getPossibleAdapter(ISSUE.Issue, Instances.class);
-
-        // Cache for source activeness.
-        // 0 == not in cache, 1 == false, 2 == true
-        TObjectByteHashMap<Resource> sourceActivenessCache = new TObjectByteHashMap<Resource>();
-
-        Set<Variable> result = new THashSet<Variable>(1013);
-
+        Set<Variable> result = new THashSet<Variable>();
+        
         for (Resource model : graph.syncRequest(new ObjectsWithType(parameter, L0X.Activates, SIMU.Model))) {
-            Collection<Resource> modelIssues = graph.syncRequest(new ObjectsWithType(model, L0.ConsistsOf, ISSUE.Issue));
-            Collection<Resource> indexedIssues = issueIndex != null ? issueIndex.find(graph, model) : Collections.<Resource>emptyList();
-            Collection<Resource> issues = !indexedIssues.isEmpty() ? new THashSet<Resource>(modelIssues.size() + indexedIssues.size()) : modelIssues;
-            if (!indexedIssues.isEmpty()) {
-                issues.addAll(modelIssues);
-                issues.addAll(indexedIssues);
-            }
-
-            for (Resource issue : issues) {
-                // Filter out unwanted material
-                boolean resolved = graph.hasStatement(issue, ISSUE.Resolved);
-                if (parameter2 && resolved)
-                    continue;
-                boolean hidden = graph.hasStatement(issue, ISSUE.Hidden);
-                boolean user = graph.hasStatement(issue, ISSUE.UserIssue);
-                boolean normal = !hidden && !user;
-                if (!showHidden && hidden)
-                    continue;
-                if (!showUser && user)
-                    continue;
-                if (!showNormal && normal)
-                    continue;
-
-                Resource source = graph.getPossibleObject(issue, ISSUE.IssueSource_Manages_Inverse);
-                if (source != null) {
-                    byte cache = sourceActivenessCache.get(source);
-                    boolean active = cache == 2 ? true : false;
-                    if (cache == 0) {
-                        active = Boolean.TRUE.equals(graph.getPossibleRelatedValue(source, ISSUE.IssueSource_active));
-                        sourceActivenessCache.put(source, active ? (byte) 2 : (byte) 1);
-                    }
-                    if (!active)
-                        continue;
-                }
-
-                Variable var = Variables.getPossibleVariable(graph, issue);
-                if (var != null)
-                    result.add(var);
-            }
+            result.addAll(graph.syncRequest(new ModelVisibleIssues(model, false)));
         }
-
-        // System.out.println("AllActiveIssues returned " + result.size());
+        
+        List<Resource> libraries = SCLFunctions.evaluateGraph("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); 
+        for (Resource library : libraries) {
+            result.addAll(graph.syncRequest(new ModelVisibleIssues(library, false)));
+        }
+        
         return result;
+        
     }
 
 }
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/BatchValidations.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/BatchValidations.java
new file mode 100644 (file)
index 0000000..5106765
--- /dev/null
@@ -0,0 +1,166 @@
+package org.simantics.issues.common;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.simantics.Simantics;
+import org.simantics.db.Issue;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.Statement;
+import org.simantics.db.VirtualGraph;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.service.VirtualGraphSupport;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.layer0.Layer0;
+
+import gnu.trove.set.hash.THashSet;
+
+public class BatchValidations {
+
+       private static final boolean PERF = false;
+
+       public static Map<Resource, Set<Issue>> validate(IProgressMonitor monitor, BatchIssueSource source, BatchIssueValidationContext context) throws DatabaseException {
+               Session session = Simantics.getSession();
+               return session.syncRequest(new ComposedValidation(monitor, source, context));
+       }
+
+       /**
+        * @param monitor
+        * @param source
+        * @param issues
+        * @return
+        * @throws DatabaseException
+        */
+       public static int store(final IProgressMonitor monitor,
+                       final Resource source, final Map<Resource, Set<Issue>> issues)
+                       throws DatabaseException {
+               return store(monitor, source, issues, Integer.MAX_VALUE);
+       }
+
+       /**
+        * @param monitor
+        * @param source
+        * @param issues
+        * @param maxIssuesToWrite
+        * @return number of issues written (added)
+        * @throws DatabaseException
+        */
+       public static int store(final IProgressMonitor monitor,
+                       final Resource source, final Map<Resource, Set<Issue>> issues,
+                       final int maxIssuesToWrite) throws DatabaseException {
+
+               if (issues.isEmpty() || maxIssuesToWrite <= 0)
+                       return 0;
+
+               Session session = Simantics.getSession();
+               VirtualGraphSupport support = session.getService(VirtualGraphSupport.class);
+               VirtualGraph vg = support.getWorkspacePersistent(IssueConstants.ISSUE_VG);
+               final int[] writtenIssues = { 0 };
+
+               session.syncRequest(new WriteRequest(vg) {
+
+                       @Override
+                       public void perform(WriteGraph graph) throws DatabaseException {
+
+                               for(Map.Entry<Resource, Set<Issue>> entry : issues.entrySet()) {
+
+                                       if (monitor.isCanceled())
+                                               return;
+
+                                       Resource context = entry.getKey();
+
+                                       Set<Issue> current = entry.getValue();
+                                       Set<Issue> existing = graph.sync(new BatchIssueDescriptions(source, context));
+
+                                       if(!existing.equals(current)) {
+
+                                               Set<Issue> added = new THashSet<Issue>(current);
+                                               Set<Issue> removed = new THashSet<Issue>(existing);
+                                               added.removeAll(existing);
+                                               removed.removeAll(current);
+
+                                               for(Issue add : added) {
+                                                       add.write(graph, source);
+                                                       // Stop if write limit is reached.
+                                                       if (++writtenIssues[0] >= maxIssuesToWrite)
+                                                               return;
+                                               }
+                                               for(Issue remove : removed) {
+                                                       Resource issue = graph.sync(new IssueByList(source, remove));
+                                                       if (issue == null)
+                                                               // FIXME: when can this happen and what should be done in this case?
+                                                               continue;
+                                                       graph.deny(issue, Layer0.getInstance(graph).PartOf);
+                                                       graph.deny(source, IssueResource.getInstance(graph).IssueSource_Manages, issue);
+                                                       RemoverUtil.remove(graph, issue);
+                                               }
+
+                                       }
+
+                               }
+
+                       }
+               });
+
+               return writtenIssues[0];
+
+       }
+
+       /**
+        * @param map
+        * @return
+        */
+       @SuppressWarnings("rawtypes")
+       private static int count(Map map) {
+               int result = 0;
+               for (Object obj : map.values()) {
+                       if (obj instanceof Set<?>) {
+                               Set<?> set = (Set<?>) obj;
+                               result += set.size();
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * Checks if the specified <code>resourceToCheckForLinks</code> is linked to
+        * anything else besides itself and <code>excludeLinksTo</code>.
+        * 
+        * <p>
+        * This is used to if an issue context is still valid. We consider any issue
+        * context that is not attached to something else besides its issue context to
+        * be an invalid issue. Assertions and L0.InstanceOf do not count as external
+        * links.
+        * 
+        * @param graph database access handle
+        * @param resourceToCheckForLinks the resource to check for "external" links
+        * @param excludeLinksTo exclude links to this resource from evaluation
+        * @return <code>true</code> if there are links, <code>false</code> otherwise
+        * @throws DatabaseException 
+        */
+       public static boolean isLinkedToOtherThan(ReadGraph graph, Resource resourceToCheckForLinks,
+                       Resource excludeLinksTo)
+                                       throws DatabaseException
+       {
+               Layer0 L0 = Layer0.getInstance(graph);
+               for (Statement stm : graph.getStatements(resourceToCheckForLinks, L0.IsWeaklyRelatedTo)) {
+                       if (stm.isAsserted(resourceToCheckForLinks))
+                               continue;
+                       if (stm.getPredicate().equals(L0.InstanceOf))
+                               continue;
+                       Resource o = stm.getObject();
+                       if (o.equals(excludeLinksTo) || o.equals(resourceToCheckForLinks))
+                               continue;
+
+                       return true;
+               }
+               return false;
+       }
+
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/ConstraintIssueSource.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/ConstraintIssueSource.java
new file mode 100644 (file)
index 0000000..3df2d96
--- /dev/null
@@ -0,0 +1,116 @@
+package org.simantics.issues.common;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.simantics.db.Issue;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.QueryMemoryWatcher;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest.DomainOnlyProcessor;
+import org.simantics.db.service.CollectionSupport;
+import org.simantics.db.service.QueryControl;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.db.SCLFunctions;
+import org.simantics.scl.runtime.function.Function1;
+
+import gnu.trove.set.hash.THashSet;
+
+/**
+ * @author Antti Villberg
+ */
+public class ConstraintIssueSource implements BatchIssueSource {
+
+    private final Resource resource;
+
+    public ConstraintIssueSource(Resource resource) {
+        this.resource = resource;
+    }
+
+    @Override
+    public Map<Resource, Set<Issue>> run(IProgressMonitor monitor, ReadGraph graph, BatchIssueValidationContext context) throws DatabaseException {
+       
+        Layer0 L0 = Layer0.getInstance(graph);
+        Set<Issue> emptySet = Collections.emptySet();
+        CollectionSupport cs = graph.getService(CollectionSupport.class);
+        Map<Resource,Set<Issue>> result = cs.createMap(Set.class); 
+        monitor.setTaskName("Constraint analysis");
+
+        DomainOnlyProcessor domain = context.domain;
+
+        int entityCount = domain.internals.size();
+        
+        IssueResource ISSUE = IssueResource.getInstance(graph);
+        Resource type = graph.getSingleType(resource, ISSUE.IssueSource);
+        List<Function1<Resource, List<Issue>>> validators = new ArrayList<>();
+        for(Resource constraint : graph.getObjects(type, ISSUE.IssueSource_HasConstraint)) {
+            Function1<Resource, List<Issue>> validator = graph.getRelatedValue2(constraint, L0.Constraint_Validator, constraint); 
+            //Resource function = graph.getSingleObject(constraint, L0.Constraint_Validator);
+            validators.add(validator);
+        }
+
+        QueryControl qc = graph.getService(QueryControl.class);
+        qc.flush(graph);
+
+               // Allow this process to make 50k queries
+               QueryMemoryWatcher memory = new QueryMemoryWatcher(graph, 50000, 0.5, 300);
+
+               SCLFunctions.runWithGraph(graph, () -> {
+
+               int totalExaminedCount = 0;
+               int examinedCount = 1000;
+
+               for(Resource r : domain.internals) {
+
+                   Set<Issue> set = emptySet;
+                   if (examinedCount >= 1000) {
+                       monitor.subTask(contextProgressMessage(totalExaminedCount, entityCount));
+                       examinedCount = 0;
+                       if(monitor.isCanceled()) return;
+                       memory.maintain();
+                   }
+                   for(Function1<Resource, List<Issue>> validator : validators) {
+                       try {
+                           @SuppressWarnings("unchecked")
+                           List<Issue> issues = validator.apply(r);//(List<Issue>)Functions.exec(graph, validator, graph, r);
+                           if (issues != null && !issues.isEmpty()) {
+                               if (set == emptySet)
+                                   set = new THashSet<Issue>();
+                               set.addAll(issues);
+                           }
+                       } catch (Throwable t) {
+                           Logger.defaultLogError(t);
+                       }
+                   }
+                   ++totalExaminedCount;
+                   ++examinedCount;
+                   if(!set.isEmpty())
+                       result.put(r, set);
+                   
+               }
+                   
+               });
+               
+        return result;
+
+    }
+
+    private static String contextProgressMessage(int totalExaminedCount, int entityCount) {
+        StringBuilder sb = new StringBuilder(80)
+        .append("Validating resources").append(" ").append(100*totalExaminedCount / entityCount).append("% ready.");
+        return sb.toString();
+    }
+
+    @Override
+    public Resource getResource() {
+        return resource;
+    }
+
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/Messages.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/Messages.java
new file mode 100644 (file)
index 0000000..7937917
--- /dev/null
@@ -0,0 +1,32 @@
+package org.simantics.issues.common;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+       private static final String BUNDLE_NAME = "org.simantics.issues.ui.handler.messages"; //$NON-NLS-1$
+       public static String ConfigureIssueSources_SelectAvailableIssueSources;
+       public static String ConfigureIssueSources_SelectedSourcesAddRemoveMsg;
+       public static String ExportIssuesAsCsv_AllFiles;
+       public static String ExportIssuesAsCsv_CommaSeparatedValues;
+       public static String ExportIssuesAsCsv_ExportIssues;
+       public static String ExportIssuesAsCsv_SelectValidationOutput;
+       public static String MenuActions_Hide;
+       public static String MenuActions_MarkResolved;
+       public static String MenuActions_MarkUnresolved;
+       public static String MenuActions_SetSeverity;
+       public static String MenuActions_Unhide;
+       public static String PurgeResolvedIssues_MonitorPurgingResolvedIssues;
+       public static String PurgeResolvedIssues_PurgedResolvedBatchIssues;
+       public static String PurgeResolvedIssues_PurgingResolvedBatchIssues;
+       public static String RunActiveValidations_MonitorPreparingResourcesForValidation;
+       public static String RunActiveValidations_ValidateModel;
+       public static String RunActiveValidations_Validation;
+       public static String RunActiveValidations_ValidationPreparation;
+       static {
+               // initialize resource bundle
+               NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+       }
+
+       private Messages() {
+       }
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/ModelVisibleIssues.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/ModelVisibleIssues.java
new file mode 100644 (file)
index 0000000..7012c3c
--- /dev/null
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.issues.common;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.BinaryRead;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.issues.common.preferences.IssuePrefs;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.operation.Layer0X;
+import org.simantics.simulation.ontology.SimulationResource;
+
+import gnu.trove.map.hash.TObjectByteHashMap;
+import gnu.trove.set.hash.THashSet;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class ModelVisibleIssues extends BinaryRead<Resource, Boolean, Set<Variable>> {
+
+    public ModelVisibleIssues(Resource model) {
+        super(model, Boolean.FALSE);
+    }
+
+    public ModelVisibleIssues(Resource model, boolean onlyUnresolved) {
+        super(model, onlyUnresolved);
+    }
+
+    @Override
+    public Set<Variable> perform(ReadGraph graph) throws DatabaseException {
+
+        System.err.println("ModelVisibleIssues for " + graph.getURI(parameter));
+        
+        Layer0 L0 = Layer0.getInstance(graph);
+        IssueResource ISSUE = IssueResource.getInstance(graph);
+
+        Resource project = Simantics.getProjectResource();
+        boolean showHidden = false;
+        boolean showNormal = true;
+        boolean showUser = true;
+        if (project != null) {
+            showHidden = IssuePrefs.showHiddenIssues(graph, project);
+            showNormal = IssuePrefs.showNormalIssues(graph, project);
+            showUser = IssuePrefs.showUserIssues(graph, project);
+        }
+
+        Instances issueIndex = graph.getPossibleAdapter(ISSUE.Issue, Instances.class);
+
+        // Cache for source activeness.
+        // 0 == not in cache, 1 == false, 2 == true
+        TObjectByteHashMap<Resource> sourceActivenessCache = new TObjectByteHashMap<Resource>();
+
+        Set<Variable> result = new THashSet<Variable>(1013);
+
+        Collection<Resource> modelIssues = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, ISSUE.Issue));
+        Collection<Resource> indexedIssues = issueIndex != null ? issueIndex.find(graph, parameter) : Collections.<Resource>emptyList();
+        Collection<Resource> issues = !indexedIssues.isEmpty() ? new THashSet<Resource>(modelIssues.size() + indexedIssues.size()) : modelIssues;
+        if (!indexedIssues.isEmpty()) {
+            issues.addAll(modelIssues);
+            issues.addAll(indexedIssues);
+        }
+
+        for (Resource issue : issues) {
+            // Filter out unwanted material
+            boolean resolved = graph.hasStatement(issue, ISSUE.Resolved);
+            if (parameter2 && resolved)
+                continue;
+            boolean hidden = graph.hasStatement(issue, ISSUE.Hidden);
+            boolean user = graph.hasStatement(issue, ISSUE.UserIssue);
+            boolean normal = !hidden && !user;
+            if (!showHidden && hidden)
+                continue;
+            if (!showUser && user)
+                continue;
+            if (!showNormal && normal)
+                continue;
+
+            Resource source = graph.getPossibleObject(issue, ISSUE.IssueSource_Manages_Inverse);
+            if (source != null) {
+                byte cache = sourceActivenessCache.get(source);
+                boolean active = cache == 2 ? true : false;
+                if (cache == 0) {
+                    active = Boolean.TRUE.equals(graph.getPossibleRelatedValue(source, ISSUE.IssueSource_active));
+                    sourceActivenessCache.put(source, active ? (byte) 2 : (byte) 1);
+                }
+                if (!active)
+                    continue;
+            }
+
+            Variable var = Variables.getPossibleVariable(graph, issue);
+            if (var != null)
+                result.add(var);
+        }
+
+        // System.out.println("AllActiveIssues returned " + result.size());
+        return result;
+    }
+
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/RunActiveValidations.java b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/RunActiveValidations.java
new file mode 100644 (file)
index 0000000..9694d60
--- /dev/null
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.issues.common;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubMonitor;
+import org.simantics.Simantics;
+import org.simantics.db.Issue;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.common.request.Queries;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.common.utils.ListUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.request.PossibleActiveModel;
+import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
+import org.simantics.db.layer0.util.SessionGarbageCollection;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.issues.preferences.IssuePreferenceUtil;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class RunActiveValidations {
+    
+    public static void run(IProgressMonitor monitor) throws DatabaseException {
+        Resource model = Simantics.getSession().syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
+        if(model != null)
+            run(monitor, model);
+    }
+
+    public static void run(IProgressMonitor monitor, Resource model) throws DatabaseException {
+
+        final Session session = Simantics.getSession();
+
+        // 1. query for which composites to run the validation
+        final Collection<BatchIssueSource> validations = new ArrayList<>();
+        final BatchIssueValidationContext context = new BatchIssueValidationContext();
+        
+        try {
+            
+            toBatchIssueSources(session,
+                    session.syncRequest(new SelectedModelBatchIssueSources(model)),
+                    validations);
+
+            SubMonitor.convert(monitor, Messages.RunActiveValidations_MonitorPreparingResourcesForValidation, 100);
+            context.contexts = Collections.singletonList(model);
+            context.domain = ModelTransferableGraphSourceRequest.getDomainOnly(session, monitor, model);
+
+            if (monitor.isCanceled())
+                throw new OperationCanceledException();
+            
+        } finally {
+            monitor.done();
+        }
+        
+        if(!validations.isEmpty() && !context.contexts.isEmpty())
+            run(monitor, validations, context);
+        
+    }
+
+    static Collection<BatchIssueSource> toBatchIssueSources(RequestProcessor processor, Collection<Resource> sources, Collection<BatchIssueSource> result) throws DatabaseException {
+        for (Resource source : sources) {
+            BatchIssueSource bis = processor.syncRequest(Queries.adapt(source, BatchIssueSource.class, true));
+            if (bis != null)
+                result.add(bis);
+        }
+        return result;
+    }
+
+    public static void run(IProgressMonitor monitor, final Collection<BatchIssueSource> validations, final BatchIssueValidationContext context) throws DatabaseException {
+        SubMonitor progress = SubMonitor.convert(monitor, Messages.RunActiveValidations_ValidateModel, 100);
+        int maxWrittenIssues = IssuePreferenceUtil.getPreferences().maxBatchIssuesToWrite;
+        int writtenIssues = 0;
+        for (BatchIssueSource source : validations) {
+            Map<Resource, Set<Issue>> results = BatchValidations.validate(progress.newChild(90, SubMonitor.SUPPRESS_NONE), source, context);
+            if (progress.isCanceled())
+                throw new OperationCanceledException();
+
+            Collection<Resource> removed = Simantics.getSession().syncRequest(new ResourceRead<Collection<Resource>>(source.getResource()) {
+                @Override
+                public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {
+                    IssueResource ISSUE = IssueResource.getInstance(graph);
+                    ArrayList<Resource> result = new ArrayList<>();
+                    for (Resource issue : graph.syncRequest(new ManagedIssues(resource))) {
+                        Resource list = graph.getSingleObject(issue, ISSUE.Issue_HasContexts);
+                        List<Resource> l = ListUtils.toList(graph, list);
+                        if (l.size() > 0) {
+                            Resource mainContext = l.get(0); 
+                            if (!BatchValidations.isLinkedToOtherThan(graph, mainContext, issue))
+                                result.add(mainContext);
+                        }
+                    }
+                    return result;
+                }
+            });
+
+            for(Resource r : removed) {
+                results.put(r, Collections.<Issue>emptySet());
+            }
+            if (progress.isCanceled())
+                throw new OperationCanceledException();
+
+            int wroteIssues = BatchValidations.store(progress.newChild(10, SubMonitor.SUPPRESS_NONE), source.getResource(), results, Math.max(0, maxWrittenIssues - writtenIssues));
+            writtenIssues += wroteIssues;
+
+            // Try to keep resource consumption down.
+            SessionGarbageCollection.gc(null, Simantics.getSession(), true, null);
+            
+        }
+
+    }
+
+}
diff --git a/bundles/org.simantics.issues.common/src/org/simantics/issues/common/messages.properties b/bundles/org.simantics.issues.common/src/org/simantics/issues/common/messages.properties
new file mode 100644 (file)
index 0000000..527e67a
--- /dev/null
@@ -0,0 +1,18 @@
+ConfigureIssueSources_SelectAvailableIssueSources=Select available issue sources\r
+ConfigureIssueSources_SelectedSourcesAddRemoveMsg=Selected sources will be used and existing deselected sources will be removed.\r
+ExportIssuesAsCsv_AllFiles=All Files (*.*)\r
+ExportIssuesAsCsv_CommaSeparatedValues=Comma-Separated Values (*.txt)\r
+ExportIssuesAsCsv_ExportIssues=Export issues\r
+ExportIssuesAsCsv_SelectValidationOutput=Select Validation Output\r
+MenuActions_Hide=Hide\r
+MenuActions_MarkResolved=Mark Resolved\r
+MenuActions_MarkUnresolved=Mark Unresolved\r
+MenuActions_SetSeverity=Set Severity\r
+MenuActions_Unhide=Unhide\r
+PurgeResolvedIssues_MonitorPurgingResolvedIssues=Purging resolved issues...\r
+PurgeResolvedIssues_PurgedResolvedBatchIssues=Purged {0} resolved batch issue(s)\r
+PurgeResolvedIssues_PurgingResolvedBatchIssues=Purging {0} resolved batch issues...\r
+RunActiveValidations_MonitorPreparingResourcesForValidation=Preparing resources for validation\r
+RunActiveValidations_ValidateModel=Validate Model\r
+RunActiveValidations_Validation=Validation\r
+RunActiveValidations_ValidationPreparation=Validation Preparation\r
index a819028de94dc38b3a860edb753059b42235c0f9..cd46d178352c1c4c50df7260706d2876b7440200 100644 (file)
@@ -13,6 +13,7 @@ ISSUE.Functions : L0.Library
 ISSUE.IssueSourceType <T L0.Type
 
 ISSUE.IssueSource <T L0.Entity : ISSUE.IssueSourceType
+    @L0.tag L0.Abstract
     @L0.tag ISSUE.IssueSource.Selected
     >-- ISSUE.IssueSource.HasConstraint --> L0.Constraint <R L0.DependsOn
     >-- ISSUE.IssueSource.Manages --> ISSUE.Issue <R L0.IsRelatedTo
@@ -22,9 +23,11 @@ ISSUE.IssueSource <T L0.Entity : ISSUE.IssueSourceType
     @L0.assert  ISSUE.IssueSource.active true
         
 ISSUE.ContinuousIssueSource <T ISSUE.IssueSource
+    @L0.tag L0.Abstract
     >-- ISSUE.ContinuousIssueSource.lastUpdateRevision --> L0.Long <R L0.HasProperty : L0.FunctionalRelation
 
 ISSUE.DynamicIssueSource <T ISSUE.IssueSource
+    @L0.tag L0.Abstract
     L0.HasDescription "A dynamic issue source is a source that is browsed purely through the Variable interface to produce a single subtree to represent issues. The issues do not have to have a database resource representation backing them."
 
 ISSUE.Issue.ContextList <T L0.List
@@ -101,6 +104,7 @@ ISSUE.Severity.Fatal : ISSUE.Severity
 ISSUE.Sources : L0.Library
 
 ISSUE.Sources.DependencyTracker <T ISSUE.ContinuousIssueSource
+  @L0.tag L0.Abstract
   >-- ISSUE.Sources.DependencyTracker.HasType --> L0.Entity <R L0.DependsOn  : L0.FunctionalRelation
   >-- ISSUE.Sources.DependencyTracker.HasSearchType --> L0.Entity <R L0.DependsOn
   >-- ISSUE.Sources.DependencyTracker.HasExtension --> L0.Function <R L0.DependsOn : L0.Function
@@ -110,6 +114,7 @@ ISSUE.Sources.DependencyTracker <T ISSUE.ContinuousIssueSource
     ISSUE.Functions.dependencyBaseRealizationFunction : L0.Function
   
 ISSUE.Sources.ListeningDependencyTracker <T ISSUE.Sources.DependencyTracker
+  @L0.tag L0.Abstract
   
 ISSUE.Sources.DependencyTracker.Issue <T ISSUE.Issue
   @L0.assert ISSUE.Issue.resource
@@ -119,6 +124,9 @@ ISSUE.Sources.DependencyTracker.Issue <T ISSUE.Issue
 
 ISSUE.Sources.DependencyTracker.AnonymousIssue <T ISSUE.Sources.DependencyTracker.Issue
 
+ISSUE.Sources.ConstraintIssueSource <T ISSUE.IssueSource
+  @L0.tag L0.Abstract
+
 // IssueSource template
 ISSUE.constraint : L0.Template
     @template %type %constraint %source %validator %baseFunction
@@ -131,10 +139,10 @@ ISSUE.constraint : L0.Template
                 L0.HasObject %type
             L0.Asserts _ : L0.Assertion
                 L0.HasPredicate ISSUE.Sources.DependencyTracker.HasConstraint
-                L0.HasObject %constraint     
+                L0.HasObject %constraint
             L0.Asserts _ : L0.Assertion
                 L0.HasPredicate ISSUE.Sources.DependencyTracker.HasBaseFunction
-                L0.HasObject %baseFunction                          
+                L0.HasObject %baseFunction
             
 
 ISSUE.listeningConstraint3 : L0.Template
@@ -198,5 +206,3 @@ ISSUE.assignConstraint : L0.Template
             L0.Asserts _ : L0.Assertion
                 L0.HasPredicate ISSUE.Sources.DependencyTracker.HasConstraint
                 L0.HasObject %constraint
-                
-                
\ No newline at end of file
diff --git a/bundles/org.simantics.issues.ontology/graph/Layer0Sources.pgraph b/bundles/org.simantics.issues.ontology/graph/Layer0Sources.pgraph
new file mode 100644 (file)
index 0000000..7e30868
--- /dev/null
@@ -0,0 +1,18 @@
+L0 = <http://www.simantics.org/Layer0-1.1>
+ISSUE = <http://www.simantics.org/Issue-1.2>
+
+ISSUE.Sources.Relations <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "Relations"
+    ISSUE.IssueSource.HasConstraint L0.Entity.RelationConstraint
+ISSUE.Sources.Properties <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "Properties"
+    ISSUE.IssueSource.HasConstraint L0.Entity.PropertyConstraint
+ISSUE.Sources.Values <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "Values"
+    ISSUE.IssueSource.HasConstraint L0.Entity.ValueConstraint
+ISSUE.Sources.URIs <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "URIs"
+    ISSUE.IssueSource.HasConstraint L0.Entity.URIConstraint
+ISSUE.Sources.Clusters <T ISSUE.Sources.ConstraintIssueSource
+    L0.HasLabel "Clusters"
+    ISSUE.IssueSource.HasConstraint L0.Entity.ClusterConstraint
diff --git a/bundles/org.simantics.issues.ui/scl/Simantics/IssueUI.scl b/bundles/org.simantics.issues.ui/scl/Simantics/IssueUI.scl
new file mode 100644 (file)
index 0000000..ec5e028
--- /dev/null
@@ -0,0 +1,5 @@
+import "Simantics/DB"
+
+importJava "org.simantics.issues.ui.handler.ConfigureIssueSources" where
+  @JavaName executeDefault
+  showIssueConfigurationDialog :: Resource -> <Proc> ()
\ No newline at end of file
index b168583e4e0fb1cb8bfb9cccfe412e14fb9f1887..1836b8cacc116ee99c7d9adb382f679594e0c0f4 100644 (file)
@@ -40,12 +40,12 @@ import org.simantics.db.common.request.UniqueRead;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.QueryIndexUtils;
 import org.simantics.db.layer0.request.PossibleActiveModel;
 import org.simantics.db.layer0.util.RemoverUtil;
 import org.simantics.issues.common.IssueUtils;
 import org.simantics.issues.ontology.IssueResource;
 import org.simantics.layer0.Layer0;
-import org.simantics.modeling.ModelingUtils;
 import org.simantics.utils.ui.ErrorLogger;
 import org.simantics.utils.ui.dialogs.ListDialog;
 
@@ -70,6 +70,16 @@ public class ConfigureIssueSources extends AbstractHandler {
        
     @Override
     public Object execute(ExecutionEvent event) throws ExecutionException {
+        try {
+            Resource indexRoot = Simantics.getSession().syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
+            executeDefault(indexRoot);
+        } catch (DatabaseException e) {
+            throw new ExecutionException("Exception while showing validation configuration dialog", e);
+        }
+        return null;
+    }
+
+    public static void executeDefault(Resource indexRoot) throws ExecutionException {
 
       try {
 
@@ -78,17 +88,17 @@ public class ConfigureIssueSources extends AbstractHandler {
                        @Override
                        public List<IssueSourceEntry> perform(ReadGraph graph) throws DatabaseException {
                                
-                               Resource activeModel = graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
-                               if(activeModel == null) return Collections.emptyList();
+                               if(indexRoot == null) return Collections.emptyList();
                                
                                List<IssueSourceEntry> result = new ArrayList<IssueSourceEntry>();
                                Layer0 L0 = Layer0.getInstance(graph);
                                IssueResource ISSUE = IssueResource.getInstance(graph);
-                               for(Resource type : ModelingUtils.searchByType(graph, activeModel, ISSUE.IssueSourceType)) {
+                               for(Resource type : QueryIndexUtils.searchByType(graph, indexRoot, ISSUE.IssueSourceType)) {
                                        String name = NameUtils.getSafeLabel(graph, type);
-                                       boolean exists = graph.syncRequest(new PossibleObjectWithType(activeModel, L0.ConsistsOf, type)) != null;
+                                       boolean exists = graph.syncRequest(new PossibleObjectWithType(indexRoot, L0.ConsistsOf, type)) != null;
                                        boolean deprecated = graph.hasStatement(type, L0.Deprecated);
-                                       if(!exists && deprecated) continue;
+                                       boolean abstract_ = graph.hasStatement(type, L0.Abstract);
+                                       if(!exists && (deprecated || abstract_)) continue;
                                        result.add(new IssueSourceEntry(name, type, exists));
                                }
                                return result;
@@ -142,25 +152,24 @@ public class ConfigureIssueSources extends AbstractHandler {
          };
          int result = dialog.open();
          if (result != Dialog.OK)
-             return null;
+             return;
        
        Simantics.getSession().syncRequest(new WriteRequest() {
 
                        @Override
                        public void perform(WriteGraph graph) throws DatabaseException {
                                
-                               Resource activeModel = graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
-                               if(activeModel == null) return;
+                               if(indexRoot == null) return;
                                
                                Layer0 L0 = Layer0.getInstance(graph);
 
                                for(IssueSourceEntry entry : sources) {
 
-                                       Resource existing = graph.syncRequest(new PossibleObjectWithType(activeModel, L0.ConsistsOf, entry.getResource())); 
+                                       Resource existing = graph.syncRequest(new PossibleObjectWithType(indexRoot, L0.ConsistsOf, entry.getResource())); 
                                        
                                        if(existing == null && entry.isChecked()) {
                                                String name = NameUtils.getSafeLabel(graph, entry.getResource());
-                                               IssueUtils.addIssueSource(graph, activeModel, entry.getResource(), name);
+                                               IssueUtils.addIssueSource(graph, indexRoot, entry.getResource(), name);
                                        }
                                        
                                        if(existing != null && !entry.isChecked()) {
@@ -173,70 +182,10 @@ public class ConfigureIssueSources extends AbstractHandler {
                
        });
          
-//        try {
-//            PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
-//                @Override
-//                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-//                    try {
-//                        purgeResolvedIssues(monitor);
-//                    } catch (DatabaseException e) {
-//                        throw new InvocationTargetException(e);
-//                    } finally {
-//                        monitor.done();
-//                    }
-//                }
-//            });
-//        } catch (InvocationTargetException e) {
-//            ErrorLogger.defaultLogError(e);
         } catch (DatabaseException e) {
             ErrorLogger.defaultLogError(e);
         }
-        return null;
+        return;
     }
 
-//    private void purgeResolvedIssues(IProgressMonitor monitor) throws DatabaseException {
-//        Session session = Simantics.getSession();
-//        final Resource project = Simantics.getProjectResource();
-//        if (project == null)
-//            return;
-//
-//        final SubMonitor mon = SubMonitor.convert(monitor, "Purging resolved issues...", 100);
-//
-//        session.syncRequest(new DelayedWriteRequest() {
-//            @Override
-//            public void perform(WriteGraph graph) throws DatabaseException {
-//                graph.markUndoPoint();
-//                IssueResource ISSUE = IssueResource.getInstance(graph);
-//                Set<Resource> toBeRemoved = new HashSet<Resource>();
-//                Map<Resource, Boolean> sourceIsContinuous = new THashMap<Resource, Boolean>(); 
-//                for (Resource activeIssue : graph.syncRequest(new AllActiveIssues(project))) {
-//                    if (graph.hasStatement(activeIssue, ISSUE.Resolved)) {
-//                        Resource managedBy = graph.getPossibleObject(activeIssue, ISSUE.IssueSource_Manages_Inverse);
-//                        if (managedBy != null) {
-//                            Boolean isContinuous = sourceIsContinuous.get(managedBy);
-//                            if (isContinuous == null) {
-//                                isContinuous = graph.isInstanceOf(managedBy, ISSUE.ContinuousIssueSource);
-//                                sourceIsContinuous.put(managedBy, isContinuous);
-//                            }
-//                            if (isContinuous)
-//                                continue;
-//                        }
-//                        toBeRemoved.add(activeIssue);
-//                    }
-//                }
-//
-//                mon.setTaskName("Purging " + toBeRemoved.size() + " resolved batch issues...");
-//                mon.setWorkRemaining(toBeRemoved.size());
-//                StringBuilder sb = new StringBuilder();
-//                sb.append("Purged " + toBeRemoved.size() + " resolved batch issue(s)");
-//                for (Resource remove : toBeRemoved) {
-//                    //sb.append(NameUtils.getSafeLabel(graph, remove) + " ");
-//                    RemoverUtil.remove(graph, remove);
-//                    mon.worked(1);
-//                }
-//                Layer0Utils.addCommentMetadata(graph, sb.toString());
-//            }
-//        });
-//    }
-
 }
index 0ab0ef98cb75b824978d0ca3743ecd2cad225f7e..94c886582e9326e4474c6a2081a98692bfad4928 100644 (file)
@@ -57,12 +57,25 @@ public class RunActiveValidations extends AbstractHandler {
 
     @Override
     public Object execute(ExecutionEvent event) throws ExecutionException {
-        Runnable postValidation = null;
-        run(postValidation);
+        try {
+            run();
+        } catch (DatabaseException e) {
+            throw new ExecutionException("Error while running active validations", e);
+        }
         return null;
     }
+    
+    public static void run() throws DatabaseException {
+        Resource model = Simantics.getSession().syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
+        if(model != null)
+            run(null);
+    }
+
+    public static void run(Resource model) {
+        run(model, null);
+    }
 
-    public void run(Runnable postValidation) {
+    public static void run(Resource model, Runnable postValidation) {
 
         final Session session = Simantics.getSession();
 
@@ -77,8 +90,6 @@ public class RunActiveValidations extends AbstractHandler {
                     @Override
                     public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                         try {
-                            Resource model = session.sync(new PossibleActiveModel(Simantics.getProjectResource()));
-                            if(model == null) return;
 
                             toBatchIssueSources(session,
                                     session.syncRequest(new SelectedModelBatchIssueSources(model)),
index f9f82e4a002e3ce7f332d6bae9ab08bb86182430..36f82a01dc69cee7d9cf3b0de233753343b1b851 100644 (file)
@@ -17,10 +17,10 @@ Export-Package: org.simantics.layer0.utils,
  org.simantics.layer0.utils.triggers,
  org.simantics.layer0.utils.writer
 Require-Bundle: gnu.trove3;bundle-version="3.0.3",
- org.simantics.db.common;bundle-version="0.8.0";visibility:=reexport,
  org.eclipse.equinox.common;bundle-version="3.5.0",
  org.simantics.layer0;bundle-version="1.0.0",
- org.simantics.layer0x.ontology;bundle-version="1.0.0"
+ org.simantics.layer0x.ontology;bundle-version="1.0.0",
+ org.simantics.db.common;bundle-version="1.1.0"
 Bundle-Vendor: VTT Technical Research Centre of Finland
 Bundle-ClassPath: .
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
index e3d00e8aa418fa57ebcacaf4da42650fc44ac3f3..d169c9684402f401abe44a54be69db6457e83cad 100644 (file)
@@ -4,6 +4,9 @@
 L0 = <http://www.simantics.org/Layer0-1.1> : L0.Ontology
     L0.HasResourceClass "org.simantics.layer0.Layer0"
 
+L0.SCLMain : L0.SCLModule
+    L0.SCLModule.definition """ include "Simantics/Layer0" """
+
 // Types
 L0.Entity : L0.Type
     L0.HasDescription "All types are inherited from this type."
@@ -42,6 +45,7 @@ L0.Entity : L0.Type
     >-- L0.Entity.methods
     @L0.assert L0.Entity.methods
       _ : L0.Property
+        L0.HasValueType "StructuredProperty"
     
 L0.Entity.methods ==> "StructuredProperty" <R L0.HasProperty : L0.FunctionalRelation
   L0.domainProperties L0.Functions.methodsPropertyDomainProperties
index fb9d271bb141a66f35f23e78b10b817e22b82b30..afa68bbe2cbeb62dc938bba618e34c24c12366e5 100644 (file)
@@ -2,7 +2,11 @@ L0 = <http://www.simantics.org/Layer0-1.1>
 
 L0.Constraint <T L0.Entity
     >-- L0.Constraint.Validator <R L0.HasProperty : L0.FunctionalRelation
-        L0.RequiresValueType "ReadGraph => Resource -> [Issue]"
+        L0.RequiresValueType "Resource -> <ReadGraph> [Issue]"
+
+L0.SCLValidator <T L0.SCLValue
+    L0.HasValueType "Resource -> <ReadGraph> [Issue]"
+    
 L0.HasConstraint <R L0.IsRelatedTo
     L0.InverseOf L0.HasConstraint.Inverse <R L0.IsRelatedTo     
     <-- L0.Type
index 0dbba3181589a58260003ff062c3e4da753ee895..ef5a587e521376e2ddc39de4af0a3e11059e3b9d 100644 (file)
@@ -50,3 +50,10 @@ L0.sclAction : L0.Template
           L0.SCLAction.action _ : L0.SCLValue
             L0.SCLValue.expression %expression
             L0.HasValueType L0.SCLAction.valueType
+
+L0.sclConstraint : L0.Template
+    @template %constraint %expression
+      %constraint : L0.Constraint
+        L0.Constraint.Validator _ : L0.SCLValidator
+          L0.SCLValue.expression %expression
+
index 7c9f35bd75b511303ec430e25d9d7e85c638c94b..4625f33ccbdc105808e32212b29445e2b7d78898 100644 (file)
@@ -1,16 +1,18 @@
 L0 = <http://www.simantics.org/Layer0-1.1>
 
 L0.Entity
-  L0.HasConstraint L0.Entity.RelationConstraint : L0.Constraint
-    L0.Constraint.Validator L0.Functions.relationValidator
-  L0.HasConstraint L0.Entity.PropertyConstraint : L0.Constraint
-    L0.Constraint.Validator L0.Functions.propertyValidator
-  L0.HasConstraint L0.Entity.ValueConstraint : L0.Constraint
-    L0.Constraint.Validator L0.Functions.valueValidator
-  L0.HasConstraint L0.Entity.URIConstraint : L0.Constraint
-    L0.Constraint.Validator L0.Functions.uriValidator
-  L0.HasConstraint L0.Entity.ClusterConstraint : L0.Constraint
-    L0.Constraint.Validator L0.Functions.clusterValidator
-
-
-        
\ No newline at end of file
+  L0.HasConstraint L0.Entity.RelationConstraint
+    @L0.sclConstraint "relationValidator"
+    //L0.Constraint.Validator L0.Functions.relationValidator
+  L0.HasConstraint L0.Entity.PropertyConstraint
+    @L0.sclConstraint "propertyValidator"
+    //L0.Constraint.Validator L0.Functions.propertyValidator
+  L0.HasConstraint L0.Entity.ValueConstraint
+    @L0.sclConstraint "valueValidator"
+    //L0.Constraint.Validator L0.Functions.valueValidator
+  L0.HasConstraint L0.Entity.ClusterConstraint
+    @L0.sclConstraint "clusterValidator"
+    //L0.Constraint.Validator L0.Functions.clusterValidator
+  L0.HasConstraint L0.Entity.URIConstraint
+    @L0.sclConstraint "uriValidator"
+    
\ No newline at end of file
index 47931cc4f1172e7eb0bc631471114d8fd648209b..98b7aa98120c69217aba16c8a9cf709a98bccbf0 100644 (file)
@@ -32,6 +32,9 @@ MOD.SCLLabelForegroundColorRule <T VP.VisualsRule
 MOD.SCLLabelBackgroundColorRule <T VP.VisualsRule
   >-- MOD.SCLLabelBackgroundColorRule.getColor ==> "Resource -> Maybe (Double, Double, Double) -> String -> Integer -> <ReadGraph> Maybe (Double, Double, Double)]" <R L0.HasProperty : L0.FunctionalRelation
 
+MOD.SCLCheckedStateRule <T VP.VisualsRule
+  >-- MOD.SCLCheckedStateRule.getState ==> "BrowseNodeRule CheckedState" <R L0.HasProperty : L0.FunctionalRelation
+
 MOD.SCLAction <T ACT.Action
   --> MOD.SCLAction.action ==> "Resource -> <Proc> ()" <R L0.HasProperty : L0.FunctionalRelation 
 
@@ -412,6 +415,13 @@ MOD.sclLabelBackgroundColorRule : L0.Template
             L0.SCLValue.expression %expression
             L0.HasValueType "Resource -> Maybe (Double, Double, Double) -> String -> Integer -> <ReadGraph> Maybe (Double, Double, Double)"
 
+MOD.sclCheckedStateRule : L0.Template
+    @template %action %expression
+        %action : MOD.SCLCheckedStateRule
+          MOD.SCLCheckedStateRule.getState _ : MOD.SCLValue
+            L0.SCLValue.expression %expression
+            L0.HasValueType "Browsable a => a -> <ReadGraph> CheckedState"
+
 MOD.sclAction : L0.Template
     @template %action %expression
         %action : MOD.SCLAction
index 590ddd21ce8f658d40b133dd6cb0fddd3be8607d..d051042d5f4258b6c92acbace7b52eeec2a9114b 100644 (file)
@@ -111,6 +111,9 @@ importJava "org.simantics.browsing.ui.content.LabelDecorator" where
 
 importJava "org.simantics.browsing.ui.CheckedState" where
     data CheckedState
+    CHECKED :: CheckedState
+    GRAYED :: CheckedState
+    NOT_CHECKED :: CheckedState
 
 importJava "org.simantics.browsing.ui.content.Labeler$Modifier" where
     data Modifier
@@ -138,3 +141,6 @@ instanceOfTest :: Variable -> <ReadGraph> (Resource -> <ReadGraph> Boolean)
 instanceOfTest self = do
   typeResource = singleObject (represents $ parent self) MOD.InstanceOfTest.HasType
   (\r -> isInstanceOf r typeResource) 
+
+type BrowseNodeRule a = VariableOrResource -> <ReadGraph,Proc> a  
+  
\ No newline at end of file
index 7693586d8029b79dcb5ccc80d838e3821644e791..53636e8b2caa889035a57d821af7fb636a1191bd 100644 (file)
         </type>
     </target>
 
+    <target interface="org.simantics.browsing.ui.model.visuals.VisualsRule">
+        <type uri="http://www.simantics.org/Modeling-0.0/SCLCheckedStateRule"
+            class="org.simantics.modeling.adapters.SCLCheckedStateRule">
+                       <graph />
+                       <this />
+        </type>
+    </target>    
+
     <target interface="org.simantics.browsing.ui.model.tests.Test">
         <type uri="http://www.simantics.org/Modeling-0.0/SCLTest"
             class="org.simantics.modeling.adapters.SCLTest">
index e09297750d680e90d2bc55081e285d6d3f12fa45..41e955cd5a2ad7c1a2c3bec6cc8015df3f7e0f8c 100644 (file)
@@ -1,5 +1,6 @@
 include "Simantics/Entity" hiding (nameOf)
 import "Simantics/Model"
+import "UI/Progress"
 import "http://www.simantics.org/Issue-1.2" as ISSUE
 
 type Issue = Resource
@@ -25,4 +26,20 @@ userIssueAdvanced model label severity contexts = do
 
 importJava "org.simantics.issues.common.IssueUtils" where
     @JavaName newUserIssueForModel
-    userIssue :: () -> <WriteGraph> Issue
\ No newline at end of file
+    userIssue :: () -> <WriteGraph> Issue
+    
+importJava "org.simantics.db" where
+    @JavaName Issue
+    data IssueI
+    
+importJava "org.simantics.db.layer0.validation.ValidationUtils" where
+  @JavaName validateConstraintsForDomain
+  validateDomain :: Resource -> <ReadGraph> [IssueI]
+  
+importJava "org.simantics.modeling.utils.BatchValidations" where
+  @JavaName runAll
+  runAllBatchValidations :: ProgressMonitor -> Resource -> Resource -> <Proc> ()
+  
+importJava "org.simantics.issues.common.RunActiveValidations" where
+  @JavaName run
+  runActiveValidations :: ProgressMonitor -> Resource -> <Proc> ()
\ No newline at end of file
index 30a482ffc6d068cfcbc45bdd93dba4490a081c52..6a1ed98425149af507f17e6ab3360df7e40d35b1 100644 (file)
@@ -1,6 +1,7 @@
 include "Simantics/DB"
 
 include "http://www.simantics.org/Layer0-1.1" as L0
+include "http://www.simantics.org/Layer0X-1.1" as L0X
 include "http://www.simantics.org/Structural-1.2" as STR
 include "http://www.simantics.org/Diagram-2.2" as DIA
 include "http://www.simantics.org/Modeling-1.2" as MOD
@@ -10,4 +11,5 @@ include "http://www.simantics.org/Spreadsheet-1.2" as SHEET
 include "http://www.simantics.org/Image2-1.2" as IMAGE
 include "http://www.simantics.org/Document-1.2" as DOCUMENT
 include "http://www.simantics.org/Event-1.2" as EVENT
-include "http://www.simantics.org/Project-1.2" as PROJECT
\ No newline at end of file
+include "http://www.simantics.org/Project-1.2" as PROJECT
+include "http://www.simantics.org/Issue-1.2" as ISSUE
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SCLCheckedStateRule.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/adapters/SCLCheckedStateRule.java
new file mode 100644 (file)
index 0000000..6fb2204
--- /dev/null
@@ -0,0 +1,59 @@
+package org.simantics.modeling.adapters;
+
+import org.simantics.browsing.ui.CheckedState;
+import org.simantics.browsing.ui.model.check.CheckedStateRule;
+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.db.layer0.variable.VariableOrResource;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function1;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SCLCheckedStateRule implements CheckedStateRule {
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(SCLCheckedStateRule.class);
+
+    private Resource rule;
+    
+    public SCLCheckedStateRule(ReadGraph graph, Resource rule) {
+        this.rule = rule;
+    }
+    
+    @Override
+    public boolean isCompatible(Class<?> contentType) {
+        return contentType.equals(Resource.class) || contentType.equals(Variable.class);
+    }
+
+    @Override
+    public CheckedState getCheckedState(ReadGraph graph, Object content) throws DatabaseException {
+    
+        ModelingResources MOD = ModelingResources.getInstance(graph);
+        
+        Variable ruleVariable = Variables.getVariable(graph, rule);
+        
+        Function1<Object,CheckedState> getLabels = ruleVariable.getPossiblePropertyValue(graph, MOD.SCLCheckedStateRule_getState);
+        if(getLabels == null) {
+            LOGGER.warn("Didn't find value for subject={}, predicate={}.", rule, ModelingResources.URIs.SCLCheckedStateRule_getState);
+            return CheckedState.NOT_CHECKED;
+        }
+
+        SCLContext sclContext = SCLContext.getCurrent();
+        Object oldGraph = sclContext.get("graph");
+        try {
+            sclContext.put("graph", graph);
+            return getLabels.apply(VariableOrResource.make(content));
+        } catch (Throwable t) {
+            LOGGER.error("Calculating checked state failed.", t);
+               throw new DatabaseException(t);
+        } finally {
+            sclContext.put("graph", oldGraph);
+        }
+        
+    }
+
+}
index a04b9315f544d698913c655ce084e485ec05224a..1ea88caf4377bb7cb66b31e8b55b8eeafec32ac9 100644 (file)
@@ -41,7 +41,7 @@ public class SCLChildRule implements ChildRule {
         
         Variable ruleVariable = Variables.getVariable(graph, rule);
 
-        Function1<Resource,List<Resource>> getChildren = ruleVariable.getPossiblePropertyValue(graph, MOD.SCLChildRule_getChildren);
+        Function1<Object,List<Resource>> getChildren = ruleVariable.getPossiblePropertyValue(graph, MOD.SCLChildRule_getChildren);
         if(getChildren == null) return Collections.emptyList();
 
         SCLContext sclContext = SCLContext.getCurrent();
index 3aaaed2f668aa308727dc4947ef2993d0854ee27..1e8ad54e13d4b8396d0f37626eb7b488322c0428 100644 (file)
@@ -18,7 +18,8 @@ Require-Bundle: org.simantics.layer0,
  org.simantics.modeling.template2d.ontology;bundle-version="1.0.0",
  org.simantics.spreadsheet.ontology;bundle-version="1.2.0",
  org.simantics.selectionview.ui.ontology;bundle-version="1.1.0",
- org.simantics.diagram.ontology;bundle-version="2.2.0"
+ org.simantics.diagram.ontology;bundle-version="2.2.0",
+ org.simantics.issues.ontology;bundle-version="1.2.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Export-Package: org.simantics.platform.ui
 Automatic-Module-Name: org.simantics.platform.ui.ontology
index cda1dacf966eb0b731d8df17785754decdbc2b0d..0a96411a7e286c5cfcbdf337444a7d29929746a3 100644 (file)
@@ -2,5 +2,6 @@ source.. = src/
 output.. = bin/
 bin.includes = META-INF/,\
                .,\
-               graph.tg
+               graph.tg,\
+               scl/
 src.includes = graph/
index 11b07f80eba5ab9520a20a9582a9f3d0d47fb0af..4dd87b15aa2514a245a1bc8d9df200330a15937f 100644 (file)
@@ -17,8 +17,7 @@ PlatformUI = <http://www.simantics.org/PlatformUI-1.0> : L0.Ontology
     L0.IsLinkedTo MOD
     
 PlatformUI.SCLMain : L0.SCLModule
-    L0.SCLModule.definition _ : L0.String
-      @L0.loadString "scl/SCLMain.scl"
+    L0.SCLModule.definition """ include "Simantics/PlatformUI" """
     
 PlatformUI.NameLabelMode <T L0.String
     @L0.tag L0.Enumeration
diff --git a/bundles/org.simantics.platform.ui.ontology/graph/ValidationView.pgraph b/bundles/org.simantics.platform.ui.ontology/graph/ValidationView.pgraph
new file mode 100644 (file)
index 0000000..4857f1c
--- /dev/null
@@ -0,0 +1,70 @@
+L0 = <http://www.simantics.org/Layer0-1.1>
+DOC = <http://www.simantics.org/Documentation-1.2>
+SWT = <http://www.simantics.org/SWT-1.0>
+STR = <http://www.simantics.org/Structural-1.2>
+SEL = <http://www.simantics.org/SelectionView-1.2>
+COMPONENTS = <http://www.simantics.org/SWT-1.0/Components>
+VIEWS = <http://www.simantics.org/PlatformUI-1.0/Views>
+VP = <http://www.simantics.org/Viewpoint-1.2>
+MOD = <http://www.simantics.org/Modeling-1.2>
+PROJECT = <http://www.simantics.org/Project-1.2>
+ISSUE = <http://www.simantics.org/Issue-1.2>
+
+VIEWS.ValidationContribution : SWT.TypedVariableTabContribution
+    SEL.AbstractVariableTabContribution.HasPriority 1
+    SEL.AbstractTypedVariableTabContribution.HasType L0.IndexRoot
+    SWT.TypedVariableTabContribution.HasView VIEWS.Validations
+    L0.HasLabel "Validation3"
+
+VIEW = VIEWS.Validations : DOC.Document
+VIEW.Root : DOC.Components.Root
+  @DOC.child1_
+    VIEW.Panel
+      @SWT.scrolledComposite
+      @DOC.child2_ VIEW.Explorer
+      @DOC.child1_
+        VIEW.Panel2
+          @SWT.gridComposite 2
+          @DOC.child1_
+            VIEW.Cell1
+              @SWT.gridCell _ false false 1
+                VIEW.ConfigureButton
+                  @SWT.button "Configure3"
+                  @VIEWS.sclEvent COMPONENTS.Button.onPress "configureButtonClick self"
+          @DOC.child2_
+            VIEW.Cell2
+              @SWT.gridCell _ false false 1
+                VIEW.ValidateButton
+                  @SWT.button "Validate"
+                  @VIEWS.sclEvent COMPONENTS.Button.onPress "validateButtonClick self"
+
+VIEW.Columns = { columns = [
+          {key = "single", label = "Issue sources", tooltip = "Issue sources", width = 80, weight = 1, alignment = "LEFT", grab = true}
+          ]} : SWT.Literals.Columns
+
+VIEW.Explorer
+  COMPONENTS.Component.Check true
+  @SWT.explorer true true
+    "http://www.simantics.org/PlatformUI-1.0/Views/Validations/BrowseContext"
+    "#ValidationSelection"
+    VIEW.Columns
+  @VIEWS.sclEvent COMPONENTS.Explorer.onCheck "issueSourceExplorerCheck self"
+
+MBC = MOD.ModelingBrowseContext
+
+VIEWS.Validations.BrowseContext : VP.BrowseContext
+    VP.BrowseContext.Includes PROJECT.ProjectBrowseContext
+    VP.BrowseContext.HasVisualsContribution PROJECT.Contributions.StandardNameLabelRule
+    VP.BrowseContext.HasChildContribution VIEWS.Validations.BrowseContext.Children : VP.ChildContribution
+        VP.ChildContribution.HasParentNodeType MBC.Variable
+        VP.ChildContribution.HasChildNodeType ISSUE.IssueSource
+        VP.ChildContribution.HasRule VIEWS.Validations.BrowseContext.Children.Rule : MOD.SCLChildRule
+            @MOD.scl MOD.SCLChildRule.getChildren "usedIssueSources" "Resource -> <ReadGraph> [Resource]"
+    VP.BrowseContext.HasVisualsContribution _ : VP.VisualsContribution
+        VP.VisualsContribution.HasNodeType ISSUE.IssueSource
+        VP.VisualsContribution.HasPriority 1.0
+        VP.VisualsContribution.HasRule VIEWS.Validations.BrowseContext.Checked
+          @MOD.sclCheckedStateRule "checkedStateRule"
+
+  
+  
\ No newline at end of file
similarity index 61%
rename from bundles/org.simantics.platform.ui.ontology/graph/scl/SCLMain.scl
rename to bundles/org.simantics.platform.ui.ontology/scl/Simantics/PlatformUI.scl
index 44c53d80e4cfa35e9320f51ae3b93227eac94dbe..316a5f15e34fa85086dc9d58a912c6468b491c7e 100644 (file)
@@ -1,5 +1,7 @@
 include "Simantics/All"
 include "SWT/All"
+import "UI/Progress"
+import "Simantics/IssueUI"
 
 useSelectedHandler :: Variable -> (String -> Maybe String) -> <WriteGraph> String
 useSelectedHandler input parameters = do
@@ -84,4 +86,48 @@ standardPropertiesElementTransformation var = do
           Nothing -> var
           Just component -> resourceVariable component
       else var
-  
\ No newline at end of file
+
+configureButtonClickHandler :: Resource -> CommandContext -> <Proc> Maybe CommandResult
+configureButtonClickHandler indexRoot context = do
+    showIssueConfigurationDialog indexRoot 
+    Nothing
+      
+configureButtonClick :: Variable -> <ReadGraph,Proc> AbstractEventHandler
+configureButtonClick self = do
+  indexRoot = represents $ contextVariable self
+  eventHandler2 $ configureButtonClickHandler indexRoot
+
+validateButtonClickHandler :: Resource -> CommandContext -> <Proc> Maybe CommandResult
+validateButtonClickHandler indexRoot context = do
+    runActiveValidations (createNullProgressMonitor ()) indexRoot
+    Nothing
+
+validateButtonClick :: Variable -> <ReadGraph,Proc> AbstractEventHandler
+validateButtonClick self = do
+  indexRoot = represents $ contextVariable self
+  eventHandler2 $ validateButtonClickHandler indexRoot
+
+issueSourceExplorerCheckHandler :: Resource -> CommandContext -> <Proc> Maybe CommandResult
+issueSourceExplorerCheckHandler indexRoot context = match possibleValue context "item" with
+  Nothing -> Nothing
+  Just issueSource -> match possibleValue context "checked" with
+    Nothing -> Nothing
+    Just value -> if value then do
+        syncWrite $ \_ -> claim issueSource ISSUE.IssueSource.Selected (parent issueSource)
+        Nothing
+      else do
+        syncWrite $ \_ -> denyByPredicate issueSource ISSUE.IssueSource.Selected
+        Nothing  
+
+issueSourceExplorerCheck :: Variable -> <ReadGraph,Proc> AbstractEventHandler
+issueSourceExplorerCheck self = do
+  indexRoot = represents $ contextVariable self
+  eventHandler2 $ issueSourceExplorerCheckHandler indexRoot
+
+usedIssueSources :: Resource -> <ReadGraph> [Resource]
+usedIssueSources indexRoot = do
+   objectsWithType indexRoot L0.ConsistsOf ISSUE.IssueSource
+
+checkedStateRule :: BrowseNodeRule CheckedState
+checkedStateRule (ResourceX r) = if existsStatement3 r ISSUE.IssueSource.Selected (parent r) then CHECKED else NOT_CHECKED
+      
\ No newline at end of file
index 436e0a17357f32072ec80c2cea18f8f97d3bb734..47bdaba3c7ebf3c044a46f3536bf4f743cc91fd7 100644 (file)
@@ -437,4 +437,15 @@ importJava "org.simantics.db.layer0.variable.RVI" where
 instantiateUnder :: Resource -> Resource -> <WriteGraph> Resource
 instantiateUnder container typeToInstantiate = do
     fn = (resourceVariable typeToInstantiate)#methods#instantiateUnder :: Resource -> Resource -> <WriteGraph> Resource  
-    fn container typeToInstantiate
\ No newline at end of file
+    fn container typeToInstantiate
+
+@JavaType "org.simantics.db.layer0.variable.VariableOrResource"
+data VariableOrResource =
+    @JavaType "org.simantics.db.layer0.variable.ResourceX"
+    @FieldNames [value]
+    ResourceX Resource
+  | @JavaType "org.simantics.db.layer0.variable.VariableX"
+    @FieldNames [value]
+    VariableX Variable
+    
+    
\ No newline at end of file
index e20dfc471ad9ea28831463f00bc9bfc220d8704a..92bbb74268865f88ba359803b248ac1304b5d774 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.scl.db;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Callable;
 
 import org.cojen.classfile.TypeDesc;
 import org.simantics.Simantics;
@@ -151,6 +152,18 @@ public class SCLFunctions {
             SCLContext.pop();
         }
     }
+    
+    public static void runWithGraph(Object graph, Runnable r) {
+        final SCLContext context = SCLContext.getCurrent();
+        SCLContext.push(context);
+        Object oldGraph = context.put(GRAPH, graph);
+        try {
+            r.run();
+        } finally {
+            context.put(GRAPH, oldGraph);
+            SCLContext.pop();
+        }
+    }
 
     private static Object[] NO_ARGS = new Object[] { Tuple0.INSTANCE };
 
index cf6f05ab2a087fcf9b2edac0178d415b97841ae4..5f7068162b6219acb8e9a1d46dde2b2c8eb34c9e 100644 (file)
@@ -309,16 +309,16 @@ STR.Property <T L0.FunctionalRelation <T L0.PropertyRelation
             L0.HasValueType "String"
 
 STR.Component
-  L0.HasConstraint STR.ConnectionConstraint : L0.Constraint
+  L0.HasConstraint STR.ConnectionValidationConstraint : L0.Constraint
     L0.Constraint.Validator
       STR.Functions.connectionValidator : L0.Function
 
-STR.ConnectionConstraint.ErrorIssue
+STR.ConnectionValidationConstraint.ErrorIssue
   @ISSUE.issue ISSUE.Severity.Error
     STR.Functions.connectionIssueDescription : L0.Function
       L0.HasValueType "String" 
   
-STR.ConnectionConstraint.Source <T ISSUE.Sources.DependencyTracker
+STR.ConnectionValidationConstraint.Source <T ISSUE.Sources.DependencyTracker
   L0.HasLabel "Structural connection validity"
   @L0.assert ISSUE.Sources.DependencyTracker.HasType STR.Component
   @L0.assert ISSUE.Sources.DependencyTracker.HasSearchType STR.Connection
index 970e6f9e813dc710545aeed3d6c0ee1c6cf234cd..e43007637ac5ca616a89f33b3cc3f62247ad8fea 100644 (file)
@@ -749,7 +749,7 @@ public class Functions {
 
                for(Resource req : requiredConnections) {
                        if(!connections.contains(req)) {
-                               result.add(new StandardIssue(sr.ConnectionConstraint_ErrorIssue, component, req));
+                               result.add(new StandardIssue(sr.ConnectionValidationConstraint_ErrorIssue, component, req));
                        }
                }
 
index 2504ba62d8f9ae04f4111bfbdaafa0086409d8f1..2e6449147a05caf9ce2fd9a18aef2f996cc949a5 100644 (file)
@@ -45,6 +45,8 @@ import org.eclipse.osgi.service.datalocation.Location;
 import org.eclipse.osgi.service.resolver.BundleDescription;
 import org.ini4j.Ini;
 import org.ini4j.InvalidFileFormatException;
+import org.simantics.SimanticsPlatform.OntologyRecoveryPolicy;
+import org.simantics.SimanticsPlatform.RecoveryPolicy;
 import org.simantics.databoard.Bindings;
 import org.simantics.databoard.Databoard;
 import org.simantics.datatypes.literal.Font;
@@ -59,6 +61,8 @@ import org.simantics.db.SessionModel;
 import org.simantics.db.UndoContext;
 import org.simantics.db.VirtualGraph;
 import org.simantics.db.WriteGraph;
+import org.simantics.db.common.processor.MergingDelayedWriteProcessor;
+import org.simantics.db.common.processor.MergingGraphRequestProcessor;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.request.WriteResultRequest;
 import org.simantics.db.common.utils.Transaction;
@@ -82,6 +86,7 @@ import org.simantics.db.service.QueryControl;
 import org.simantics.db.service.UndoRedoSupport;
 import org.simantics.db.service.VirtualGraphSupport;
 import org.simantics.db.service.XSupport;
+import org.simantics.db.services.GlobalServiceInitializer;
 import org.simantics.graph.db.GraphDependencyAnalyzer;
 import org.simantics.graph.db.GraphDependencyAnalyzer.IU;
 import org.simantics.graph.db.GraphDependencyAnalyzer.IdentityNode;
@@ -950,14 +955,23 @@ public class SimanticsPlatform implements LifecycleListener {
 
     }
 
+    public void registerServices(SessionContext context) {
+
+        new GlobalServiceInitializer().initialize(session);
+        
+    }
+
+
     public SessionContext createSessionContext(boolean init) throws PlatformException {
         try {
             // Construct and initialize SessionContext from Session.
+            session.registerService(MergingGraphRequestProcessor.class, new MergingGraphRequestProcessor("SessionService", session, 20));
+            session.registerService(MergingDelayedWriteProcessor.class, new MergingDelayedWriteProcessor(session, 20));
             SessionContext sessionContext = SessionContext.create(session, init);
             String message = "Session context created";
             LOGGER.info(message);
             if (init) {
-                sessionContext.registerServices();
+                registerServices(sessionContext);
                 message = "Session services registered";
                 LOGGER.info(message);
             }