View Javadoc

1   /*
2    wsmo4j - a WSMO API and Reference Implementation
3    Copyright (c) 2005, University of Innsbruck, Austria
4    This library is free software; you can redistribute it and/or modify it under
5    the terms of the GNU Lesser General Public License as published by the Free
6    Software Foundation; either version 2.1 of the License, or (at your option)
7    any later version.
8    This library is distributed in the hope that it will be useful, but WITHOUT
9    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11   details.
12   You should have received a copy of the GNU Lesser General Public License along
13   with this library; if not, write to the Free Software Foundation, Inc.,
14   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15   */
16  package org.deri.wsmo4j.validator;
17  
18  import java.util.*;
19  
20  import org.omwg.logicalexpression.LogicalExpression;
21  import org.omwg.ontology.*;
22  import org.wsmo.common.*;
23  import org.wsmo.common.exception.SynchronisationException;
24  import org.wsmo.factory.Factory;
25  import org.wsmo.factory.LogicalExpressionFactory;
26  import org.wsmo.validator.*;
27  
28  
29  /**
30   * Interface or class description
31   *
32   * <pre>
33   *  Created on Aug 18, 2005
34   *  Committed by $Author: morcen $
35   *  $Source$,
36   * </pre>
37   *
38   * @author Holger Lausen (holger.lausen@deri.org)
39   * @author nathalie.steinmetz@deri.org
40   * @version $Revision: 1946 $ $Date: 2007-04-02 15:13:28 +0300 (Mon, 02 Apr 2007) $
41   * @see org.wsmo.validator.WsmlValidator
42   */
43  public class WsmlValidatorImpl
44          implements WsmlValidator {
45  
46      public LogicalExpressionFactory leFactory = null;
47  
48      public boolean validateImports = true;
49      
50      // set containing the identifiers of all ontologies that have been tried to be validated
51      public HashSet <Identifier> visitedOntologies = new HashSet <Identifier> ();
52      
53      public WsmlValidatorImpl(){
54          this(null);
55      }
56  
57      /**
58       * The WsmlValidator is initialised based on the supplied preferences.
59       * The properties map can contain the factories to be used as Strings or as
60       * instances. If a factory to use is only indicated as String, the constructor
61       * needs to create an instance of this given factory.
62       *
63       * @param properties the preferences for the validator.
64       */
65      public WsmlValidatorImpl(Map properties) {
66          if (properties != null && properties.containsKey(Factory.LE_FACTORY)) {
67          Object o = properties.get(Factory.LE_FACTORY);
68              if (o == null || !(o instanceof LogicalExpressionFactory)) {
69                  o = Factory.createLogicalExpressionFactory(new HashMap <String, Object>());
70              }
71              leFactory = (LogicalExpressionFactory) o;
72          }
73  
74          if (leFactory == null) {
75              leFactory = Factory.createLogicalExpressionFactory(new HashMap <String, Object>());
76          }
77          assert (leFactory != null);  
78          
79          if (properties != null && properties.containsKey(WsmlValidator.VALIDATE_IMPORTS)) {
80          	Object o = properties.get(WsmlValidator.VALIDATE_IMPORTS);
81          	// by default imported ontologies are validated
82          	if (o == null || !(o instanceof Boolean)) {
83          		o = new Boolean(true);
84          	}
85          	validateImports = ((Boolean) o).booleanValue();
86          }
87      }
88      
89      /**
90       * When no variant is specified in the TopEntity, the TopEntity is checked for valid wsml-full,
91       * otherwise it is validated against the variant stated in the TopEntity.
92       *
93       * @param te TopEntity
94       * @param errorMessages list that will be filled with error messages dound during validation
95       * @param warningMessages list that will be filled with warning messages found during validation
96       * @return true/false, if the TopEntity is valid to the TopEntity's variant or not
97       * @see org.wsmo.validator.Validator#isValid(org.wsmo.common.TopEntity, java.util.List, 
98       *      java.util.List)
99       */
100     public boolean isValid(TopEntity te, List <ValidationError> errorMessages, List <ValidationWarning> warningMessages) {
101     	String variant = te.getWsmlVariant();
102         if (variant == null) {
103             variant = WSML.WSML_FULL;
104         }
105         return isValid(te, variant, errorMessages, warningMessages);
106     }
107 
108     /**
109      * The TopEntity is validated against the given variant.
110      *
111      * @param te TopEntity to be validated.
112      * @param variant to be validated against (String representation of the corresponging IRI 
113      * 			e.g. "http://www.wsmo.org/wsml/wsml-syntax/wsml-core")
114      * @param errorMessages list that will be filled with error messages found during validation
115      * @param warningMessages list that will be filled with warning messages found during validation
116      * @return true/false, if the TopEntity is valid with respect to the variant or not
117      * @see org.wsmo.validator.WsmlValidator#isValid(org.wsmo.common.TopEntity, java.lang.String, java.util.List, java.util.List)
118      * @see ValidationError
119      * @see ValidationWarning
120      */
121     public boolean isValid(TopEntity te, String variant, List <ValidationError> errorMessages, List <ValidationWarning> warningMessages) {
122         List <ValidationError> errors = errorMessages;
123         List <ValidationWarning> warnings = warningMessages;
124         if (errors == null){
125             errors = new LinkedList <ValidationError> ();
126         }
127         if (warnings== null){
128             warnings = new LinkedList <ValidationWarning> ();
129         }
130 
131         if (te.getWsmlVariant() == null){
132             warnings.add(new ValidationWarningImpl(
133                     te,
134                     "No WSML variant specified",
135                     "Specify the variant using the wsmlVariant keyword with the corresponding IRI"));
136         }
137         if (te.getWsmlVariant() != null &&
138                 ! (te.getWsmlVariant().equals(WSML.WSML_CORE)||
139                 te.getWsmlVariant().equals(WSML.WSML_DL)||
140                 te.getWsmlVariant().equals(WSML.WSML_RULE)||
141                 te.getWsmlVariant().equals(WSML.WSML_FLIGHT)||
142                 te.getWsmlVariant().equals(WSML.WSML_FULL))){
143             errors.add(new ValidationErrorImpl(te,
144                     "The WSML variant specified is not valid ("+
145                     te.getWsmlVariant()+")", WSML.WSML_FULL));
146         }
147 
148         if (validateImports) {
149         	locateOntologies(te, errors, warnings);
150         }
151         else if (te.listOntologies().size() > 0){
152         	warnings.add(new ValidationWarningImpl(te, "The feature to validate " +
153         			"imported ontologies is disabled. Thus we cannot check the " +
154         			"validity of eventually imported ontologies.", "Enable " +
155 					"the validation of imported ontologies by setting the validator " +
156 					"preference VALIDATE_IMPORTS on true."));
157         }
158         
159         if (variant.equals(WSML.WSML_CORE)) {
160             WsmlCoreValidator v = new WsmlCoreValidator(leFactory);
161             return (v.isValid(te, errors, warnings));
162         }
163         else if (variant.equals(WSML.WSML_DL)) {
164             WsmlDLValidator v = new WsmlDLValidator(leFactory);
165             return (v.isValid(te,errors, warnings));
166         }
167         else if (variant.equals(WSML.WSML_FLIGHT)) {
168             WsmlFlightValidator v = new WsmlFlightValidator(leFactory);
169             return (v.isValid(te, errors, warnings));
170         }
171         else if (variant.equals(WSML.WSML_RULE)) {
172             WsmlRuleValidator v = new WsmlRuleValidator(leFactory);
173             return (v.isValid(te, errors, warnings));
174         }
175         else if (variant.equals(WSML.WSML_FULL)) {
176             WsmlFullValidator v = new WsmlFullValidator(leFactory);
177             return (v.isValid(te, errors, warnings));
178         }
179         else {
180             throw new IllegalArgumentException(
181                     "Invalid WSML Variant specified: \"" + variant +
182                     "\". Expected String representation of respective IRI, e.g: \""+WSML.WSML_CORE+"\"");
183         }
184     }
185 
186     /**
187      * The logical expression is validated against the given variant.
188      *
189      * @param logExpr LogicalExpression to be checked
190      * @param variant to be validated against (String representation of the corresponging IRI 
191      * 		  e.g. "http://www.wsmo.org/wsml/wsml-syntax/wsml-core")
192      * @param errorMessages list that will be filled with error messages dound during validation
193      * @param warningMessages list that will be filled with warning messages found during validation
194      * @return true/false, if the LogicalExpression is valid to the given variant or not
195      * @see org.wsmo.validator.Validator#isValid(LogicalExpression, String, java.util.List, 
196      *      java.util.List)
197      */
198 	public boolean isValid(LogicalExpression logExpr, String variant, List <ValidationError> errorMessages, List <ValidationWarning> warningMessages) {
199 		List <ValidationError> errors = errorMessages;
200         List <ValidationWarning>warnings = warningMessages;
201         if (errors == null){
202             errors = new LinkedList <ValidationError> ();
203         }
204         if (warnings== null){
205             warnings = new LinkedList <ValidationWarning> ();
206         }
207         
208         if (variant.equals(WSML.WSML_CORE)) {
209             WsmlCoreValidator v = new WsmlCoreValidator(leFactory);
210             return (v.isValid(logExpr, errors, warnings));
211         }
212         else if (variant.equals(WSML.WSML_DL)) {
213             WsmlDLValidator v = new WsmlDLValidator(leFactory);
214             return (v.isValid(logExpr,errors, warnings));
215         }
216         else if (variant.equals(WSML.WSML_FLIGHT)) {
217             WsmlFlightValidator v = new WsmlFlightValidator(leFactory);
218             return (v.isValid(logExpr, errors, warnings));
219         }
220         else if (variant.equals(WSML.WSML_RULE)) {
221             WsmlRuleValidator v = new WsmlRuleValidator(leFactory);
222             return (v.isValid(logExpr, errors, warnings));
223         }
224         else if (variant.equals(WSML.WSML_FULL)) {
225             WsmlFullValidator v = new WsmlFullValidator(leFactory);
226             return (v.isValid(logExpr, errors, warnings));
227         }
228         else {
229             throw new IllegalArgumentException(
230                     "Invalid WSML Variant specified: \"" + variant +
231                     "\". Expected String representation of respective IRI, e.g: \""+WSML.WSML_CORE+"\"");
232         }
233 	}
234     
235     /**
236      * This method checks for which wsml variant the given TopEntity is valid.
237      *
238      * @param te TopEntity to be checked
239      * @return String variant, the IRI of the variant that te is in, null if not valid wsml full
240      * @see org.wsmo.validator.WsmlValidator#determineVariant(org.wsmo.common.TopEntity, java.util.List, java.util.List)
241      */
242     public String determineVariant(TopEntity te, List <ValidationError> errorMessages, List <ValidationWarning> warningMessages) {
243         List <ValidationError> errors = errorMessages;
244         String variant = null;
245         WsmlFullValidator vf = new WsmlFullValidator(leFactory);
246         if (vf.isValid(te, errors, warningMessages)) {
247             variant = WSML.WSML_FULL;
248             WsmlRuleValidator vr = new WsmlRuleValidator(leFactory);
249             if (vr.isValid(te, errors, warningMessages)) {
250                 variant = WSML.WSML_RULE;
251                 WsmlFlightValidator vfl = new WsmlFlightValidator(leFactory);
252                 if (vfl.isValid(te, errors, warningMessages)) {
253                     variant = WSML.WSML_FLIGHT;
254                     WsmlCoreValidator vc = new WsmlCoreValidator(leFactory);
255                     if (vc.isValid(te, errors, warningMessages)) {
256                         variant = WSML.WSML_CORE;
257                     }
258                 }
259             }
260             else {
261             	errors.clear();
262             	warningMessages.clear();
263 	            WsmlDLValidator vdl = new WsmlDLValidator(leFactory);
264 	            if (vdl.isValid(te, errors, warningMessages)) {
265 	            	variant = WSML.WSML_DL;
266 	            }
267             }
268         }
269         return variant;
270     }
271     
272     /**
273      * This method checks for which wsml variant the given logical expression is valid.
274      *
275      * @param logExpr LogicalExpression to be checked
276      * @return String variant, the IRI of the variant that logExpr is in, null if not valid wsml full
277      * @see org.wsmo.validator.WsmlValidator#determineVariant(LogicalExpression, java.util.List, java.util.List)
278      */
279     public String determineVariant(LogicalExpression logExpr, List <ValidationError> errorMessages, List <ValidationWarning> warningMessages) {
280     	List <ValidationError> errors = errorMessages;
281         String variant = null;
282         WsmlFullValidator vf = new WsmlFullValidator(leFactory);
283         if (vf.isValid(logExpr, errors, warningMessages)) {
284             variant = WSML.WSML_FULL;
285             WsmlRuleValidator vr = new WsmlRuleValidator(leFactory);
286             if (vr.isValid(logExpr, errors, warningMessages)) {
287                 variant = WSML.WSML_RULE;
288                 WsmlFlightValidator vfl = new WsmlFlightValidator(leFactory);
289                 if (vfl.isValid(logExpr, errors, warningMessages)) {
290                     variant = WSML.WSML_FLIGHT;
291                     WsmlCoreValidator vc = new WsmlCoreValidator(leFactory);
292                     if (vc.isValid(logExpr, errors, warningMessages)) {
293                         variant = WSML.WSML_CORE;
294                     }
295                 }
296             }
297             else {
298             	errors.clear();
299             	warningMessages.clear();
300 	            WsmlDLValidator vdl = new WsmlDLValidator(leFactory);
301 	            if (vdl.isValid(logExpr, errors, warningMessages)) {
302 	            	variant = WSML.WSML_DL;
303 	            }
304             }
305         }
306         return variant;
307 	}
308 
309     private void locateOntologies(TopEntity te, List <ValidationError> errors, List <ValidationWarning> warnings) {
310     	for (Iterator it = te.listOntologies().iterator(); it.hasNext();){
311     		Ontology ontology = (Ontology) it.next();
312     		if (!visitedOntologies.contains(ontology.getIdentifier())){
313     			visitedOntologies.add(ontology.getIdentifier());
314     			List <ValidationError> errorMessages = new Vector <ValidationError> ();
315     			String variant = null;
316     			try {
317     				variant = ontology.getWsmlVariant();
318     	
319     				if (ontology.getWsmlVariant() == null) {
320     					variant = WSML.WSML_FULL;
321     				}
322     				boolean valid = isValid(ontology, errorMessages, warnings);
323     				if (!valid) {	
324     					errors.add(new ValidationErrorImpl(te, ValidationError.IMPORT_ERR + 
325     							":\nImported ontology " + ontology.getIdentifier() + " is not valid " +
326     							"against the variant specified in the file.", variant));
327     				}
328     				boolean badVariant = false;
329     				String teVariant = te.getWsmlVariant();
330     				if (teVariant!=null){
331     					if ((te.getWsmlVariant().equals(WSML.WSML_RULE) && 
332     							variant.equals(WSML.WSML_FULL)) || 
333     							(te.getWsmlVariant().equals(WSML.WSML_FLIGHT) && 
334     							(variant.equals(WSML.WSML_RULE) || variant.equals(WSML.WSML_FULL))) || 
335 		    					(te.getWsmlVariant().equals(WSML.WSML_DL) && 
336 		    					(variant.equals(WSML.WSML_FLIGHT) || variant.equals(WSML.WSML_RULE) || 
337 		    					variant.equals(WSML.WSML_FULL))) || 
338 		    					(te.getWsmlVariant().equals(WSML.WSML_CORE) && 
339 		    					!(variant.equals(WSML.WSML_CORE)))) {
340 		    					badVariant = true;
341     					}
342     				}
343     				if (badVariant) {
344     					errors.add(new ValidationErrorImpl(te, ValidationError.IMPORT_ERR + 
345     							":\nThe variant of the imported ontology " + ontology.getIdentifier() + 
346     							" is higher than the variant of the main ontology.", variant));
347     				}	
348     			} catch (SynchronisationException e) {
349     				warnings.add(new ValidationWarningImpl(te, "Could not validate " +
350     						"Ontology: " + ontology.getIdentifier() + ", as it is " +
351     						"only a proxy, not a real imported ontology", "First import ontology " +
352     								ontology.getIdentifier() + ", and then validate again"));
353     			}
354     		}
355     	}
356     }
357     
358 }