1 package org.simantics.graph.compiler.internal.validation;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.concurrent.Callable;
7 import org.simantics.graph.compiler.GraphCompilerPreferences;
8 import org.simantics.graph.compiler.ValidationMode;
9 import org.simantics.graph.compiler.internal.store.LocationStore;
10 import org.simantics.graph.query.CompositeGraph;
11 import org.simantics.graph.query.Path;
12 import org.simantics.graph.query.Paths;
13 import org.simantics.graph.query.Res;
14 import org.simantics.graph.store.GraphStore;
15 import org.simantics.graph.store.IdRes;
16 import org.simantics.graph.utils.GraphExecutor;
17 import org.simantics.ltk.Location;
18 import org.simantics.ltk.Problem;
20 public class ValidateGraph implements Runnable {
22 Collection<Problem> problems;
24 GraphCompilerPreferences preferences;
27 public ValidateGraph(CompositeGraph graph,
28 Collection<Problem> problems,
30 GraphCompilerPreferences preferences) {
32 this.problems = problems;
34 this.preferences = preferences;
35 this.paths = graph.getPaths();
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);
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.");
58 if(preferences.validateResourceHasType != ValidationMode.IGNORE) {
59 if(!graph.rawGetObjects(resource, paths.InstanceOf).isEmpty()) {
61 else if(!graph.rawGetObjects(resource, paths.Inherits).isEmpty()) {
64 emit(id, preferences.validateResourceHasType, "Resource " + resource + " does not have a type, it has to instantiate or inherit some other resource.");
67 /*if(preferences.validateRelationRestrictions != ValidationMode.IGNORE) {
68 store.statements.forStatementsWithSubject(id, new IStatementProcedure() {
70 public void execute(int s, int p, int o) {
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>() {
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.");
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.");
111 GraphExecutor.EXECUTOR.invokeAll(tasks);
112 } catch (InterruptedException e) {
113 throw new RuntimeException(e);