-package org.simantics.modeling.utils;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.eclipse.core.runtime.ILog;\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.IStatus;\r
-import org.eclipse.core.runtime.Platform;\r
-import org.eclipse.core.runtime.Status;\r
-import org.eclipse.core.runtime.SubMonitor;\r
-import org.simantics.Simantics;\r
-import org.simantics.db.Issue;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.VirtualGraph;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
-import org.simantics.db.layer0.util.RemoverUtil;\r
-import org.simantics.db.service.VirtualGraphSupport;\r
-import org.simantics.issues.common.AllBatchIssueSources;\r
-import org.simantics.issues.common.BatchIssueDescriptions;\r
-import org.simantics.issues.common.BatchIssueSource;\r
-import org.simantics.issues.common.BatchIssueValidationContext;\r
-import org.simantics.issues.common.ComposedValidation;\r
-import org.simantics.issues.common.IssueByList;\r
-import org.simantics.issues.common.IssueConstants;\r
-import org.simantics.issues.ontology.IssueResource;\r
-import org.simantics.issues.preferences.IssuePreferenceUtil;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.internal.Plugin;\r
-import org.simantics.modeling.requests.CollectionRequest;\r
-import org.simantics.modeling.requests.CollectionResult;\r
-import org.simantics.modeling.requests.Node;\r
-import org.simantics.utils.page.PageDesc;\r
-\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-public class BatchValidations {\r
-\r
- private static final boolean PERF = false;\r
-\r
- public static Collection<Resource> fillConfig(IProgressMonitor monitor, Collection<Resource> models) throws DatabaseException {\r
- final CollectionResult result = Simantics.getSession().syncRequest(new CollectionRequest(monitor, PageDesc.DEFAULT, models.toArray(Resource.NONE)));\r
- if (result == null)\r
- return Collections.emptyList();\r
- return toComposites(result.breadthFirstFlatten());\r
- }\r
-\r
- private static Collection<Resource> toComposites(Collection<Node> nodes) {\r
- Collection<Resource> result = new ArrayList<Resource>(nodes.size());\r
- for (Node n : nodes) {\r
- Resource composite = n.getDefiningResources().resources[0];\r
- Resource diagram = n.getDiagramResource();\r
- if (composite != null && diagram != null)\r
- result.add(composite);\r
- }\r
- return result;\r
- }\r
-\r
- public static Map<Resource, Set<Issue>> validate(IProgressMonitor monitor, BatchIssueSource source, BatchIssueValidationContext context) throws DatabaseException {\r
- Session session = Simantics.getSession();\r
- return session.syncRequest(new ComposedValidation(monitor, source, context));\r
- }\r
-\r
- /**\r
- * @param monitor\r
- * @param source\r
- * @param issues\r
- * @return\r
- * @throws DatabaseException\r
- */\r
- public static int store(final IProgressMonitor monitor,\r
- final Resource source, final Map<Resource, Set<Issue>> issues)\r
- throws DatabaseException {\r
- return store(monitor, source, issues, Integer.MAX_VALUE);\r
- }\r
-\r
- /**\r
- * @param monitor\r
- * @param source\r
- * @param issues\r
- * @param maxIssuesToWrite\r
- * @return number of issues written (added)\r
- * @throws DatabaseException\r
- */\r
- public static int store(final IProgressMonitor monitor,\r
- final Resource source, final Map<Resource, Set<Issue>> issues,\r
- final int maxIssuesToWrite) throws DatabaseException {\r
-\r
- if (issues.isEmpty() || maxIssuesToWrite <= 0)\r
- return 0;\r
-\r
- Session session = Simantics.getSession();\r
- VirtualGraphSupport support = session.getService(VirtualGraphSupport.class);\r
- VirtualGraph vg = support.getWorkspacePersistent(IssueConstants.ISSUE_VG);\r
- final int[] writtenIssues = { 0 };\r
-\r
- session.syncRequest(new WriteRequest(vg) {\r
-\r
- @Override\r
- public void perform(WriteGraph graph) throws DatabaseException {\r
-\r
- for(Map.Entry<Resource, Set<Issue>> entry : issues.entrySet()) {\r
-\r
- if (monitor.isCanceled())\r
- return;\r
-\r
- Resource context = entry.getKey();\r
-\r
- Set<Issue> current = entry.getValue();\r
- Set<Issue> existing = graph.sync(new BatchIssueDescriptions(source, context));\r
-\r
- if(!existing.equals(current)) {\r
-\r
- Set<Issue> added = new THashSet<Issue>(current);\r
- Set<Issue> removed = new THashSet<Issue>(existing);\r
- added.removeAll(existing);\r
- removed.removeAll(current);\r
-\r
- for(Issue add : added) {\r
- add.write(graph, source);\r
- // Stop if write limit is reached.\r
- if (++writtenIssues[0] >= maxIssuesToWrite)\r
- return;\r
- }\r
- for(Issue remove : removed) {\r
- Resource issue = graph.sync(new IssueByList(source, remove));\r
- if (issue == null)\r
- // FIXME: when can this happen and what should be done in this case?\r
- continue;\r
- graph.deny(issue, Layer0.getInstance(graph).PartOf);\r
- graph.deny(source, IssueResource.getInstance(graph).IssueSource_Manages, issue);\r
- RemoverUtil.remove(graph, issue);\r
- }\r
-\r
- }\r
-\r
- }\r
-\r
- }\r
- });\r
-\r
- return writtenIssues[0];\r
-\r
- }\r
-\r
- public static void runAll(IProgressMonitor monitor, Resource model) throws DatabaseException {\r
- runAll(monitor, model, model);\r
- }\r
-\r
- public static void runAll(IProgressMonitor monitor, Resource model, Resource resource) throws DatabaseException {\r
- final Session session = Simantics.getSession();\r
- final Collection<BatchIssueSource> validations = session.sync( new AllBatchIssueSources(model) );\r
- SubMonitor progress = SubMonitor.convert(monitor, "Validate Model", 100*validations.size());\r
- BatchIssueValidationContext context = new BatchIssueValidationContext();\r
- context.domain = ModelTransferableGraphSourceRequest.getDomainOnly(session, monitor, resource);\r
- context.contexts = fillConfig(progress, Collections.singletonList(resource));\r
- int maxWrittenIssues = IssuePreferenceUtil.getPreferences().maxBatchIssuesToWrite;\r
- int totalIssueCount = 0;\r
- int writtenIssueCount = 0;\r
- if (!context.contexts.isEmpty()) {\r
- long t0 = System.nanoTime();\r
- for(BatchIssueSource bis : validations) {\r
- if (monitor.isCanceled())\r
- return;\r
- long startTime = System.nanoTime();\r
- if (PERF)\r
- System.out.println("validate " + bis);\r
- Map<Resource, Set<Issue>> is = validate(progress.newChild(90, SubMonitor.SUPPRESS_NONE), bis, context);\r
- int issueCount = count(is);\r
- long validationTime = System.nanoTime();\r
- if (PERF)\r
- System.out.println("store " + issueCount + " issues");\r
- int wroteIssues = store(progress.newChild(10, SubMonitor.SUPPRESS_NONE), bis.getResource(), is, Math.max(0, maxWrittenIssues - writtenIssueCount));\r
- totalIssueCount += issueCount;\r
- writtenIssueCount += wroteIssues;\r
- long writeTime = System.nanoTime();\r
- if (PERF) {\r
- System.out.println("validation time: " + ((validationTime-startTime)*1e-9) + " s");\r
- System.out.println("issue store time: " + ((writeTime-validationTime)*1e-9) + " s");\r
- }\r
- }\r
- long tf = System.nanoTime();\r
- if (PERF) {\r
- System.out.println("total validation time: " + ((tf-t0)*1e-9) + " s");\r
- }\r
- }\r
- if (totalIssueCount > maxWrittenIssues) {\r
- ILog log = Platform.getLog(Platform.getBundle(Plugin.PLUGIN_ID));\r
- log.log(new Status(IStatus.WARNING, Plugin.PLUGIN_ID, "Batch issue validation produced " + totalIssueCount + " issues which is more than it was allowed to write into the database. The write limit was " + maxWrittenIssues + "."));\r
- }\r
- }\r
-\r
- /**\r
- * @param map\r
- * @return\r
- */\r
- @SuppressWarnings("rawtypes")\r
- private static int count(Map map) {\r
- int result = 0;\r
- for (Object obj : map.values()) {\r
- if (obj instanceof Set<?>) {\r
- Set<?> set = (Set<?>) obj;\r
- result += set.size();\r
- }\r
- }\r
- return result;\r
- }\r
-\r
-}\r
+package org.simantics.modeling.utils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.simantics.Simantics;
+import org.simantics.db.Issue;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+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.ModelTransferableGraphSourceRequest;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.service.VirtualGraphSupport;
+import org.simantics.issues.common.AllBatchIssueSources;
+import org.simantics.issues.common.BatchIssueDescriptions;
+import org.simantics.issues.common.BatchIssueSource;
+import org.simantics.issues.common.BatchIssueValidationContext;
+import org.simantics.issues.common.ComposedValidation;
+import org.simantics.issues.common.IssueByList;
+import org.simantics.issues.common.IssueConstants;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.issues.preferences.IssuePreferenceUtil;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.internal.Plugin;
+import org.simantics.modeling.requests.CollectionRequest;
+import org.simantics.modeling.requests.CollectionResult;
+import org.simantics.modeling.requests.Node;
+import org.simantics.utils.page.PageDesc;
+
+import gnu.trove.set.hash.THashSet;
+
+public class BatchValidations {
+
+ private static final boolean PERF = false;
+
+ public static Collection<Resource> fillConfig(IProgressMonitor monitor, Collection<Resource> models) throws DatabaseException {
+ final CollectionResult result = Simantics.getSession().syncRequest(new CollectionRequest(monitor, PageDesc.DEFAULT, models.toArray(Resource.NONE)));
+ if (result == null)
+ return Collections.emptyList();
+ return toComposites(result.breadthFirstFlatten());
+ }
+
+ private static Collection<Resource> toComposites(Collection<Node> nodes) {
+ Collection<Resource> result = new ArrayList<Resource>(nodes.size());
+ for (Node n : nodes) {
+ Resource composite = n.getDefiningResources().resources[0];
+ Resource diagram = n.getDiagramResource();
+ if (composite != null && diagram != null)
+ result.add(composite);
+ }
+ return result;
+ }
+
+ 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];
+
+ }
+
+ public static void runAll(IProgressMonitor monitor, Resource model) throws DatabaseException {
+ runAll(monitor, model, model);
+ }
+
+ public static void runAll(IProgressMonitor monitor, Resource model, Resource resource) throws DatabaseException {
+ final Session session = Simantics.getSession();
+ final Collection<BatchIssueSource> validations = session.sync( new AllBatchIssueSources(model) );
+ SubMonitor progress = SubMonitor.convert(monitor, "Validate Model", 100*validations.size());
+ BatchIssueValidationContext context = new BatchIssueValidationContext();
+ context.domain = ModelTransferableGraphSourceRequest.getDomainOnly(session, monitor, resource);
+ context.contexts = fillConfig(progress, Collections.singletonList(resource));
+ int maxWrittenIssues = IssuePreferenceUtil.getPreferences().maxBatchIssuesToWrite;
+ int totalIssueCount = 0;
+ int writtenIssueCount = 0;
+ if (!context.contexts.isEmpty()) {
+ long t0 = System.nanoTime();
+ for(BatchIssueSource bis : validations) {
+ if (monitor.isCanceled())
+ return;
+ long startTime = System.nanoTime();
+ if (PERF)
+ System.out.println("validate " + bis);
+ Map<Resource, Set<Issue>> is = validate(progress.newChild(90, SubMonitor.SUPPRESS_NONE), bis, context);
+ int issueCount = count(is);
+ long validationTime = System.nanoTime();
+ if (PERF)
+ System.out.println("store " + issueCount + " issues");
+ int wroteIssues = store(progress.newChild(10, SubMonitor.SUPPRESS_NONE), bis.getResource(), is, Math.max(0, maxWrittenIssues - writtenIssueCount));
+ totalIssueCount += issueCount;
+ writtenIssueCount += wroteIssues;
+ long writeTime = System.nanoTime();
+ if (PERF) {
+ System.out.println("validation time: " + ((validationTime-startTime)*1e-9) + " s");
+ System.out.println("issue store time: " + ((writeTime-validationTime)*1e-9) + " s");
+ }
+ }
+ long tf = System.nanoTime();
+ if (PERF) {
+ System.out.println("total validation time: " + ((tf-t0)*1e-9) + " s");
+ }
+ }
+ if (totalIssueCount > maxWrittenIssues) {
+ ILog log = Platform.getLog(Platform.getBundle(Plugin.PLUGIN_ID));
+ log.log(new Status(IStatus.WARNING, Plugin.PLUGIN_ID, "Batch issue validation produced " + totalIssueCount + " issues which is more than it was allowed to write into the database. The write limit was " + maxWrittenIssues + "."));
+ }
+ }
+
+ /**
+ * @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;
+ }
+
+}