-package org.simantics.db.layer0.validation;\r
-\r
-import java.util.Collection;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-\r
-import org.simantics.db.ChangeSet;\r
-import org.simantics.db.ChangeSet.StatementChange;\r
-import org.simantics.db.Issue;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.common.utils.Functions;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.event.ChangeEvent;\r
-import org.simantics.db.event.ChangeListener;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.layer0.Layer0;\r
-\r
-public class ChangeSetValidator implements ChangeListener {\r
-\r
- void reportInconsistency(ReadGraph graph, Resource subject, String description) throws DatabaseException {\r
- System.err.println("Change set validation reports the following issue: " + NameUtils.getSafeName(graph, subject, true) + ": " + description);\r
- }\r
- \r
- @Override\r
- public void graphChanged(ChangeEvent e) throws DatabaseException { \r
- ChangeSet changeSet = e.getChanges();\r
- ReadGraph g = e.getGraph();\r
-// Layer0 l0 = Layer0.getInstance(g);\r
- \r
- HashSet<Resource> allResources = new HashSet<Resource>();\r
- \r
- for(StatementChange change : changeSet.changedStatements()) {\r
- allResources.add(change.getSubject());\r
- allResources.add(change.getObject());\r
-// if(change.isClaim()) {\r
-// Resource subject = change.getSubject(); \r
-// Resource predicate = change.getPredicate();\r
-// Resource object = change.getObject();\r
-// if(predicate == l0.InstanceOf) {\r
-// if(!isType(g, l0, object)) {\r
-// reportInconsistency(g, subject, "The range of InstanceOf relation is Type.");\r
-// }\r
-// else {\r
-// // TODO\r
-// }\r
-// }\r
-// else if(predicate == l0.SubrelationOf) {\r
-// if(!isRelation(g, l0, object)) {\r
-// reportInconsistency(g, subject, "The range of SubrelationOf relation is Relation.");\r
-// }\r
-// }\r
-// else if(predicate == l0.Inherits) {\r
-// if(!isType(g, l0, object)) {\r
-// reportInconsistency(g, subject, "The range of Inherits relation is Type.");\r
-// }\r
-// }\r
-// else {\r
-// if(!isRelation(g, l0, predicate)) {\r
-// reportInconsistency(g, subject, "The predicate of a statement must be a relation.");\r
-// }\r
-// else {\r
-// if(g.isInstanceOf(predicate, l0.FunctionalRelation)) {\r
-// if(g.getObjects(subject, predicate).size() > 1)\r
-// reportInconsistency(g, subject, \r
-// "Relation " +\r
-// NameUtils.getSafeName(g, predicate)\r
-// + " is functional.");\r
-// }\r
-// if(g.isSubrelationOf(predicate, l0.HasProperty)) {\r
-// String error = L0Validations.checkValueType(g, subject, predicate);\r
-// if(error != null) reportInconsistency(g, subject, error);\r
-// }\r
-// {\r
-// Collection<Resource> domain = g.getObjects(predicate, l0.HasDomain);\r
-// if (!isInstanceOfAny(g, subject, domain, true)) {\r
-// StringBuilder sb = new StringBuilder()\r
-// .append("The domain of ")\r
-// .append(NameUtils.getSafeName(g, predicate))\r
-// .append(" relation is ");\r
-// orString(g, sb, domain).append(".");\r
-// reportInconsistency(g, subject, sb.toString());\r
-// }\r
-// }\r
-// {\r
-// Collection<Resource> range = g.getObjects(predicate, l0.HasRange);\r
-// if (!isInstanceOfAny(g, object, range, true)) {\r
-// StringBuilder sb = new StringBuilder()\r
-// .append("The range of ")\r
-// .append(NameUtils.getSafeName(g, predicate))\r
-// .append(" relation is ");\r
-// orString(g, sb, range).append(".");\r
-// reportInconsistency(g, object, sb.toString());\r
-// }\r
-// }\r
-// }\r
-// }\r
-// }\r
-// else {\r
-// // TODO\r
-// }\r
- }\r
- \r
- for(Resource resource : changeSet.changedValues()) {\r
- allResources.add(resource);\r
-// if(g.hasValue(resource)) {\r
-// if(!g.isInstanceOf(resource, l0.Literal)) {\r
-// reportInconsistency(g, resource, \r
-// "Resource has a value but it is not a literal.");\r
-// }\r
-// else {\r
-// // TODO check that the value is valid for the data type\r
-// }\r
-// }\r
-// else {\r
-// if(g.isInstanceOf(resource, l0.Literal)) {\r
-// reportInconsistency(g, resource, \r
-// "Resource is a literal but it does not have a value.");\r
-// }\r
-// }\r
- }\r
- \r
- Layer0 L0 = Layer0.getInstance(g);\r
-\r
- for(Resource r : allResources) {\r
- \r
- try {\r
-\r
- for(Resource constraint : g.sync(new GetConstraints(r))) {\r
-\r
- try {\r
-\r
- Resource function = g.getSingleObject(constraint, L0.Constraint_Validator);\r
- @SuppressWarnings("unchecked")\r
- Set<Issue> contexts = new HashSet<Issue>((List<Issue>)Functions.exec(g, function, g, r));\r
- for(Issue i : contexts) {\r
- reportInconsistency(g, r, g.getURI(i.getType()));\r
- }\r
-\r
- } catch (Throwable t) {\r
- Logger.defaultLogError(t);\r
- }\r
- \r
- }\r
-\r
- } catch (Throwable t) {\r
- Logger.defaultLogError(t);\r
- }\r
- \r
- }\r
- \r
- }\r
-\r
- private boolean isInstanceOfAny(ReadGraph graph, Resource r, Collection<Resource> types, boolean ifEmpty) throws DatabaseException {\r
- if (types.isEmpty())\r
- return ifEmpty;\r
- for (Resource type : types) {\r
- if (graph.isInstanceOf(r, type)) {\r
- return true;\r
- }\r
- }\r
- return false;\r
- }\r
-\r
- private StringBuilder orString(ReadGraph graph, StringBuilder sb, Collection<Resource> rs) throws DatabaseException {\r
- sb.append("(");\r
- boolean first = true;\r
- for (Resource r : rs) {\r
- if (!first)\r
- sb.append(" | ");\r
- first = false;\r
- sb.append(NameUtils.getSafeName(graph, r));\r
- }\r
- sb.append(")");\r
- return sb;\r
- }\r
-\r
- public static boolean isRelation(ReadGraph g, Layer0 l0, Resource relation) throws DatabaseException {\r
- return g.hasStatement(relation, l0.SubrelationOf) || relation == l0.IsWeaklyRelatedTo;\r
- }\r
- \r
- public static boolean isType(ReadGraph g, Layer0 l0, Resource type) throws DatabaseException {\r
- return g.hasStatement(type, l0.Inherits) || type == l0.Entity;\r
- }\r
- \r
-}\r
+package org.simantics.db.layer0.validation;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.simantics.db.ChangeSet;
+import org.simantics.db.ChangeSet.StatementChange;
+import org.simantics.db.Issue;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.utils.Functions;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.event.ChangeEvent;
+import org.simantics.db.event.ChangeListener;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+
+public class ChangeSetValidator implements ChangeListener {
+
+ void reportInconsistency(ReadGraph graph, Resource subject, String description) throws DatabaseException {
+ System.err.println("Change set validation reports the following issue: " + NameUtils.getSafeName(graph, subject, true) + ": " + description);
+ }
+
+ @Override
+ public void graphChanged(ChangeEvent e) throws DatabaseException {
+ ChangeSet changeSet = e.getChanges();
+ ReadGraph g = e.getGraph();
+// Layer0 l0 = Layer0.getInstance(g);
+
+ HashSet<Resource> allResources = new HashSet<Resource>();
+
+ for(StatementChange change : changeSet.changedStatements()) {
+ allResources.add(change.getSubject());
+ allResources.add(change.getObject());
+// if(change.isClaim()) {
+// Resource subject = change.getSubject();
+// Resource predicate = change.getPredicate();
+// Resource object = change.getObject();
+// if(predicate == l0.InstanceOf) {
+// if(!isType(g, l0, object)) {
+// reportInconsistency(g, subject, "The range of InstanceOf relation is Type.");
+// }
+// else {
+// // TODO
+// }
+// }
+// else if(predicate == l0.SubrelationOf) {
+// if(!isRelation(g, l0, object)) {
+// reportInconsistency(g, subject, "The range of SubrelationOf relation is Relation.");
+// }
+// }
+// else if(predicate == l0.Inherits) {
+// if(!isType(g, l0, object)) {
+// reportInconsistency(g, subject, "The range of Inherits relation is Type.");
+// }
+// }
+// else {
+// if(!isRelation(g, l0, predicate)) {
+// reportInconsistency(g, subject, "The predicate of a statement must be a relation.");
+// }
+// else {
+// if(g.isInstanceOf(predicate, l0.FunctionalRelation)) {
+// if(g.getObjects(subject, predicate).size() > 1)
+// reportInconsistency(g, subject,
+// "Relation " +
+// NameUtils.getSafeName(g, predicate)
+// + " is functional.");
+// }
+// if(g.isSubrelationOf(predicate, l0.HasProperty)) {
+// String error = L0Validations.checkValueType(g, subject, predicate);
+// if(error != null) reportInconsistency(g, subject, error);
+// }
+// {
+// Collection<Resource> domain = g.getObjects(predicate, l0.HasDomain);
+// if (!isInstanceOfAny(g, subject, domain, true)) {
+// StringBuilder sb = new StringBuilder()
+// .append("The domain of ")
+// .append(NameUtils.getSafeName(g, predicate))
+// .append(" relation is ");
+// orString(g, sb, domain).append(".");
+// reportInconsistency(g, subject, sb.toString());
+// }
+// }
+// {
+// Collection<Resource> range = g.getObjects(predicate, l0.HasRange);
+// if (!isInstanceOfAny(g, object, range, true)) {
+// StringBuilder sb = new StringBuilder()
+// .append("The range of ")
+// .append(NameUtils.getSafeName(g, predicate))
+// .append(" relation is ");
+// orString(g, sb, range).append(".");
+// reportInconsistency(g, object, sb.toString());
+// }
+// }
+// }
+// }
+// }
+// else {
+// // TODO
+// }
+ }
+
+ for(Resource resource : changeSet.changedValues()) {
+ allResources.add(resource);
+// if(g.hasValue(resource)) {
+// if(!g.isInstanceOf(resource, l0.Literal)) {
+// reportInconsistency(g, resource,
+// "Resource has a value but it is not a literal.");
+// }
+// else {
+// // TODO check that the value is valid for the data type
+// }
+// }
+// else {
+// if(g.isInstanceOf(resource, l0.Literal)) {
+// reportInconsistency(g, resource,
+// "Resource is a literal but it does not have a value.");
+// }
+// }
+ }
+
+ Layer0 L0 = Layer0.getInstance(g);
+
+ for(Resource r : allResources) {
+
+ try {
+
+ for(Resource constraint : g.sync(new GetConstraints(r))) {
+
+ try {
+
+ Resource function = g.getSingleObject(constraint, L0.Constraint_Validator);
+ @SuppressWarnings("unchecked")
+ Set<Issue> contexts = new HashSet<Issue>((List<Issue>)Functions.exec(g, function, g, r));
+ for(Issue i : contexts) {
+ reportInconsistency(g, r, g.getURI(i.getType()));
+ }
+
+ } catch (Throwable t) {
+ Logger.defaultLogError(t);
+ }
+
+ }
+
+ } catch (Throwable t) {
+ Logger.defaultLogError(t);
+ }
+
+ }
+
+ }
+
+ private boolean isInstanceOfAny(ReadGraph graph, Resource r, Collection<Resource> types, boolean ifEmpty) throws DatabaseException {
+ if (types.isEmpty())
+ return ifEmpty;
+ for (Resource type : types) {
+ if (graph.isInstanceOf(r, type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private StringBuilder orString(ReadGraph graph, StringBuilder sb, Collection<Resource> rs) throws DatabaseException {
+ sb.append("(");
+ boolean first = true;
+ for (Resource r : rs) {
+ if (!first)
+ sb.append(" | ");
+ first = false;
+ sb.append(NameUtils.getSafeName(graph, r));
+ }
+ sb.append(")");
+ return sb;
+ }
+
+ public static boolean isRelation(ReadGraph g, Layer0 l0, Resource relation) throws DatabaseException {
+ return g.hasStatement(relation, l0.SubrelationOf) || relation == l0.IsWeaklyRelatedTo;
+ }
+
+ public static boolean isType(ReadGraph g, Layer0 l0, Resource type) throws DatabaseException {
+ return g.hasStatement(type, l0.Inherits) || type == l0.Entity;
+ }
+
+}