1 /*******************************************************************************
2 * Copyright (c) 2019 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 * Semantum Oy - Reorganization
12 *******************************************************************************/
13 package org.simantics.issues.common;
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.simantics.Simantics;
20 import org.simantics.db.Issue;
21 import org.simantics.db.ReadGraph;
22 import org.simantics.db.Resource;
23 import org.simantics.db.Session;
24 import org.simantics.db.Statement;
25 import org.simantics.db.VirtualGraph;
26 import org.simantics.db.WriteGraph;
27 import org.simantics.db.common.request.WriteRequest;
28 import org.simantics.db.exception.DatabaseException;
29 import org.simantics.db.layer0.util.RemoverUtil;
30 import org.simantics.db.service.VirtualGraphSupport;
31 import org.simantics.issues.ontology.IssueResource;
32 import org.simantics.layer0.Layer0;
34 import gnu.trove.set.hash.THashSet;
36 public class BatchValidations {
38 private static final boolean PERF = false;
40 public static Map<Resource, Set<Issue>> validate(IProgressMonitor monitor, BatchIssueSource source, BatchIssueValidationContext context) throws DatabaseException {
41 Session session = Simantics.getSession();
42 return session.syncRequest(new ComposedValidation(monitor, source, context));
50 * @throws DatabaseException
52 public static int store(final IProgressMonitor monitor,
53 final Resource source, final Map<Resource, Set<Issue>> issues)
54 throws DatabaseException {
55 return store(monitor, source, issues, Integer.MAX_VALUE);
62 * @param maxIssuesToWrite
63 * @return number of issues written (added)
64 * @throws DatabaseException
66 public static int store(final IProgressMonitor monitor,
67 final Resource source, final Map<Resource, Set<Issue>> issues,
68 final int maxIssuesToWrite) throws DatabaseException {
70 if (issues.isEmpty() || maxIssuesToWrite <= 0)
73 Session session = Simantics.getSession();
74 VirtualGraphSupport support = session.getService(VirtualGraphSupport.class);
75 VirtualGraph vg = support.getWorkspacePersistent(IssueConstants.ISSUE_VG);
76 final int[] writtenIssues = { 0 };
78 session.syncRequest(new WriteRequest(vg) {
81 public void perform(WriteGraph graph) throws DatabaseException {
83 for(Map.Entry<Resource, Set<Issue>> entry : issues.entrySet()) {
85 if (monitor.isCanceled())
88 Resource context = entry.getKey();
90 Set<Issue> current = entry.getValue();
91 Set<Issue> existing = graph.sync(new BatchIssueDescriptions(source, context));
93 if(!existing.equals(current)) {
95 Set<Issue> added = new THashSet<Issue>(current);
96 Set<Issue> removed = new THashSet<Issue>(existing);
97 added.removeAll(existing);
98 removed.removeAll(current);
100 for(Issue add : added) {
101 add.write(graph, source);
102 // Stop if write limit is reached.
103 if (++writtenIssues[0] >= maxIssuesToWrite)
106 for(Issue remove : removed) {
107 Resource issue = graph.sync(new IssueByList(source, remove));
109 // FIXME: when can this happen and what should be done in this case?
111 graph.deny(issue, Layer0.getInstance(graph).PartOf);
112 graph.deny(source, IssueResource.getInstance(graph).IssueSource_Manages, issue);
113 RemoverUtil.remove(graph, issue);
123 return writtenIssues[0];
131 @SuppressWarnings("rawtypes")
132 private static int count(Map map) {
134 for (Object obj : map.values()) {
135 if (obj instanceof Set<?>) {
136 Set<?> set = (Set<?>) obj;
137 result += set.size();
144 * Checks if the specified <code>resourceToCheckForLinks</code> is linked to
145 * anything else besides itself and <code>excludeLinksTo</code>.
148 * This is used to if an issue context is still valid. We consider any issue
149 * context that is not attached to something else besides its issue context to
150 * be an invalid issue. Assertions and L0.InstanceOf do not count as external
153 * @param graph database access handle
154 * @param resourceToCheckForLinks the resource to check for "external" links
155 * @param excludeLinksTo exclude links to this resource from evaluation
156 * @return <code>true</code> if there are links, <code>false</code> otherwise
157 * @throws DatabaseException
159 public static boolean isLinkedToOtherThan(ReadGraph graph, Resource resourceToCheckForLinks,
160 Resource excludeLinksTo)
161 throws DatabaseException
163 Layer0 L0 = Layer0.getInstance(graph);
164 for (Statement stm : graph.getStatements(resourceToCheckForLinks, L0.IsWeaklyRelatedTo)) {
165 if (stm.isAsserted(resourceToCheckForLinks))
167 if (stm.getPredicate().equals(L0.InstanceOf))
169 Resource o = stm.getObject();
170 if (o.equals(excludeLinksTo) || o.equals(resourceToCheckForLinks))