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