]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Improvements to constraint-based issues 37/3137/8
authorAntti Villberg <antti.villberg@semantum.fi>
Wed, 21 Aug 2019 12:26:18 +0000 (15:26 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Thu, 22 Aug 2019 07:19:11 +0000 (07:19 +0000)
gitlab #355

Change-Id: Ia6ab17a6850e4ad1600e739063797a330077d5f6

18 files changed:
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/build.properties
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.modeling/scl/Simantics/Issue.scl
bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLFunctions.java

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..006e779d47cb105311e11bf66906ca2c1c4de85a 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 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
@@ -8,11 +8,11 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
  *******************************************************************************/
 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 +20,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 +38,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);
+        Set<Resource> result = new THashSet<>();
+
         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..cc0006d9cfa98a4a8baa0c8084890523f800c4bc 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 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
@@ -8,31 +8,26 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
  *******************************************************************************/
 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 +43,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<>();
 
         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;
-                }
+            result.addAll(graph.syncRequest(new ModelVisibleIssues(model, false)));
+        }
 
-                Variable var = Variables.getPossibleVariable(graph, issue);
-                if (var != null)
-                    result.add(var);
-            }
+        List<Resource> libraries = SCLFunctions.evaluateGraph("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE); 
+        for (Resource library : libraries) {
+            result.addAll(graph.syncRequest(new ModelVisibleIssues(library, false)));
         }
 
-        // System.out.println("AllActiveIssues returned " + result.size());
         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..0800560
--- /dev/null
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2019 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
+ *     Semantum Oy - Reorganization
+ *******************************************************************************/
+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..0b02c0e
--- /dev/null
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.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<>();
+                            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..f68cf62
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.issues.common;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+       private static final String BUNDLE_NAME = "org.simantics.issues.common.messages"; //$NON-NLS-1$
+       public static String RunActiveValidations_MonitorPreparingResourcesForValidation;
+       public static String RunActiveValidations_ValidateModel;
+       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..28d3417
--- /dev/null
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2019 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
+ *     Semantum Oy - Reorganization
+ *******************************************************************************/
+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<>(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("ModelVisibleIssues 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..72a5f06
--- /dev/null
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2019 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
+ *     Semantum Oy - Reorganization
+ *******************************************************************************/
+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..99646ca
--- /dev/null
@@ -0,0 +1,2 @@
+RunActiveValidations_MonitorPreparingResourcesForValidation=Preparing resources for validation\r
+RunActiveValidations_ValidateModel=Validate Model\r
index a819028de94dc38b3a860edb753059b42235c0f9..e96923119907180732dee0438fac734897043d4e 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
@@ -20,11 +21,13 @@ ISSUE.IssueSource <T L0.Entity : ISSUE.IssueSourceType
     >-- ISSUE.IssueSource.Selected --> ISSUE.IssueSource <R L0.IsRelatedTo
     >-- ISSUE.IssueSource.active ==> "Boolean" <R L0.HasProperty : L0.FunctionalRelation
     @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
@@ -44,16 +47,16 @@ ISSUE.Issue <T L0.Entity
     >-- ISSUE.Issue.creationTime --> L0.String <R L0.HasProperty : L0.FunctionalRelation
     >-- ISSUE.Issue.hider ==> "Maybe (Boolean -> <WriteGraph> Boolean)" <R L0.HasProperty : L0.FunctionalRelation
     >-- ISSUE.Issue.hidden ==> "Boolean" <R L0.HasProperty : L0.FunctionalRelation
-    @L0.assert L0.HasDescription 
+    @L0.assert L0.HasDescription
       ISSUE.Functions.defaultDescription : L0.Function
         L0.HasValueType "String"
     @L0.assert ISSUE.Issue.severity
       ISSUE.Functions.standardIssueSeverity : L0.Function
         L0.HasValueType "String"
-    @L0.assert ISSUE.Issue.resource 
+    @L0.assert ISSUE.Issue.resource
       ISSUE.Functions.standardIssueResource : L0.Function
         L0.HasValueType "String"
-    @L0.assert ISSUE.Issue.path 
+    @L0.assert ISSUE.Issue.path
       ISSUE.Functions.standardIssuePath : L0.Function
         L0.HasValueType "String"
     @L0.assert ISSUE.Issue.contexts
@@ -86,7 +89,7 @@ ISSUE.Severity <T L0.Value
     @L0.tag L0.Enumeration
     @L0.assert L0.ConvertsToValueWith
         L0.Functions.resourceAsValue
-    
+
 ISSUE.Severity.Note : ISSUE.Severity
     L0.HasDescription "These issues are markers for documentation purposes"
 ISSUE.Severity.Info : ISSUE.Severity
@@ -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
@@ -108,9 +112,10 @@ ISSUE.Sources.DependencyTracker <T ISSUE.ContinuousIssueSource
   >-- ISSUE.Sources.DependencyTracker.HasConstraint --> L0.Constraint <R ISSUE.IssueSource.HasConstraint : L0.FunctionalRelation
   @L0.assert ISSUE.Sources.DependencyTracker.HasBaseFunction
     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
     ISSUE.Functions.standardIssueResource
@@ -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,11 +139,11 @@ 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
     @template %type %constraint %source %validator
@@ -164,7 +172,7 @@ ISSUE.listeningConstraint : L0.Template
                 L0.HasObject %constraint
             L0.Asserts _ : L0.Assertion
                 L0.HasPredicate ISSUE.Sources.DependencyTracker.HasBaseFunction
-                L0.HasObject %baseFunction                
+                L0.HasObject %baseFunction
 
 // Issue template
 ISSUE.issue : 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..9b0cb10
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+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
index 4cab8fbcefb45e8bc1ae43b981675d25fcaab4bb..063f95b83d32bbb269e4cccdcc79c0fd0dc82a94 100644 (file)
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2007, 2011 Association for Decentralized Information Management
+# Copyright (c) 2007, 2019 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
@@ -15,4 +15,5 @@ bin.includes = META-INF/,\
                .,\
                plugin.xml,\
                icons/,\
-               adapters.xml
+               adapters.xml,\
+               scl/
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..7f0a5dd
--- /dev/null
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+import "Simantics/DB"
+
+importJava "org.simantics.issues.ui.handler.ConfigureIssueSources" where
+  @JavaName executeDefault
+  showIssueConfigurationDialog :: Resource -> <Proc> ()
\ No newline at end of file
index b168583e4e0fb1cb8bfb9cccfe412e14fb9f1887..720b9d10beeeacb12eead12496a7c308bf713a63 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 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
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
  *******************************************************************************/
 package org.simantics.issues.ui.handler;
 
@@ -40,12 +41,13 @@ 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.db.request.Write;
 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;
 
@@ -67,176 +69,106 @@ public class ConfigureIssueSources extends AbstractHandler {
                        checked = value;
                }
        }
-       
-    @Override
-    public Object execute(ExecutionEvent event) throws ExecutionException {
 
-      try {
+       @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;
+       }
 
-       final List<IssueSourceEntry> sources = Simantics.getSession().syncRequest(new UniqueRead<List<IssueSourceEntry>>() {
+       public static void executeDefault(Resource indexRoot) throws ExecutionException {
 
-                       @Override
-                       public List<IssueSourceEntry> perform(ReadGraph graph) throws DatabaseException {
-                               
-                               Resource activeModel = graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource()));
-                               if(activeModel == 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)) {
-                                       String name = NameUtils.getSafeLabel(graph, type);
-                                       boolean exists = graph.syncRequest(new PossibleObjectWithType(activeModel, L0.ConsistsOf, type)) != null;
-                                       boolean deprecated = graph.hasStatement(type, L0.Deprecated);
-                                       if(!exists && deprecated) continue;
-                                       result.add(new IssueSourceEntry(name, type, exists));
+               if (indexRoot == null)
+                       return;
+
+               try {
+                       final List<IssueSourceEntry> sources = Simantics.getSession().syncRequest(new UniqueRead<List<IssueSourceEntry>>() {
+
+                               @Override
+                               public List<IssueSourceEntry> perform(ReadGraph graph) throws DatabaseException {
+
+                                       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 : QueryIndexUtils.searchByType(graph, indexRoot, ISSUE.IssueSourceType)) {
+                                               String name = NameUtils.getSafeLabel(graph, type);
+                                               boolean exists = graph.syncRequest(new PossibleObjectWithType(indexRoot, L0.ConsistsOf, type)) != null;
+                                               boolean deprecated = graph.hasStatement(type, L0.Deprecated);
+                                               boolean abstract_ = graph.hasStatement(type, L0.Abstract);
+                                               if(!exists && (deprecated || abstract_)) continue;
+                                               result.add(new IssueSourceEntry(name, type, exists));
+                                       }
+                                       return result;
                                }
-                               return result;
-                       }
-               
-       });
-       
-        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
-         ListDialog<IssueSourceEntry> dialog = new ListDialog<IssueSourceEntry>(
-                 shell, sources,
-                 Messages.ConfigureIssueSources_SelectAvailableIssueSources,
-                 Messages.ConfigureIssueSources_SelectedSourcesAddRemoveMsg) {
-                
-                   protected CheckboxTableViewer createViewer(Composite composite) {
-                       CheckboxTableViewer viewer = CheckboxTableViewer.newCheckList(
-                               composite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
-                       final Table table = (Table)viewer.getControl();
-                       viewer.setCheckStateProvider(new ICheckStateProvider() {
-                                               
+
+                       });
+
+                       Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+                       ListDialog<IssueSourceEntry> dialog = new ListDialog<IssueSourceEntry>(
+                                       shell, sources,
+                                       Messages.ConfigureIssueSources_SelectAvailableIssueSources,
+                                       Messages.ConfigureIssueSources_SelectedSourcesAddRemoveMsg) {
+
+                               protected CheckboxTableViewer createViewer(Composite composite) {
+                                       CheckboxTableViewer viewer = CheckboxTableViewer.newCheckList(
+                                                       composite, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
+                                       viewer.setCheckStateProvider(new ICheckStateProvider() {
                                                @Override
-                                               public boolean isGrayed(Object arg0) {
+                                               public boolean isGrayed(Object o) {
                                                        return false;
                                                }
-                                               
                                                @Override
-                                               public boolean isChecked(Object arg0) {
-                                                       IssueSourceEntry entry = (IssueSourceEntry)arg0;
+                                               public boolean isChecked(Object o) {
+                                                       IssueSourceEntry entry = (IssueSourceEntry)o;
                                                        return entry.isChecked();
                                                }
-                                               
                                        });
-                       viewer.addCheckStateListener(new ICheckStateListener() {
-                                               
-                                               @Override
-                                               public void checkStateChanged(CheckStateChangedEvent arg0) {
-                                                       IssueSourceEntry entry = (IssueSourceEntry)arg0.getElement();
-                                                       entry.setChecked(arg0.getChecked());
-                                               }
+                                       viewer.addCheckStateListener(e -> {
+                                               IssueSourceEntry entry = (IssueSourceEntry)e.getElement();
+                                               entry.setChecked(e.getChecked());
                                        });
-                       table.addSelectionListener(new SelectionListener () {
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       table.deselectAll();
-                               }
-                               @Override
-                               public void widgetDefaultSelected(SelectionEvent e) {}
-                       });
-                       return viewer;
-                   }
-
-         };
-         int result = dialog.open();
-         if (result != Dialog.OK)
-             return null;
-       
-       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;
-                               
+                                       viewer.getTable().addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
+                                               viewer.getTable().deselectAll();
+                                       }));
+                                       return viewer;
+                               }
+
+                       };
+                       int result = dialog.open();
+                       if (result != Dialog.OK)
+                               return;
+
+                       Simantics.getSession().syncRequest((Write) graph -> {
+
                                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()) {
                                                RemoverUtil.remove(graph, existing);
                                        }
-                                       
+
                                }
-                               
-                       }
-               
-       });
-         
-//        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;
-    }
-
-//    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());
-//            }
-//        });
-//    }
+
+                       });
+               } catch (DatabaseException e) {
+                       ErrorLogger.defaultLogError(e);
+               }
+
+       }
 
 }
