1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| |
16 |
| |
17 |
| package org.deri.wsmo4j.validator; |
18 |
| |
19 |
| |
20 |
| import java.util.*; |
21 |
| |
22 |
| import org.deri.wsmo4j.io.serializer.wsml.*; |
23 |
| import org.deri.wsmo4j.logicalexpression.*; |
24 |
| import org.omwg.logicalexpression.*; |
25 |
| import org.omwg.ontology.*; |
26 |
| import org.wsmo.common.*; |
27 |
| import org.wsmo.common.exception.*; |
28 |
| import org.wsmo.factory.LogicalExpressionFactory; |
29 |
| import org.wsmo.service.Capability; |
30 |
| import org.wsmo.service.Goal; |
31 |
| import org.wsmo.service.WebService; |
32 |
| import org.wsmo.validator.*; |
33 |
| |
34 |
| |
35 |
| |
36 |
| |
37 |
| |
38 |
| |
39 |
| |
40 |
| |
41 |
| |
42 |
| |
43 |
| |
44 |
| |
45 |
| |
46 |
| |
47 |
| |
48 |
| public class WsmlFullValidator |
49 |
| implements Validator { |
50 |
| |
51 |
| private Ontology ontology = null; |
52 |
| |
53 |
| private AnonIdCollectHelper helper = null; |
54 |
| |
55 |
| protected ConstantTransformer constants = ConstantTransformer.getInstance(); |
56 |
| |
57 |
| protected List <ValidationError> errors = null; |
58 |
| |
59 |
| protected List <ValidationWarning> warnings = null; |
60 |
| |
61 |
| protected LogExprSerializerWSML leSerializer = null; |
62 |
| |
63 |
| protected LogicalExpressionFactory leFactory = null; |
64 |
| |
65 |
0
| public WsmlFullValidator(LogicalExpressionFactory leFactory) {
|
66 |
0
| this.leFactory = leFactory;
|
67 |
| } |
68 |
| |
69 |
| |
70 |
| |
71 |
| |
72 |
| |
73 |
| |
74 |
0
| protected void visitAxiom(Axiom axiom) {
|
75 |
0
| WsmlFullExpressionValidator exprVal = new WsmlFullExpressionValidator(axiom, errors);
|
76 |
0
| Iterator axioms = axiom.listDefinitions().iterator();
|
77 |
0
| while (axioms.hasNext()) {
|
78 |
0
| ((LogicalExpression)axioms.next()).accept(exprVal);
|
79 |
| } |
80 |
| } |
81 |
| |
82 |
| |
83 |
| |
84 |
| |
85 |
| |
86 |
| |
87 |
0
| protected void visitConcept(Concept concept) {
|
88 |
| |
89 |
| |
90 |
| |
91 |
0
| Iterator i = concept.listAttributes().iterator();
|
92 |
0
| while (i.hasNext()) {
|
93 |
0
| Attribute a = (Attribute)i.next();
|
94 |
0
| if (a.listTypes().size() == 0) {
|
95 |
0
| if (a.getIdentifier() instanceof IRI) {
|
96 |
0
| if (concept.getIdentifier() instanceof IRI) {
|
97 |
0
| addError(concept, a, ValidationError.ATTR_ERR + ":\n" +
|
98 |
| "Attributes must have a range specified (" |
99 |
| + ((IRI) a.getIdentifier()).getLocalName() + " at Concept " |
100 |
| + ((IRI) concept.getIdentifier()).getLocalName() + ")"); |
101 |
| } |
102 |
| else { |
103 |
0
| addError(concept, a, ValidationError.ATTR_ERR + ":\n" +
|
104 |
| "Attributes must have a range specified (" |
105 |
| + ((IRI) a.getIdentifier()).getLocalName() + " at Concept " |
106 |
| + concept.getIdentifier().toString() + ")"); |
107 |
| } |
108 |
| } |
109 |
| else { |
110 |
0
| if (concept.getIdentifier() instanceof IRI) {
|
111 |
0
| addError(concept, a, ValidationError.ATTR_ERR + ":\n" +
|
112 |
| "Attributes must have a range specified (" |
113 |
| + a.getIdentifier().toString() + " at Concept " |
114 |
| + ((IRI) concept.getIdentifier()).getLocalName() + ")"); |
115 |
| } |
116 |
| else { |
117 |
0
| addError(concept, a, ValidationError.ATTR_ERR + ":\n" +
|
118 |
| "Attributes must have a range specified (" |
119 |
| + a.getIdentifier().toString() + " at Concept " |
120 |
| + concept.getIdentifier().toString() + ")"); |
121 |
| } |
122 |
| } |
123 |
| } |
124 |
0
| if (a.isReflexive()) {
|
125 |
0
| Iterator it = a.listTypes().iterator();
|
126 |
0
| while (it.hasNext()) {
|
127 |
0
| if (it.next() instanceof WsmlDataType) {
|
128 |
0
| addError(concept, a, ValidationError.ATTR_ERR + ":\n" +
|
129 |
| "Attribute features are not allowed on attributes " + |
130 |
| "with a data type in its range (" |
131 |
| + a.getIdentifier().toString() + " at Concept " |
132 |
| + concept.getIdentifier().toString() + ")"); |
133 |
| } |
134 |
| } |
135 |
| } |
136 |
0
| if (a.isSymmetric()) {
|
137 |
0
| Iterator it = a.listTypes().iterator();
|
138 |
0
| while (it.hasNext()) {
|
139 |
0
| if (it.next() instanceof WsmlDataType) {
|
140 |
0
| addError(concept, a, ValidationError.ATTR_ERR + ":\n" +
|
141 |
| "Attribute features are not allowed on attributes " + |
142 |
| "with a data type in its range (" |
143 |
| + a.getIdentifier().toString() + " at Concept " |
144 |
| + concept.getIdentifier().toString() + ")"); |
145 |
| } |
146 |
| } |
147 |
| } |
148 |
0
| if (a.isTransitive()) {
|
149 |
0
| Iterator it = a.listTypes().iterator();
|
150 |
0
| while (it.hasNext()) {
|
151 |
0
| if (it.next() instanceof WsmlDataType) {
|
152 |
0
| addError(concept, a, ValidationError.ATTR_ERR + ":\n" +
|
153 |
| "Attribute features are not allowed on attributes " + |
154 |
| "with a data type in its range (" |
155 |
| + a.getIdentifier().toString() + " at Concept " |
156 |
| + concept.getIdentifier().toString() + ")"); |
157 |
| } |
158 |
| } |
159 |
| } |
160 |
0
| if (a.getInverseOf() != null) {
|
161 |
0
| Iterator it = a.listTypes().iterator();
|
162 |
0
| while (it.hasNext()) {
|
163 |
0
| if (it.next() instanceof WsmlDataType) {
|
164 |
0
| addError(concept, a, ValidationError.ATTR_ERR + ":\n" +
|
165 |
| "Attribute features are not allowed on attributes " + |
166 |
| "with a data type in its range (" |
167 |
| + a.getIdentifier().toString() + " at Concept " |
168 |
| + concept.getIdentifier().toString() + ")"); |
169 |
| } |
170 |
| } |
171 |
| } |
172 |
| } |
173 |
| } |
174 |
| |
175 |
| |
176 |
| |
177 |
| |
178 |
| |
179 |
| |
180 |
0
| protected void visitInstance(Instance instance) {
|
181 |
| |
182 |
| } |
183 |
| |
184 |
| |
185 |
| |
186 |
| |
187 |
| |
188 |
| |
189 |
0
| protected void visitRelation(Relation relation) {
|
190 |
0
| int parameterCount = relation.listParameters().size();
|
191 |
0
| if (parameterCount == 0) {
|
192 |
0
| if (relation.getIdentifier() instanceof IRI) {
|
193 |
0
| addError(relation, ValidationError.REL_ARITY_ERR + ":\n" +
|
194 |
| "Relation must have arity specified (" |
195 |
| + ((IRI) relation.getIdentifier()).getLocalName() + ")"); |
196 |
| } |
197 |
| else { |
198 |
0
| addError(relation, ValidationError.REL_ARITY_ERR + ":\n" +
|
199 |
| "Relation must have arity specified (" |
200 |
| + relation.getIdentifier().toString() + ")"); |
201 |
| } |
202 |
0
| return;
|
203 |
| } |
204 |
0
| Iterator i = relation.listParameters().iterator();
|
205 |
0
| int specifiedParameters=0;
|
206 |
0
| while (i.hasNext()) {
|
207 |
0
| Parameter p = (Parameter)i.next();
|
208 |
0
| if (p.listTypes().size() == 0) {
|
209 |
0
| specifiedParameters++;
|
210 |
| } |
211 |
| } |
212 |
0
| if (parameterCount != specifiedParameters && specifiedParameters != 0) {
|
213 |
0
| if (relation.getIdentifier() instanceof IRI) {
|
214 |
0
| addError(relation, ValidationError.REL_ERR + ":\n" +
|
215 |
| "Either all Parameter or none must be specified\n" + |
216 |
| "(in relation " + ((IRI) relation.getIdentifier()).getLocalName() + ")"); |
217 |
| } |
218 |
| else { |
219 |
0
| addError(relation, ValidationError.REL_ERR + ":\n" +
|
220 |
| "Either all Parameter or none must be specified\n" + |
221 |
| "(in relation " + relation.getIdentifier().toString() + ")"); |
222 |
| } |
223 |
| } |
224 |
| |
225 |
| } |
226 |
| |
227 |
| |
228 |
| |
229 |
| |
230 |
| |
231 |
| |
232 |
| |
233 |
| |
234 |
| |
235 |
| |
236 |
| |
237 |
0
| protected void visitRelationInstance(RelationInstance relationInstance)
|
238 |
| throws SynchronisationException, InvalidModelException { |
239 |
0
| if (relationInstance.getRelation() == null) {
|
240 |
0
| if (relationInstance.getIdentifier() instanceof IRI) {
|
241 |
0
| addError(relationInstance, ValidationError.REL_INST_ERR + ":\n" +
|
242 |
| "RelationInstances must be associated to an Relation " |
243 |
| + "(" + ((IRI) relationInstance.getIdentifier()).getLocalName() + ")"); |
244 |
| } |
245 |
| else { |
246 |
0
| addError(relationInstance, ValidationError.REL_INST_ERR + ":\n" +
|
247 |
| "RelationInstances must be associated to an Relation " |
248 |
| + "(" + relationInstance.getIdentifier().toString() + ")"); |
249 |
| } |
250 |
| } |
251 |
| } |
252 |
| |
253 |
| |
254 |
| |
255 |
| |
256 |
| |
257 |
0
| public Collection getErrors() {
|
258 |
0
| return errors;
|
259 |
| } |
260 |
| |
261 |
| |
262 |
| |
263 |
| |
264 |
| |
265 |
| |
266 |
| |
267 |
| |
268 |
| |
269 |
| |
270 |
| |
271 |
| |
272 |
| |
273 |
| |
274 |
| |
275 |
0
| public boolean isValid(TopEntity te, List <ValidationError> errorMessages, List <ValidationWarning> warningMessages) {
|
276 |
0
| leSerializer = new LogExprSerializerWSML(te);
|
277 |
0
| errors = errorMessages;
|
278 |
0
| warnings = warningMessages;
|
279 |
0
| if (te instanceof Ontology) {
|
280 |
0
| ontology = (Ontology)te;
|
281 |
| |
282 |
0
| helper = new AnonIdCollectHelper(errors);
|
283 |
0
| helper.checkAnonIds(ontology);
|
284 |
0
| Iterator i = ontology.listConcepts().iterator();
|
285 |
0
| while (i.hasNext()) {
|
286 |
0
| visitConcept((Concept)i.next());
|
287 |
| } |
288 |
0
| i = ontology.listInstances().iterator();
|
289 |
0
| while (i.hasNext()) {
|
290 |
0
| visitInstance((Instance)i.next());
|
291 |
| } |
292 |
| |
293 |
0
| i = ontology.listRelations().iterator();
|
294 |
0
| while (i.hasNext()) {
|
295 |
0
| visitRelation((Relation)i.next());
|
296 |
| } |
297 |
| |
298 |
0
| i = ontology.listRelationInstances().iterator();
|
299 |
0
| while (i.hasNext()) {
|
300 |
0
| try {
|
301 |
0
| visitRelationInstance((RelationInstance)i.next());
|
302 |
| } |
303 |
| catch (InvalidModelException ime) { |
304 |
0
| new RuntimeException(ime);
|
305 |
| } |
306 |
| } |
307 |
| |
308 |
0
| i = ontology.listAxioms().iterator();
|
309 |
0
| while (i.hasNext()) {
|
310 |
0
| visitAxiom((Axiom)i.next());
|
311 |
| } |
312 |
| } |
313 |
0
| else if (te instanceof WebService || te instanceof Goal) {
|
314 |
0
| Capability capa = null;
|
315 |
0
| if (te instanceof WebService) {
|
316 |
0
| WebService webServ = (WebService) te;
|
317 |
0
| capa = webServ.getCapability();
|
318 |
| } |
319 |
0
| else if (te instanceof Goal) {
|
320 |
0
| Goal goal = (Goal) te;
|
321 |
0
| capa = goal.getCapability();
|
322 |
| } |
323 |
0
| if (capa != null) {
|
324 |
0
| Iterator it = capa.listAssumptions().iterator();
|
325 |
0
| while (it.hasNext()) {
|
326 |
0
| visitAxiom((Axiom) it.next());
|
327 |
| } |
328 |
| |
329 |
0
| it = capa.listEffects().iterator();
|
330 |
0
| while (it.hasNext()) {
|
331 |
0
| visitAxiom((Axiom) it.next());
|
332 |
| } |
333 |
| |
334 |
0
| it = capa.listPreConditions().iterator();
|
335 |
0
| while (it.hasNext()) {
|
336 |
0
| visitAxiom((Axiom) it.next());
|
337 |
| } |
338 |
| |
339 |
0
| it = capa.listPostConditions().iterator();
|
340 |
0
| while (it.hasNext()) {
|
341 |
0
| visitAxiom((Axiom) it.next());
|
342 |
| } |
343 |
| } |
344 |
0
| addWarning(te, "The validation of Web Services and Goals is not " +
|
345 |
| "yet complete. Currently the logical expressions in " + |
346 |
| "assumptions, effects, pre- and postconditions are " + |
347 |
| "validated against the WSML variant specified in the " + |
348 |
| "file.", null); |
349 |
| } |
350 |
| else { |
351 |
0
| throw new UnsupportedOperationException(
|
352 |
| "Only implemented for ontologies, web services and goals at present"); |
353 |
| } |
354 |
0
| return (errors.isEmpty());
|
355 |
| } |
356 |
| |
357 |
0
| public boolean isValid(LogicalExpression logExpr, List <ValidationError> errorMessages, List <ValidationWarning> warningMessages) {
|
358 |
0
| leSerializer = new LogExprSerializerWSML(null);
|
359 |
0
| errors = errorMessages;
|
360 |
0
| warnings = warningMessages;
|
361 |
0
| WsmlFullExpressionValidator exprVal = new WsmlFullExpressionValidator(null, errors);
|
362 |
0
| logExpr.accept(exprVal);
|
363 |
0
| return (errors.isEmpty());
|
364 |
| } |
365 |
| |
366 |
| |
367 |
| |
368 |
| |
369 |
0
| protected void addWarning(Entity ent, String msg, String quickFix) {
|
370 |
0
| ValidationWarningImpl vw = new ValidationWarningImpl(ent, msg, quickFix);
|
371 |
0
| if (!warnings.contains(vw)) {
|
372 |
0
| warnings.add(vw);
|
373 |
| } |
374 |
| } |
375 |
| |
376 |
| |
377 |
| |
378 |
| |
379 |
0
| protected void addError(Entity ent, String msg) {
|
380 |
0
| ValidationErrorImpl ve = new ValidationErrorImpl(ent, msg, WSML.WSML_FULL);
|
381 |
0
| if (!errors.contains(ve)) {
|
382 |
0
| errors.add(ve);
|
383 |
| } |
384 |
| } |
385 |
| |
386 |
| |
387 |
| |
388 |
| |
389 |
0
| protected void addError(Entity ent, Attribute att, String msg) {
|
390 |
0
| AttributeErrorImpl ae = new AttributeErrorImpl(ent, att, msg, WSML.WSML_FULL);
|
391 |
0
| if (!errors.contains(ae)) {
|
392 |
0
| errors.add(ae);
|
393 |
| } |
394 |
| } |
395 |
| |
396 |
| } |