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.5 2006/02/05 23:48:47 valyt Exp $
17   */
18  package gate.creole.ontology;
19  
20  import java.util.ArrayList;
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Set;
25  
26  /** Represents a single ontology class. */
27  public class TClassImpl extends OntologyResourceImpl implements TClass {
28    /** the id of the class */
29    String id;
30    /** the set of direct sub classes of this class */
31    Set directSubClasses = new HashSet();
32    /** the set of direct super classes of this class */
33    Set directSuperClasses = new HashSet();
34    /** The sub classes transitive closure set */
35    Set subClassesTransitiveClosure = new HashSet();
36    /** The super classes transitive closure set */
37    Set superClassesTransitiveClosure = new HashSet();
38  
39    /**
40     * Creates a new class given id,name,comment and ontology.
41     * 
42     * @param anId
43     *          the id of the new class
44     * @param aName
45     *          the name of the new class
46     * @param aComment
47     *          the comment of the new class
48     * @param anOntology
49     *          the ontology to which the new class belongs
50     */
51    public TClassImpl(String anId, String aName, String aComment,
52            Taxonomy anOntology) {
53      super(aName, aComment, anOntology);
54      id = anId;
55    }
56  
57    /**
58     * Gets the id of the class.
59     * 
60     * @return the id of the class
61     */
62    public String getId() {
63      return id;
64    }
65  
66    public void setURI(String theURI) {
67      if(-1 == theURI.indexOf('#')) {
68        theURI = getOntology().getDefaultNameSpace() + '#' + theURI;
69      }
70      uri = theURI;
71      ontology.setModified(true);
72    }
73  
74    public String getComment() {
75      return comment;
76    }
77  
78    public void setComment(String aComment) {
79      comment = aComment;
80      ontology.setModified(true);
81    }
82  
83    public String getName() {
84      return name;
85    }
86  
87    public void setName(String aName) {
88      name = aName;
89      ontology.setModified(true);
90    }
91  
92    public void addSubClass(TClass subClass) {
93      this.directSubClasses.add(subClass);
94      Set set;
95      if(null != (set = subClass.getSuperClasses(TClass.DIRECT_CLOSURE))) {
96        if(!set.contains(this)) {
97          subClass.addSuperClass(this);
98        }
99      }
100     ontology.setModified(true);
101   } // addSubClass();
102 
103   public void addSuperClass(TClass superClass) {
104     directSuperClasses.add(superClass);
105     Set set;
106     if(null != (set = superClass.getSubClasses(TClass.DIRECT_CLOSURE))) {
107       if(!set.contains(this)) {
108         superClass.addSubClass(this);
109       }
110     }
111     ontology.setModified(true);
112   }
113 
114   public void removeSubClass(TClass subClass) {
115     directSubClasses.remove(subClass);
116     Set set;
117     if(null != (set = subClass.getSuperClasses(TClass.DIRECT_CLOSURE))) {
118       if(set.contains(this)) {
119         subClass.removeSuperClass(this);
120       }
121     }
122     ontology.setModified(true);
123   }
124 
125   public void removeSuperClass(TClass superClass) {
126     directSuperClasses.remove(superClass);
127     Set set;
128     if(null != (set = superClass.getSubClasses(TClass.DIRECT_CLOSURE))) {
129       if(set.contains(this)) {
130         superClass.removeSubClass(this);
131       }
132     }
133     ontology.setModified(true);
134   }
135 
136   public Set getSubClasses(byte closure) {
137     Set result;
138     switch(closure){
139       case DIRECT_CLOSURE: {
140         result = directSubClasses;
141         break;
142       }
143       case TRANSITIVE_CLOSURE: {
144         if(0 == subClassesTransitiveClosure.size()
145                 || getOntology().isModified()) {
146           /* infer again */
147           inferSubClassesTransitiveClosure();
148         } // if should infer again
149         result = subClassesTransitiveClosure;
150         break;
151       }
152       default: {
153         throw new IllegalArgumentException("Unknown closure type " + closure);
154       }
155     } // switch
156     return new HashSet(result);
157   } // getSubClasses()
158 
159   public Set getSuperClasses(byte closure) {
160     Set result;
161     switch(closure){
162       case DIRECT_CLOSURE: {
163         result = directSuperClasses;
164         break;
165       }
166       case TRANSITIVE_CLOSURE: {
167         if(0 == superClassesTransitiveClosure.size()
168                 || getOntology().isModified()) {
169           /* infer again */
170           inferSuperClassesTransitiveClosure();
171         } // if should infer again
172         result = superClassesTransitiveClosure;
173         break;
174       }
175       default: {
176         throw new IllegalArgumentException("Unknown closure type: " + closure);
177       }
178     } // switch
179     return new HashSet(result);
180   } // getSuperClasses()
181 
182   public void inferSubClassesTransitiveClosure() {
183     List bag = new ArrayList(directSubClasses);
184     subClassesTransitiveClosure = new HashSet();
185     TClass currentClass;
186     while(bag.size() > 0) {
187       currentClass = (TClass)bag.remove(0);
188       if(subClassesTransitiveClosure.add(currentClass))
189         bag.addAll(currentClass.getSubClasses(TClass.DIRECT_CLOSURE));
190     } // while bag is not empty
191   } // inferSubClassesTransitiveClosure();
192 
193   public void inferSuperClassesTransitiveClosure() {
194     List bag = new ArrayList(directSuperClasses);
195     superClassesTransitiveClosure = new HashSet();
196     TClass currentClass;
197     while(bag.size() > 0) {
198       currentClass = (TClass)bag.remove(0);
199       if(superClassesTransitiveClosure.add(currentClass))
200         bag.addAll(currentClass.getSuperClasses(TClass.DIRECT_CLOSURE));
201     } // while bag is not empty
202   } // inferSuperClassesTransitiveClosure();
203 
204   public boolean isTopClass() {
205     return directSuperClasses.size() == 0;
206   }
207 
208   public String toString() {
209     return name;
210   }
211 
212   public static Set getSubClasses(byte closure, Set classes) {
213     Set result = new HashSet();
214     Iterator ci = classes.iterator();
215     TClass c;
216     while(ci.hasNext()) {
217       c = (TClass)ci.next();
218       result.addAll(c.getSubClasses(closure));
219     }// while classes
220     return result;
221   } // getSubClasses()
222 
223   public static Set getSuperClasses(byte closure, Set classes) {
224     Set result = new HashSet();
225     Iterator ci = classes.iterator();
226     TClass c;
227     while(ci.hasNext()) {
228       c = (TClass)ci.next();
229       result.addAll(c.getSuperClasses(closure));
230     }// while classes
231     return result;
232   } // getSuperClasses()
233 
234   public ArrayList getSubClassesVSDistance() {
235     ArrayList result = new ArrayList();
236     Set set;
237     int level = 0;
238     TClass c;
239     Set levelSet = new HashSet();
240     levelSet.add(this);
241     boolean rollon = (0 < this.getSubClasses(TClass.DIRECT_CLOSURE).size());
242     while(rollon) {
243       /*
244        * iterate over all the classes in levelSet and infre their subclasses in
245        * set
246        */
247       set = new HashSet();
248       Iterator li = levelSet.iterator();
249       while(li.hasNext()) {
250         c = (TClass)li.next();
251         set.addAll(c.getSubClasses(TClass.DIRECT_CLOSURE));
252       } // while leveset
253       if(0 < set.size()) {
254         result.add(level++, set);
255       }
256       levelSet = set;
257       rollon = 0 < levelSet.size();
258     } // while sublcasses
259     return result;
260   } // getSubClassesVSDistance()
261 
262   public ArrayList getSuperClassesVSDistance() {
263     ArrayList result = new ArrayList();
264     Set set;
265     int level = 0;
266     TClass c;
267     Set levelSet = new HashSet();
268     levelSet.add(this);
269     boolean rollon = (0 < this.getSuperClasses(TClass.DIRECT_CLOSURE).size());
270     while(rollon) {
271       /*
272        * iterate over all the classes in levelSet and infre their subclasses in
273        * set
274        */
275       set = new HashSet();
276       Iterator li = levelSet.iterator();
277       while(li.hasNext()) {
278         c = (TClass)li.next();
279         set.addAll(c.getSuperClasses(TClass.DIRECT_CLOSURE));
280       } // while leveset
281       if(0 < set.size()) {
282         result.add(level++, set);
283       }
284       levelSet = set;
285       rollon = 0 < levelSet.size();
286     } // while superlcasses
287     return result;
288   } // getSuperClassesVSDistance()
289 
290   public boolean equals(Object o) {
291     boolean result = false;
292     if(o instanceof TClass) {
293       TClass c = (TClass)o;
294       result = true;
295       if(null != this.getId() && null != c.getId())
296         result &= this.getId().equals(c.getId());
297       else result &= this.getId() == c.getId();
298       if(null != this.getName() && null != c.getName())
299         result &= this.getName().equals(c.getName());
300       else result &= this.getName() == c.getName();
301       if(null != this.getOntology() && null != c.getOntology())
302         result &= this.getOntology().equals(c.getOntology());
303       else result &= this.getOntology() == c.getOntology();
304       if(null != this.getURI() && null != c.getURI())
305         result &= this.getURI().equals(c.getURI());
306       else result &= this.getURI() == c.getURI();
307     }
308     return result;
309   } // equals
310 } // class TClassImpl
311