1   /*
2    * OClassImpl.java
3    *
4    * Copyright (c) 2002, The University of Sheffield.
5    *
6    * This file is part of GATE (see http://gate.ac.uk/), and is free
7    * software, licenced under the GNU Library General Public License,
8    * Version 2, June1991.
9    *
10   * A copy of this licence is included in the distribution in the file
11   * licence.html, and is also available at http://gate.ac.uk/gate/licence.html.
12   *
13   * borislav popov 02/2002
14   *
15   */
16  package gate.creole.ontology;
17  
18  import java.util.*;
19  
20  
21  
22  /** Represents a single ontology class.*/
23  public class OClassImpl implements OClass{
24  
25    /** the ontology to which the class belongs*/
26    Ontology ontology;
27  
28    /** the URI of the class */
29    String uri;
30  
31    /** the id of the class */
32    String id;
33  
34    /**the name of the class */
35    String name;
36  
37    /**the comment of the class*/
38    String comment;
39  
40    /** the set of direct sub classes of this class */
41    Set directSubClasses = new HashSet();
42  
43    /** the set of direct super classes of this class */
44    Set directSuperClasses = new HashSet();
45  
46    /** The sub classes transitive closure set*/
47    Set subClassesTransitiveClosure = new HashSet();
48  
49    /** The super classes transitive closure set*/
50    Set superClassesTransitiveClosure = new HashSet();
51  
52    /**
53     * Creates a new class given id,name,comment and ontology.
54     * @param anId the id of the new class
55     * @param aName the name of the new class
56     * @param aComment the comment of the new class
57     * @param anOntology the ontology to which the new class belongs
58     */
59    public OClassImpl(String anId, String aName, String aComment, Ontology anOntology) {
60      id = anId;
61      name = aName;
62      comment = aComment;
63      ontology = anOntology;
64    }
65  
66    /**
67     * Gets the id of the class.
68     * @return the id of the class
69     */
70    public String getId(){
71      return id;
72    }
73  
74    /**
75     * Gets the ontology to which this class is associated.
76     * @return the ontology to which this class is associated.
77     */
78    public Ontology getOntology() {
79      return ontology;
80    }
81  
82    public String getURI() {
83      return uri;
84    }
85  
86    public void setURI(String theURI) {
87      if (-1 == theURI.indexOf('#')){
88        theURI = getOntology().getSourceURI()+'#'+theURI;
89      }
90      uri = theURI;
91      ontology.setModified(true);
92    }
93  
94    public String getComment(){
95      return comment;
96    }
97  
98    public void setComment(String aComment) {
99      comment = aComment;
100     ontology.setModified(true);
101   }
102 
103   public String getName() {
104     return name;
105   }
106 
107   public void setName(String aName) {
108     name = aName;
109     ontology.setModified(true);
110   }
111 
112   public void addSubClass(OClass subClass) {
113     this.directSubClasses.add(subClass);
114     Set set;
115     try {
116       if (null != (set = subClass.getSuperClasses(OClass.DIRECT_CLOSURE))) {
117         if (!set.contains(this)) {
118           subClass.addSuperClass(this);
119         }
120       }
121       ontology.setModified(true);
122     } catch (NoSuchClosureTypeException x) {
123       throw new gate.util.GateRuntimeException(x.getMessage());
124     }
125   } // addSubClass();
126 
127   public void addSuperClass(OClass superClass) {
128     try {
129       directSuperClasses.add(superClass);
130       Set set;
131       if (null != (set = superClass.getSubClasses(OClass.DIRECT_CLOSURE))) {
132         if (!set.contains(this)) {
133           superClass.addSubClass(this);
134         }
135       }
136       ontology.setModified(true);
137     } catch (NoSuchClosureTypeException x) {
138       throw new gate.util.GateRuntimeException(x.getMessage());
139     }
140 
141   }
142 
143   public void removeSubClass(OClass subClass) {
144     try {
145       directSubClasses.remove(subClass);
146       Set set;
147       if (null!=(set=subClass.getSuperClasses(OClass.DIRECT_CLOSURE))){
148         if ( set.contains(this) ) {
149           subClass.removeSuperClass(this);
150         }
151       }
152       ontology.setModified(true);
153     } catch (NoSuchClosureTypeException x) {
154       throw new gate.util.GateRuntimeException(x.getMessage());
155     }
156   }
157 
158   public void removeSuperClass(OClass superClass) {
159     try {
160       directSuperClasses.remove(superClass);
161       Set set;
162       if ( null != (set = superClass.getSubClasses(OClass.DIRECT_CLOSURE))) {
163         if ( set.contains(this) ) {
164           superClass.removeSubClass(this);
165         }
166       }
167       ontology.setModified(true);
168     } catch (NoSuchClosureTypeException x) {
169       throw new gate.util.GateRuntimeException(x.getMessage());
170     }
171   }
172 
173   public Set getSubClasses(byte closure) throws NoSuchClosureTypeException {
174     Set result;
175     switch (closure) {
176       case DIRECT_CLOSURE : {
177         result = directSubClasses;
178         break;
179       }
180       case TRANSITIVE_CLOSURE : {
181         if (0==subClassesTransitiveClosure.size() ||
182             getOntology().isModified() ) {
183             /* infer again */
184             inferSubClassesTransitiveClosure();
185         } // if should infer again
186 
187         result = subClassesTransitiveClosure;
188         break;
189       }
190       default : {
191         throw new NoSuchClosureTypeException(closure);
192       }
193     } //switch
194 
195     return new HashSet(result);
196   } // getSubClasses()
197 
198   public Set getSuperClasses(byte closure) throws NoSuchClosureTypeException{
199     Set result;
200     switch (closure) {
201       case DIRECT_CLOSURE : {
202         result = directSuperClasses;
203         break;
204       }
205       case TRANSITIVE_CLOSURE : {
206         if (0==superClassesTransitiveClosure.size() ||
207             getOntology().isModified() ) {
208             /* infer again */
209             inferSuperClassesTransitiveClosure();
210         } // if should infer again
211         result = superClassesTransitiveClosure;
212         break;
213       }
214       default : {
215         throw new NoSuchClosureTypeException(closure);
216       }
217     } //switch
218 
219     return new HashSet(result);
220   } // getSuperClasses()
221 
222   public void inferSubClassesTransitiveClosure(){
223     try {
224 
225       List bag = new ArrayList(directSubClasses);
226       subClassesTransitiveClosure = new HashSet();
227       OClass currentClass;
228       while (bag.size()>0) {
229         currentClass = (OClass) bag.get(0);
230         bag.remove(0);
231         subClassesTransitiveClosure.add(currentClass);
232         bag.addAll(currentClass.getSubClasses(OClass.DIRECT_CLOSURE));
233       } //while bag is not empty
234 
235     } catch (NoSuchClosureTypeException x) {
236       throw new gate.util.GateRuntimeException(x.getMessage());
237     }
238 
239   } // inferSubClassesTransitiveClosure();
240 
241   public void inferSuperClassesTransitiveClosure(){
242     try {
243       List bag = new ArrayList(directSuperClasses);
244       superClassesTransitiveClosure = new HashSet();
245       OClass currentClass;
246       while (bag.size()>0) {
247         currentClass = (OClass) bag.get(0);
248         bag.remove(0);
249         superClassesTransitiveClosure.add(currentClass);
250         bag.addAll(currentClass.getSuperClasses(OClass.DIRECT_CLOSURE));
251       } //while bag is not empty
252     } catch (NoSuchClosureTypeException x) {
253       throw new gate.util.GateRuntimeException(x.getMessage());
254     }
255 
256 
257   } // inferSuperClassesTransitiveClosure();
258 
259   public boolean isTopClass(){
260     return directSuperClasses.size() == 0;
261   }
262 
263   public String toString(){
264     return name;
265   }
266 
267 
268 
269 
270   public static Set getSubClasses(byte closure,Set classes) {
271     try {
272       Set result = new HashSet();
273       Iterator ci = classes.iterator();
274       OClass c;
275       while (ci.hasNext()) {
276 
277         c = (OClass) ci.next();
278         result.addAll(c.getSubClasses(closure));
279 
280       }// while classes
281       return result;
282     } catch (NoSuchClosureTypeException x) {
283       throw new gate.util.GateRuntimeException(x.getMessage());
284     }
285 
286   } // getSubClasses()
287 
288 
289   public static Set getSuperClasses(byte closure,Set classes) {
290     try {
291       Set result = new HashSet();
292       Iterator ci = classes.iterator();
293       OClass c;
294       while (ci.hasNext()) {
295 
296         c = (OClass) ci.next();
297         result.addAll(c.getSuperClasses(closure));
298 
299       }// while classes
300       return result;
301     } catch (NoSuchClosureTypeException x) {
302       throw new gate.util.GateRuntimeException(x.getMessage());
303     }
304 
305   } // getSuperClasses()
306 
307 
308   public ArrayList getSubClassesVSDistance() {
309     try {
310       ArrayList result = new ArrayList();
311       Set set;
312       int level = 0;
313       OClass c;
314       Set levelSet = new HashSet();
315       levelSet.add(this);
316       boolean rollon = (0 < this.getSubClasses(OClass.DIRECT_CLOSURE).size());
317 
318       while (rollon) {
319         /* iterate over all the classes in levelSet and infre their subclasses in set*/
320         set = new HashSet();
321         Iterator li = levelSet.iterator();
322         while (li.hasNext()) {
323           c = (OClass) li.next();
324           set.addAll(c.getSubClasses(OClass.DIRECT_CLOSURE));
325         } //while leveset
326         if ( 0 < set.size() ) {
327           result.add(level++,set);
328         }
329         levelSet = set;
330         rollon = 0 < levelSet.size();
331       } // while sublcasses
332       return result;
333     } catch (NoSuchClosureTypeException x) {
334       throw new gate.util.GateRuntimeException(x.getMessage());
335     }
336 
337   } // getSubClassesVSDistance()
338 
339 
340 
341   public ArrayList getSuperClassesVSDistance() {
342     try {
343       ArrayList result = new ArrayList();
344       Set set;
345       int level = 0;
346       OClass c;
347       Set levelSet = new HashSet();
348       levelSet.add(this);
349       boolean rollon = (0 < this.getSuperClasses(OClass.DIRECT_CLOSURE).size());
350 
351       while (rollon) {
352         /* iterate over all the classes in levelSet and infre their subclasses in set*/
353         set = new HashSet();
354         Iterator li = levelSet.iterator();
355         while (li.hasNext()) {
356           c = (OClass) li.next();
357           set.addAll(c.getSuperClasses(OClass.DIRECT_CLOSURE));
358         } //while leveset
359         if ( 0 < set.size() ) {
360           result.add(level++,set);
361         }
362         levelSet = set;
363         rollon = 0 < levelSet.size();
364       } // while superlcasses
365       return result;
366     } catch (NoSuchClosureTypeException x) {
367       throw new gate.util.GateRuntimeException(x.getMessage());
368     }
369 
370   } // getSuperClassesVSDistance()
371 
372 
373   public boolean equals(Object o) {
374     boolean result = false;
375     if ( o instanceof OClass ) {
376       OClass c = (OClass) o;
377       result = true;
378       if (null != this.getId() & null!= c.getId())
379         result &= this.getId().equals(c.getId());
380       else
381         result = this.getId() == c.getId();
382 
383       if (null != this.getName() & null!= c.getName())
384         result &= this.getName().equals(c.getName());
385       else
386         result = this.getName() == c.getName();
387 
388       if (null != this.getOntology() & null!= c.getOntology())
389         result &=  this.getOntology().equals(c.getOntology());
390       else
391         result = this.getOntology() == c.getOntology();
392 
393       if (null != this.getURI() & null!= c.getURI())
394         result &= this.getURI().equals(c.getURI());
395       else
396         result = this.getURI() == c.getURI();
397     }
398     return result;
399   } // equals
400 
401 } //class OClassImpl