]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.issues.common/src/org/simantics/issues/common/BatchValidations.java
Playground for Antti.
[simantics/platform.git] / bundles / org.simantics.issues.common / src / org / simantics / issues / common / BatchValidations.java
1 package org.simantics.issues.common;
2
3 import java.util.Map;
4 import java.util.Set;
5
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;
21
22 import gnu.trove.set.hash.THashSet;
23
24 public class BatchValidations {
25
26         private static final boolean PERF = false;
27
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));
31         }
32
33         /**
34          * @param monitor
35          * @param source
36          * @param issues
37          * @return
38          * @throws DatabaseException
39          */
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);
44         }
45
46         /**
47          * @param monitor
48          * @param source
49          * @param issues
50          * @param maxIssuesToWrite
51          * @return number of issues written (added)
52          * @throws DatabaseException
53          */
54         public static int store(final IProgressMonitor monitor,
55                         final Resource source, final Map<Resource, Set<Issue>> issues,
56                         final int maxIssuesToWrite) throws DatabaseException {
57
58                 if (issues.isEmpty() || maxIssuesToWrite <= 0)
59                         return 0;
60
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 };
65
66                 session.syncRequest(new WriteRequest(vg) {
67
68                         @Override
69                         public void perform(WriteGraph graph) throws DatabaseException {
70
71                                 for(Map.Entry<Resource, Set<Issue>> entry : issues.entrySet()) {
72
73                                         if (monitor.isCanceled())
74                                                 return;
75
76                                         Resource context = entry.getKey();
77
78                                         Set<Issue> current = entry.getValue();
79                                         Set<Issue> existing = graph.sync(new BatchIssueDescriptions(source, context));
80
81                                         if(!existing.equals(current)) {
82
83                                                 Set<Issue> added = new THashSet<Issue>(current);
84                                                 Set<Issue> removed = new THashSet<Issue>(existing);
85                                                 added.removeAll(existing);
86                                                 removed.removeAll(current);
87
88                                                 for(Issue add : added) {
89                                                         add.write(graph, source);
90                                                         // Stop if write limit is reached.
91                                                         if (++writtenIssues[0] >= maxIssuesToWrite)
92                                                                 return;
93                                                 }
94                                                 for(Issue remove : removed) {
95                                                         Resource issue = graph.sync(new IssueByList(source, remove));
96                                                         if (issue == null)
97                                                                 // FIXME: when can this happen and what should be done in this case?
98                                                                 continue;
99                                                         graph.deny(issue, Layer0.getInstance(graph).PartOf);
100                                                         graph.deny(source, IssueResource.getInstance(graph).IssueSource_Manages, issue);
101                                                         RemoverUtil.remove(graph, issue);
102                                                 }
103
104                                         }
105
106                                 }
107
108                         }
109                 });
110
111                 return writtenIssues[0];
112
113         }
114
115         /**
116          * @param map
117          * @return
118          */
119         @SuppressWarnings("rawtypes")
120         private static int count(Map map) {
121                 int result = 0;
122                 for (Object obj : map.values()) {
123                         if (obj instanceof Set<?>) {
124                                 Set<?> set = (Set<?>) obj;
125                                 result += set.size();
126                         }
127                 }
128                 return result;
129         }
130
131         /**
132          * Checks if the specified <code>resourceToCheckForLinks</code> is linked to
133          * anything else besides itself and <code>excludeLinksTo</code>.
134          * 
135          * <p>
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
139          * links.
140          * 
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 
146          */
147         public static boolean isLinkedToOtherThan(ReadGraph graph, Resource resourceToCheckForLinks,
148                         Resource excludeLinksTo)
149                                         throws DatabaseException
150         {
151                 Layer0 L0 = Layer0.getInstance(graph);
152                 for (Statement stm : graph.getStatements(resourceToCheckForLinks, L0.IsWeaklyRelatedTo)) {
153                         if (stm.isAsserted(resourceToCheckForLinks))
154                                 continue;
155                         if (stm.getPredicate().equals(L0.InstanceOf))
156                                 continue;
157                         Resource o = stm.getObject();
158                         if (o.equals(excludeLinksTo) || o.equals(resourceToCheckForLinks))
159                                 continue;
160
161                         return true;
162                 }
163                 return false;
164         }
165
166 }