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