]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/internal/validation/ValidateGraph.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.graph.compiler / src / org / simantics / graph / compiler / internal / validation / ValidateGraph.java
1 package org.simantics.graph.compiler.internal.validation;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.concurrent.Callable;
6
7 import org.simantics.graph.compiler.GraphCompilerPreferences;
8 import org.simantics.graph.compiler.ValidationMode;
9 import org.simantics.graph.compiler.internal.ltk.Location;
10 import org.simantics.graph.compiler.internal.ltk.Problem;
11 import org.simantics.graph.compiler.internal.store.LocationStore;
12 import org.simantics.graph.query.CompositeGraph;
13 import org.simantics.graph.query.Path;
14 import org.simantics.graph.query.Paths;
15 import org.simantics.graph.query.Res;
16 import org.simantics.graph.store.GraphStore;
17 import org.simantics.graph.store.IdRes;
18 import org.simantics.graph.utils.GraphExecutor;
19
20 public class ValidateGraph implements Runnable {
21         CompositeGraph graph;
22         Collection<Problem> problems;
23         GraphStore store;
24         GraphCompilerPreferences preferences;
25         Paths paths;
26
27         public ValidateGraph(CompositeGraph graph,
28                         Collection<Problem> problems,
29                         GraphStore store,
30                         GraphCompilerPreferences preferences) {
31                 this.graph = graph;
32                 this.problems = problems;
33                 this.store = store;
34                 this.preferences = preferences;
35                 this.paths = graph.getPaths();
36         }
37         
38         private void emit(int id, ValidationMode mode, String message) {
39                 LocationStore locations = store.getStore(LocationStore.class);
40                 Location location = locations.getLocation(id);
41                 Problem problem = new Problem(location, message);
42                 synchronized(problems) {                
43                         problems.add(problem);
44                 }
45         }
46
47         public void validate(int id, Res resource) {
48                 if(!graph.rawGetObjects(resource, paths.SubrelationOf).isEmpty()) {
49                         for(Res res : graph.rawGetObjects(resource, paths.InverseOf)) {
50                                 if(resource instanceof IdRes && res instanceof Path)
51                                         emit(id, ValidationMode.ERROR, "Resource " + resource + " doesn't have URI but its inverse has.");
52                                 if(res instanceof IdRes && resource instanceof Path) {
53                                         emit(store.resToId(res), ValidationMode.ERROR, "Resource " + res + " doesn't have URI but its inverse has.");
54                                 }
55                         }       
56                 }
57                 else {
58                         if(preferences.validateResourceHasType != ValidationMode.IGNORE) {
59                                 if(!graph.rawGetObjects(resource, paths.InstanceOf).isEmpty()) {
60                                 }
61                                 else if(!graph.rawGetObjects(resource, paths.Inherits).isEmpty()) {                     
62                                 }
63                                 else
64                                         emit(id, preferences.validateResourceHasType, "Resource " + resource + " does not have a type, it has to instantiate or inherit some other resource.");
65                         }
66                 }
67                 /*if(preferences.validateRelationRestrictions != ValidationMode.IGNORE) {
68                         store.statements.forStatementsWithSubject(id, new IStatementProcedure() {
69                                 @Override
70                                 public void execute(int s, int p, int o) {
71                                         
72                                 }
73                         });
74                 }*/
75         }
76
77         @Override
78         public void run() {
79                 int resourceCount = store.identities.getResourceCount();
80                 int segmentLength = Math.max(256, resourceCount / GraphExecutor.EXECUTOR_THREADS / 4 + 1);
81                 ArrayList<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
82                 for(int segmentStart_ = 0;segmentStart_ < resourceCount;segmentStart_ += segmentLength) {
83                         final int segmentStart = segmentStart_;
84                         final int segmentEnd = Math.min(segmentStart + segmentLength, resourceCount);
85                         tasks.add(new Callable<Object>() {
86                                 @Override
87                                 public Object call() {
88                                         for(int id = segmentStart;id<segmentEnd;++id) {
89                                                 Res res = store.idToRes(id);
90                                                 if(res instanceof Path) {
91                                                         if(store.identities.isNewResource(id)) {
92                                                                 if(graph.countOccurences(res) > 1) {
93                                                                         emit(id, ValidationMode.ERROR, "Resource " + res + " is already defined in dependencies, but it is marked new in this graph.");
94                                                                         continue;
95                                                                 }
96                                                         }
97                                                         else {
98                                                                 if(graph.countOccurences(res) <= 1) {
99                                                                         emit(id, ValidationMode.ERROR, "Resource " + res + " is not defined in dependencies and it is not marked new in this graph.");
100                                                                         continue;
101                                                                 }
102                                                         }
103                                                 }                               
104                                                 validate(id, res);
105                                         }
106                                         return null;
107                                 }
108                         });                     
109                 }
110                 try {
111                         GraphExecutor.EXECUTOR.invokeAll(tasks);
112                 } catch (InterruptedException e) {
113                         throw new RuntimeException(e);
114                 }
115         }
116         
117 }