1 package org.simantics.db.layer0.validation;
3 import java.util.Collection;
4 import java.util.HashSet;
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;
21 public class ChangeSetValidator implements ChangeListener {
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);
28 public void graphChanged(ChangeEvent e) throws DatabaseException {
29 ChangeSet changeSet = e.getChanges();
30 ReadGraph g = e.getGraph();
31 // Layer0 l0 = Layer0.getInstance(g);
33 HashSet<Resource> allResources = new HashSet<Resource>();
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.");
50 // else if(predicate == l0.SubrelationOf) {
51 // if(!isRelation(g, l0, object)) {
52 // reportInconsistency(g, subject, "The range of SubrelationOf relation is Relation.");
55 // else if(predicate == l0.Inherits) {
56 // if(!isType(g, l0, object)) {
57 // reportInconsistency(g, subject, "The range of Inherits relation is Type.");
61 // if(!isRelation(g, l0, predicate)) {
62 // reportInconsistency(g, subject, "The predicate of a statement must be a relation.");
65 // if(g.isInstanceOf(predicate, l0.FunctionalRelation)) {
66 // if(g.getObjects(subject, predicate).size() > 1)
67 // reportInconsistency(g, subject,
69 // NameUtils.getSafeName(g, predicate)
70 // + " is functional.");
72 // if(g.isSubrelationOf(predicate, l0.HasProperty)) {
73 // String error = L0Validations.checkValueType(g, subject, predicate);
74 // if(error != null) reportInconsistency(g, subject, error);
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());
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());
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.");
114 // // TODO check that the value is valid for the data type
118 // if(g.isInstanceOf(resource, l0.Literal)) {
119 // reportInconsistency(g, resource,
120 // "Resource is a literal but it does not have a value.");
125 Layer0 L0 = Layer0.getInstance(g);
127 for(Resource r : allResources) {
131 for(Resource constraint : g.sync(new GetConstraints(r))) {
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()));
142 } catch (Throwable t) {
143 Logger.defaultLogError(t);
148 } catch (Throwable t) {
149 Logger.defaultLogError(t);
156 private boolean isInstanceOfAny(ReadGraph graph, Resource r, Collection<Resource> types, boolean ifEmpty) throws DatabaseException {
159 for (Resource type : types) {
160 if (graph.isInstanceOf(r, type)) {
167 private StringBuilder orString(ReadGraph graph, StringBuilder sb, Collection<Resource> rs) throws DatabaseException {
169 boolean first = true;
170 for (Resource r : rs) {
174 sb.append(NameUtils.getSafeName(graph, r));
180 public static boolean isRelation(ReadGraph g, Layer0 l0, Resource relation) throws DatabaseException {
181 return g.hasStatement(relation, l0.SubrelationOf) || relation == l0.IsWeaklyRelatedTo;
184 public static boolean isType(ReadGraph g, Layer0 l0, Resource type) throws DatabaseException {
185 return g.hasStatement(type, l0.Inherits) || type == l0.Entity;