]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/validation/ChangeSetValidator.java
Fixed ProfileObserver.update race with multiple query threads
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / validation / ChangeSetValidator.java
1 package org.simantics.db.layer0.validation;
2
3 import java.util.Collection;
4 import java.util.HashSet;
5 import java.util.List;
6 import java.util.Set;
7
8 import org.simantics.db.ChangeSet;
9 import org.simantics.db.ChangeSet.StatementChange;
10 import org.simantics.db.Issue;
11 import org.simantics.db.ReadGraph;
12 import org.simantics.db.Resource;
13 import org.simantics.db.common.utils.Functions;
14 import org.simantics.db.common.utils.Logger;
15 import org.simantics.db.common.utils.NameUtils;
16 import org.simantics.db.event.ChangeEvent;
17 import org.simantics.db.event.ChangeListener;
18 import org.simantics.db.exception.DatabaseException;
19 import org.simantics.layer0.Layer0;
20
21 public class ChangeSetValidator implements ChangeListener {
22
23         void reportInconsistency(ReadGraph graph, Resource subject, String description) throws DatabaseException {
24                 System.err.println("Change set validation reports the following issue: " + NameUtils.getSafeName(graph, subject, true) + ": " + description);
25         }
26         
27         @Override
28         public void graphChanged(ChangeEvent e) throws DatabaseException {    
29                 ChangeSet changeSet = e.getChanges();
30                 ReadGraph g = e.getGraph();
31 //              Layer0 l0 = Layer0.getInstance(g);
32                 
33                 HashSet<Resource> allResources = new HashSet<Resource>();
34                 
35                 for(StatementChange change : changeSet.changedStatements()) {
36                         allResources.add(change.getSubject());
37                         allResources.add(change.getObject());
38 //                      if(change.isClaim()) {
39 //                              Resource subject = change.getSubject();                 
40 //                              Resource predicate = change.getPredicate();
41 //                              Resource object = change.getObject();
42 //                              if(predicate == l0.InstanceOf) {
43 //                                      if(!isType(g, l0, object)) {
44 //                                              reportInconsistency(g, subject, "The range of InstanceOf relation is Type.");
45 //                                      }
46 //                                      else {
47 //                                              // TODO
48 //                                      }
49 //                              }
50 //                              else if(predicate == l0.SubrelationOf) {
51 //                                      if(!isRelation(g, l0, object)) {
52 //                                              reportInconsistency(g, subject, "The range of SubrelationOf relation is Relation.");
53 //                                      }
54 //                              }
55 //                              else if(predicate == l0.Inherits) {
56 //                                      if(!isType(g, l0, object)) {
57 //                                              reportInconsistency(g, subject, "The range of Inherits relation is Type.");
58 //                                      }
59 //                              }
60 //                              else {
61 //                                      if(!isRelation(g, l0, predicate)) {
62 //                                              reportInconsistency(g, subject, "The predicate of a statement must be a relation.");
63 //                                      }
64 //                                      else {
65 //                                          if(g.isInstanceOf(predicate, l0.FunctionalRelation)) {
66 //                                              if(g.getObjects(subject, predicate).size() > 1)
67 //                                                  reportInconsistency(g, subject, 
68 //                                        "Relation " +
69 //                                        NameUtils.getSafeName(g, predicate)
70 //                                        + " is functional.");
71 //                                          }
72 //                                          if(g.isSubrelationOf(predicate, l0.HasProperty)) {
73 //                                              String error = L0Validations.checkValueType(g, subject, predicate);
74 //                                              if(error != null) reportInconsistency(g, subject, error);
75 //                                          }
76 //                                              {
77 //                                                      Collection<Resource> domain = g.getObjects(predicate, l0.HasDomain);
78 //                                                      if (!isInstanceOfAny(g, subject, domain, true)) {
79 //                                                              StringBuilder sb = new StringBuilder()
80 //                                                              .append("The domain of ")
81 //                                                              .append(NameUtils.getSafeName(g, predicate))
82 //                                                              .append(" relation is ");
83 //                                                              orString(g, sb, domain).append(".");
84 //                                                              reportInconsistency(g, subject, sb.toString());
85 //                                                      }
86 //                                              }
87 //                                              {
88 //                                                      Collection<Resource> range = g.getObjects(predicate, l0.HasRange);
89 //                                                      if (!isInstanceOfAny(g, object, range, true)) {
90 //                                                              StringBuilder sb = new StringBuilder()
91 //                                                              .append("The range of ")
92 //                                                              .append(NameUtils.getSafeName(g, predicate))
93 //                                                              .append(" relation is ");
94 //                                                              orString(g, sb, range).append(".");
95 //                                                              reportInconsistency(g, object, sb.toString());
96 //                                                      }
97 //                                              }
98 //                                      }
99 //                              }
100 //                      }
101 //                      else {
102 //                          // TODO
103 //                      }
104                 }
105                 
106                 for(Resource resource : changeSet.changedValues()) {
107                         allResources.add(resource);
108 //                      if(g.hasValue(resource)) {
109 //                              if(!g.isInstanceOf(resource, l0.Literal)) {
110 //                                  reportInconsistency(g, resource, 
111 //                            "Resource has a value but it is not a literal.");
112 //                              }
113 //                              else {
114 //                                      // TODO check that the value is valid for the data type
115 //                              }
116 //                      }
117 //                      else {
118 //                              if(g.isInstanceOf(resource, l0.Literal)) {
119 //                                  reportInconsistency(g, resource, 
120 //                        "Resource is a literal but it does not have a value.");
121 //                              }
122 //                      }
123                 }
124                 
125                 Layer0 L0 = Layer0.getInstance(g);
126
127                 for(Resource r : allResources) {
128                         
129                         try {
130
131                                 for(Resource constraint : g.sync(new GetConstraints(r))) {
132
133                                         try {
134
135                                                 Resource function = g.getSingleObject(constraint, L0.Constraint_Validator);
136                                                 @SuppressWarnings("unchecked")
137                                                 Set<Issue> contexts = new HashSet<Issue>((List<Issue>)Functions.exec(g, function, g, r));
138                                                 for(Issue i : contexts) {
139                                                         reportInconsistency(g, r, g.getURI(i.getType()));
140                                                 }
141
142                                         } catch (Throwable t) {
143                                                 Logger.defaultLogError(t);
144                                         }
145                                         
146                                 }
147
148                         } catch (Throwable t) {
149                                 Logger.defaultLogError(t);
150                         }
151                         
152                 }
153                 
154         }
155
156         private boolean isInstanceOfAny(ReadGraph graph, Resource r, Collection<Resource> types, boolean ifEmpty) throws DatabaseException {
157                 if (types.isEmpty())
158                         return ifEmpty;
159                 for (Resource type : types) {
160                         if (graph.isInstanceOf(r, type)) {
161                                 return true;
162                         }
163                 }
164                 return false;
165         }
166
167         private StringBuilder orString(ReadGraph graph, StringBuilder sb, Collection<Resource> rs) throws DatabaseException {
168                 sb.append("(");
169                 boolean first = true;
170                 for (Resource r : rs) {
171                         if (!first)
172                                 sb.append(" | ");
173                         first = false;
174                         sb.append(NameUtils.getSafeName(graph, r));
175                 }
176                 sb.append(")");
177                 return sb;
178         }
179
180     public static boolean isRelation(ReadGraph g, Layer0 l0, Resource relation) throws DatabaseException {
181                 return g.hasStatement(relation, l0.SubrelationOf) || relation == l0.IsWeaklyRelatedTo;
182         }
183         
184         public static boolean isType(ReadGraph g, Layer0 l0, Resource type) throws DatabaseException {
185                 return g.hasStatement(type, l0.Inherits) || type == l0.Entity;
186         }
187         
188 }