1 package org.simantics.issues.common;
6 import org.eclipse.core.runtime.IProgressMonitor;
7 import org.simantics.Simantics;
8 import org.simantics.db.Issue;
9 import org.simantics.db.ReadGraph;
10 import org.simantics.db.Resource;
11 import org.simantics.db.Session;
12 import org.simantics.db.Statement;
13 import org.simantics.db.VirtualGraph;
14 import org.simantics.db.WriteGraph;
15 import org.simantics.db.common.request.WriteRequest;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.layer0.util.RemoverUtil;
18 import org.simantics.db.service.VirtualGraphSupport;
19 import org.simantics.issues.ontology.IssueResource;
20 import org.simantics.layer0.Layer0;
22 import gnu.trove.set.hash.THashSet;
24 public class BatchValidations {
26 private static final boolean PERF = false;
28 public static Map<Resource, Set<Issue>> validate(IProgressMonitor monitor, BatchIssueSource source, BatchIssueValidationContext context) throws DatabaseException {
29 Session session = Simantics.getSession();
30 return session.syncRequest(new ComposedValidation(monitor, source, context));
38 * @throws DatabaseException
40 public static int store(final IProgressMonitor monitor,
41 final Resource source, final Map<Resource, Set<Issue>> issues)
42 throws DatabaseException {
43 return store(monitor, source, issues, Integer.MAX_VALUE);
50 * @param maxIssuesToWrite
51 * @return number of issues written (added)
52 * @throws DatabaseException
54 public static int store(final IProgressMonitor monitor,
55 final Resource source, final Map<Resource, Set<Issue>> issues,
56 final int maxIssuesToWrite) throws DatabaseException {
58 if (issues.isEmpty() || maxIssuesToWrite <= 0)
61 Session session = Simantics.getSession();
62 VirtualGraphSupport support = session.getService(VirtualGraphSupport.class);
63 VirtualGraph vg = support.getWorkspacePersistent(IssueConstants.ISSUE_VG);
64 final int[] writtenIssues = { 0 };
66 session.syncRequest(new WriteRequest(vg) {
69 public void perform(WriteGraph graph) throws DatabaseException {
71 for(Map.Entry<Resource, Set<Issue>> entry : issues.entrySet()) {
73 if (monitor.isCanceled())
76 Resource context = entry.getKey();
78 Set<Issue> current = entry.getValue();
79 Set<Issue> existing = graph.sync(new BatchIssueDescriptions(source, context));
81 if(!existing.equals(current)) {
83 Set<Issue> added = new THashSet<Issue>(current);
84 Set<Issue> removed = new THashSet<Issue>(existing);
85 added.removeAll(existing);
86 removed.removeAll(current);
88 for(Issue add : added) {
89 add.write(graph, source);
90 // Stop if write limit is reached.
91 if (++writtenIssues[0] >= maxIssuesToWrite)
94 for(Issue remove : removed) {
95 Resource issue = graph.sync(new IssueByList(source, remove));
97 // FIXME: when can this happen and what should be done in this case?
99 graph.deny(issue, Layer0.getInstance(graph).PartOf);
100 graph.deny(source, IssueResource.getInstance(graph).IssueSource_Manages, issue);
101 RemoverUtil.remove(graph, issue);
111 return writtenIssues[0];
119 @SuppressWarnings("rawtypes")
120 private static int count(Map map) {
122 for (Object obj : map.values()) {
123 if (obj instanceof Set<?>) {
124 Set<?> set = (Set<?>) obj;
125 result += set.size();
132 * Checks if the specified <code>resourceToCheckForLinks</code> is linked to
133 * anything else besides itself and <code>excludeLinksTo</code>.
136 * This is used to if an issue context is still valid. We consider any issue
137 * context that is not attached to something else besides its issue context to
138 * be an invalid issue. Assertions and L0.InstanceOf do not count as external
141 * @param graph database access handle
142 * @param resourceToCheckForLinks the resource to check for "external" links
143 * @param excludeLinksTo exclude links to this resource from evaluation
144 * @return <code>true</code> if there are links, <code>false</code> otherwise
145 * @throws DatabaseException
147 public static boolean isLinkedToOtherThan(ReadGraph graph, Resource resourceToCheckForLinks,
148 Resource excludeLinksTo)
149 throws DatabaseException
151 Layer0 L0 = Layer0.getInstance(graph);
152 for (Statement stm : graph.getStatements(resourceToCheckForLinks, L0.IsWeaklyRelatedTo)) {
153 if (stm.isAsserted(resourceToCheckForLinks))
155 if (stm.getPredicate().equals(L0.InstanceOf))
157 Resource o = stm.getObject();
158 if (o.equals(excludeLinksTo) || o.equals(resourceToCheckForLinks))