View Javadoc

1   /*
2    wsmo4j - a WSMO API and Reference Implementation
3    Copyright (c) 2004, DERI Innsbruck
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  import java.util.Map.Entry;
20  
21  import org.omwg.ontology.*;
22  import org.wsmo.common.*;
23  import org.wsmo.validator.ValidationError;
24  
25  /**
26   * The AnonIdCollectHelper collects the anonym concepts, instances and relation, and 
27   * checks if they are used correctly. An object with an unnumbered anonymous identifier 
28   * cannot be referenced, and thus, the validator throws an error, if such an object is 
29   * referenced.
30   *
31   * <pre>
32   * Created on March 24, 2006
33   * Committed by $Author: morcen $
34   * $Source$
35   * </pre>
36   *
37   * @author nathalie.steinmetz@deri.org
38   *
39   * @version $Revision: 1946 $ $Date: 2007-04-02 15:13:28 +0300 (Mon, 02 Apr 2007) $
40   */
41  public class AnonIdCollectHelper {
42  
43      private final static String ERROR_ANON_IDS = "An object with an unnumbered " +
44              "anonymous identifier cannot be referenced. To reference this object, name it.";
45      
46      private List <ValidationError> errors = null;
47      
48      private HashMap <Concept, Integer> concepts = null;
49      
50      private HashMap <Relation, Integer> relations = null;
51      
52      private HashMap <Instance, Integer> instances = null;
53      
54      public AnonIdCollectHelper(List <ValidationError> errors) {
55          this.errors = errors;
56          concepts = new HashMap <Concept, Integer> ();
57          relations = new HashMap <Relation, Integer> ();
58          instances = new HashMap <Instance, Integer> ();
59      }
60      
61      /*
62       * This method checks if the given concept has got an unnumbered 
63       * anonymous identifier and thus needs to be put into the concerned 
64       * map 'concepts'. If not, it is checked if there are any references 
65       * to such an anonymous concept, which then needs to be put in the map.
66       */
67      private void visitConcept(Concept concept){
68          boolean checked = false;
69          if (concept.getIdentifier() instanceof UnnumberedAnonymousID) { 
70              addToConcepts(concept);          
71              if (concept.listSuperConcepts().size() > 0) {
72                  if (checked) {
73                      checked = false;
74                      addToConcepts(concept);
75                  }
76                  else {
77                      checked = true;
78                  }
79              }
80              if (concept.listAttributes().size() > 0) {
81                  if (checked) {
82                      checked = false;
83                      addToConcepts(concept);
84                  }
85                  else {
86                      checked = true;
87                  }
88              }
89              if (concept.listInstances().size() > 0) {
90                  for (int i=0; i<concept.listInstances().size(); i++) {
91                      if (checked) {
92                          checked = false;
93                          addToConcepts(concept);
94                      }
95                      else {
96                          checked = true;
97                      }
98                  }
99              }
100             if (concept.listNFPValues().size() > 0) {
101                 for (int i=0; i<concept.listNFPValues().size(); i++) {
102                     if (checked) {
103                         checked = false;
104                         addToConcepts(concept);
105                     }
106                     else {
107                         checked = true;
108                     }
109                 }
110             }   
111         }
112         if (concept.listSuperConcepts().size() > 0) {
113             Iterator it = concept.listSuperConcepts().iterator();
114             while (it.hasNext()) {
115                 Concept tmp = (Concept) it.next();
116                 if (tmp.getIdentifier() instanceof UnnumberedAnonymousID) {
117                     addToConcepts(tmp, concept);
118                 }
119             }
120         }
121         if (concept.listAttributes().size() > 0) {
122             Iterator it = concept.listAttributes().iterator();
123             while (it.hasNext()) {
124                 Attribute a = (Attribute) it.next();
125                 if (a.listTypes().size() > 0) {
126                     Iterator it2 = a.listTypes().iterator();
127                     while (it2.hasNext()) {
128                         Type t = (Type) it2.next();
129                         if (t instanceof Concept && 
130                                 ((Concept) t).getIdentifier() instanceof UnnumberedAnonymousID) {
131                             addToConcepts((Concept) t, a);
132                         }
133                     }
134                 }
135             }
136         }
137     }
138     
139     /*
140      * This method checks if the given instance has got an unnumbered 
141      * anonymous identifier and thus needs to be put into the appropriate 
142      * map 'instances'. If not, it is checked if there are any references 
143      * to such an anonymous instance, which then needs to be put in the map.
144      */
145     private void visitInstance(Instance instance) {
146         boolean checked = false;
147         if (instance.getIdentifier() instanceof UnnumberedAnonymousID) {
148             addToInstances(instance);
149             if (instance.listAttributeValues().size() > 0) {
150                 if (checked) {
151                     checked = false;
152                     addToInstances(instance);
153                 }
154                 else {
155                     checked = true;
156                 }
157             }
158             if (instance.listConcepts().size() > 0) {
159                 for (int i=0; i<instance.listConcepts().size(); i++) {
160                     if (checked) {
161                         checked = false;
162                         addToInstances(instance);
163                     }
164                     else {
165                         checked = true;
166                     }
167                 }
168             }
169             if (instance.listNFPValues().size() > 0) {
170                 for (int i=0; i<instance.listNFPValues().size(); i++) {
171                     if (checked) {
172                         checked = false;
173                         addToInstances(instance);
174                     }
175                     else {
176                         checked = true;
177                     }
178                 }
179             }
180         }
181         if (instance.listAttributeValues().size() > 0) {
182             Iterator it = instance.listAttributeValues().entrySet().iterator();
183             while (it.hasNext()) { 
184                 Set set = (Set) ((Entry) it.next()).getValue();
185                 Iterator it2 = set.iterator();
186                 while (it2.hasNext()) {
187                     Object o = it2.next();
188                     if (o instanceof Instance && 
189                             ((Instance) o).getIdentifier() instanceof UnnumberedAnonymousID) {
190                         addToInstances((Instance) o, instance);
191                     }
192                 }
193             }       
194         }
195     }
196     
197     /*
198      * This method checks if the given relation has got an unnumbered 
199      * anonymous identifier and thus needs to be put into the appropriate 
200      * map 'relations'. If not, it is checked if there are any references 
201      * to an anonymous relation or concept, which then needs to be put in 
202      * the appropriate map.
203      */
204     private void visitRelation(Relation relation) {   
205         if (relation.getIdentifier() instanceof UnnumberedAnonymousID) {
206             addToRelations(relation);
207             if (relation.listSuperRelations().size() > 0) {
208                 addToRelations(relation);
209             }
210             if (relation.listParameters().size() > 0) {
211                 Iterator it = relation.listParameters().iterator();
212                 while (it.hasNext()) {
213                     Parameter p = (Parameter) it.next();
214                     if (p.listTypes().size() > 0) {
215                         addToRelations(relation);
216                     }
217                 }
218             }
219             if (relation.listNFPValues().size() > 0) {
220                 for (int i=0; i<relation.listNFPValues().size(); i++) {
221                     addToRelations(relation);
222                 }
223             }
224         }
225         if (relation.listSuperRelations().size() > 0) {
226             Iterator it = relation.listSuperRelations().iterator();
227             while(it.hasNext()) {
228                 Relation tmp = (Relation) it.next();
229                 if (tmp.getIdentifier() instanceof UnnumberedAnonymousID) {
230                     addToRelations(tmp, relation);
231                 }
232             }
233         }
234         if (relation.listParameters().size() > 0) {
235             Iterator it = relation.listParameters().iterator();
236             while (it.hasNext()) {
237                 Parameter p = (Parameter) it.next();
238                 if (p.listTypes().size() > 0) {
239                     Iterator it2 = p.listTypes().iterator();
240                     while (it2.hasNext()) {
241                         Type t = (Type) it2.next();
242                         if (t instanceof Concept && 
243                                 ((Concept) t).getIdentifier() instanceof UnnumberedAnonymousID) {
244                             addToConcepts((Concept) t, relation);
245                             // if an relation contains a reference to an anonymous concept, 
246                             // this relation cannot have a sub- or superrelation.
247                             if (relation.listSuperRelations().size() > 0 || 
248                                     relation.listSubRelations().size() > 0) {
249                                 addError(relation, ValidationError.ANON_ID_ERR + ":\n" + 
250                                         ERROR_ANON_IDS);
251                             }
252                         }
253                     }
254                 }
255             }
256         }
257     }
258     
259     /*
260      * This method checks if the given relationInstance references 
261      * an anonymous relation or instance, which then needs to be put 
262      * in the appropriate map.
263      */
264     private void visitRelationInstance(RelationInstance relationInstance) {
265         if (relationInstance.getRelation().getIdentifier() instanceof UnnumberedAnonymousID) {
266             addError(relationInstance, ValidationError.ANON_ID_ERR + ":\n" + 
267                     "A relationInstance cannot reference an anonymous relation");
268         }
269         if (relationInstance.listParameterValues().size() > 0) {
270             Iterator it = relationInstance.listParameterValues().iterator();
271             while (it.hasNext()) {
272                 Value v = (Value) it.next();
273                 if (v instanceof Instance && 
274                         ((Instance) v).getIdentifier() instanceof UnnumberedAnonymousID) {
275                     addToInstances((Instance) v, relationInstance);
276                 }
277             }
278         }
279     }
280     
281     /*
282      * see addToConcepts(Concept concept, Entity entity)
283      */
284     private void addToConcepts(Concept concept) {
285         addToConcepts(concept, concept);
286     }
287     
288     /*
289      * This method adds a given concept to the concepts map. If 
290      * the concept is already contained in the map, the number of 
291      * references to it is increased and a ValidationError is added.
292      * 
293      * param concept, concept to be added to the concepts map
294      * param entity, entity to be added to the ValidationError
295      */
296     private void addToConcepts(Concept concept, Entity entity) {
297         if (concepts.containsKey(concept)) {
298             concepts.put(concept, new Integer(concepts.get(concept).intValue() + 1));
299             addError(entity, ValidationError.ANON_ID_ERR + ":\n" + 
300                   ERROR_ANON_IDS);
301         }
302         else {
303             concepts.put(concept, new Integer(1));
304         }
305     }
306     
307     /*
308      * see addToInstances(Instance instance, Entity entity)
309      */
310     private void addToInstances(Instance instance) {
311         addToInstances(instance, instance);
312     }
313     
314     /*
315      * This method adds a given instance to the instances map. If 
316      * the instance is already contained in the map, the number of 
317      * references to it is increased and a ValidationError is added.
318      * 
319      * param instance, instance to be added to the instances map
320      * param entity, entity to be added to the ValidationError
321      */
322     private void addToInstances(Instance instance, Entity entity) {
323         if (instances.containsKey(instance)) {
324             instances.put(instance, new Integer(instances.get(instance).intValue() + 1));
325             addError(entity, ValidationError.ANON_ID_ERR + ":\n" + 
326                   ERROR_ANON_IDS);
327         }
328         else {
329             instances.put(instance, new Integer(1));
330         }
331     }
332     
333     /*
334      * see addToRelations(Relation relation)
335      */
336     private void addToRelations(Relation relation) {
337         addToRelations(relation, relation);
338     }
339     
340     /*
341      * This method adds a given relation to the relations map. If 
342      * the relation is already contained in the map, the number of 
343      * references to it is increased and a ValidationError is added.
344      * 
345      * param relation, relation to be added to the relations map
346      * param entity, entity to be added to the ValidationError
347      */
348     private void addToRelations(Relation relation, Entity entity) {
349         if (relations.containsKey(relation)) {
350             relations.put(relation, new Integer(relations.get(relation).intValue() + 1));
351             addError(entity, ValidationError.ANON_ID_ERR + ":\n" + 
352                     ERROR_ANON_IDS);
353         }
354         else {
355             relations.put(relation, new Integer(1));
356         }
357     }
358     
359     /**
360      * This method takes the ontology and checks all its contained 
361      * elements for an erronous use of unnumbered anonymous identifiers.
362      */
363     public void checkAnonIds(Ontology ontology) {
364         Iterator i = ontology.listConcepts().iterator();
365         while (i.hasNext()) {
366             Concept concept = (Concept) i.next();
367             visitConcept(concept);
368         }
369         i = ontology.listInstances().iterator();
370         while (i.hasNext()) {
371             Instance instance = (Instance) i.next();
372             visitInstance(instance);
373         }
374 
375         i = ontology.listRelations().iterator();
376         while (i.hasNext()) {
377             Relation relation = (Relation) i.next();
378             visitRelation(relation);
379         }
380 
381         i = ontology.listRelationInstances().iterator();
382         while (i.hasNext()) {
383             RelationInstance relationInstance = (RelationInstance) i.next();
384             visitRelationInstance(relationInstance);
385         }
386     }
387     
388     private void addError(Entity entity, String reason) {
389         errors.add(new ValidationErrorImpl(entity, reason, WSML.WSML_FULL));
390     } 
391 
392 }
393 /*
394  * $Log$
395  * Revision 1.5  2007/04/02 12:13:20  morcen
396  * Generics support added to wsmo-api, wsmo4j and wsmo-test
397  *
398  * Revision 1.4  2006/04/26 13:11:49  nathaliest
399  * fixed a bug at instances anonId check
400  *
401  * Revision 1.3  2006/03/28 08:16:36  nathaliest
402  * added documentation
403  *
404  * Revision 1.2  2006/03/28 07:56:16  nathaliest
405  * fix
406  *
407  * Revision 1.1  2006/03/27 16:35:01  nathaliest
408  * changed anonId check
409  *
410  * 
411  */