index 0ab0ef98cb75b824978d0ca3743ecd2cad225f7e..efdba04d0ee07fecb12bbb814628989ef6ec434e 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 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
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - Reorganization
  *******************************************************************************/
 package org.simantics.issues.ui.handler;
 
@@ -57,12 +58,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 void run(Runnable postValidation) {
+    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 static void run(Resource model, Runnable postValidation) {
 
         final Session session = Simantics.getSession();
 
@@ -77,8 +91,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)),
@@ -151,7 +163,7 @@ public class RunActiveValidations extends AbstractHandler {
                                             Resource list = graph.getSingleObject(issue, ISSUE.Issue_HasContexts);
                                             List<Resource> l = ListUtils.toList(graph, list);
                                             if (l.size() > 0) {
-                                                Resource mainContext = l.get(0); 
+                                                Resource mainContext = l.get(0);
                                                 if (!BatchValidations.isLinkedToOtherThan(graph, mainContext, issue))
                                                     result.add(mainContext);
                                             }
@@ -174,7 +186,7 @@ public class RunActiveValidations extends AbstractHandler {
 
                             }
                         } catch (OperationCanceledException e) {
-                               throw e;
+                            throw e;
                         } catch (Exception e) {
                             throw new InvocationTargetException(e);
                         } finally {
index e09297750d680e90d2bc55081e285d6d3f12fa45..ee7e51e0be85b398c2d2f96cb3cd3c6b01e7f95a 100644 (file)
@@ -1,20 +1,21 @@
 include "Simantics/Entity" hiding (nameOf)
 import "Simantics/Model"
+import "UI/Progress"
 import "http://www.simantics.org/Issue-1.2" as ISSUE
 
 type Issue = Resource
 type Severity = Resource
-    
+
 issuesOf :: Model -> <ReadGraph> [Issue]
 issuesOf model = recurse ISSUE.Issue model
   where
     recurse t r = do
-        cs = children r 
+        cs = children r
         issues = filter isIssue cs
         issueGrp = filter (not . isIssue) cs
         issues + concatMap (recurse t) issueGrp
     isIssue r = isInstanceOf r ISSUE.Issue
-    
+
 importJava "org.simantics.issues.common.IssueUtils" where
     @JavaName newUserIssueForModel
     newUserIssueForModel :: Model -> String -> Severity -> [Resource] -> <WriteGraph> Issue
@@ -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 e20dfc471ad9ea28831463f00bc9bfc220d8704a..d8f83e05f5b2f231bc5dcd14bf27bf93ff85ffdc 100644 (file)
@@ -1,3 +1,14 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
 package org.simantics.scl.db;
 
 import java.io.IOException;
@@ -152,6 +163,18 @@ public class SCLFunctions {
         }
     }
 
+    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 };
 
     public static <T> void asyncRead(final Function f) throws DatabaseException {