001 package com.ontotext.gate.vr;
002
003 import java.util.*;
004 import gate.creole.ontology.*;
005 import gate.util.*;
006 import gate.creole.gazetteer.*;
007 import java.awt.datatransfer.*;
008 import java.io.*;
009 import java.net.URL;
010
011 /** Represents a single class node from the visualized ontology */
012 public class ClassNode
013 implements IFolder,Transferable,Cloneable, Serializable
014 {
015
016 private static final long serialVersionUID = 3258128055154063414L;
017
018 /** flavor used for drag and drop */
019 final public static DataFlavor CLASS_NODE_FLAVOR =
020 new DataFlavor(ClassNode.class, "Class Node");
021
022 static DataFlavor flavors[] = {CLASS_NODE_FLAVOR};
023
024 private String name;
025 private Vector<ClassNode> children = new Vector<ClassNode>();
026 private Object source;
027
028 /** create a structure representing the class hierarchy of an ontology
029 * @param includeInstances if true, then instances of the ontology
030 * are also included
031 * @return the root node of the structure
032 */
033 public static ClassNode createRootNode(Ontology o) {
034 return createRootNode(o, false, false);
035 }
036
037 public static ClassNode createRootNode(Ontology o, boolean includeInstances, boolean includeAnonymousClasses) {
038 if (null == o)
039 throw new gate.util.LazyProgrammerException("ontology is null.");
040
041 ClassNode root = new ClassNode(o);
042 Iterator<OClass> itops = o.getOClasses(true).iterator();
043 Vector<ClassNode> kids = new Vector<ClassNode>();
044 if(includeAnonymousClasses) {
045 while (itops.hasNext()) {
046 ClassNode node = new ClassNode(itops.next());
047 kids.add(node);
048 } // while
049 } else {
050 while (itops.hasNext()) {
051 OClass aClass = itops.next();
052 if(aClass instanceof AnonymousClass) {
053 continue;
054 }
055 ClassNode node = new ClassNode(aClass);
056 kids.add(node);
057 } // while
058 }
059
060 root.source = o;
061 root.setChildren(kids);
062 Vector<ClassNode> parents = kids;
063 Vector<ClassNode> allKids;
064 do {
065 allKids = new Vector<ClassNode>();
066 for ( int i= 0 ; i < parents.size() ; i++ ) {
067 ClassNode parent = parents.get(i);
068 kids = new Vector<ClassNode>();
069
070 //skip this one if it's an instance
071 if(parent.getSource() instanceof OInstance)
072 continue;
073
074 OClass ocl = (OClass) parent.getSource();
075
076 //if we include instances, then get them too
077 if (includeInstances && (o instanceof Ontology)) {
078 Ontology kb = (Ontology) o;
079 Set<OInstance> instances = kb.getOInstances(ocl, OConstants.Closure.DIRECT_CLOSURE);
080 if (instances != null && !instances.isEmpty()) {
081 Iterator<OInstance> insti = instances.iterator();
082 while (insti.hasNext())
083 kids.add(new ClassNode(insti.next()));
084 }
085 }
086
087 if (0 == ocl.getSubClasses(OConstants.Closure.DIRECT_CLOSURE).size()) {
088 if (!kids.isEmpty())
089 //add the instances as children, but do not add them for future
090 //traversal to allKids
091 parent.setChildren(kids);
092 continue;
093 } // if 0 children
094
095 Iterator<OClass> kidsi = ocl.getSubClasses(OConstants.Closure.DIRECT_CLOSURE).iterator();
096
097 while ( kidsi.hasNext()) {
098 OClass aClass = kidsi.next();
099 if(!includeAnonymousClasses && aClass instanceof AnonymousClass) continue;
100 kids.add(new ClassNode(aClass));
101 } // while kidsi
102 parent.setChildren(kids);
103 allKids.addAll(kids);
104
105 } // for i
106 parents = allKids;
107 } while (0 < allKids.size());
108
109 return root;
110 }//createRootNode()
111
112 /** Creates a structure representing the class hierarchy of an ontology
113 * and the gazetteerLists mapped to it.
114 * @param o an ontology
115 * @param mapping mapping definition
116 * @param nameVsNode : this is actually a return value: should be
117 * initialized before passing to this method and afterwards one can find a mapping
118 * of class names vs class nodes there.
119 * @return the root node of the structure
120 */
121 public static ClassNode createRootNode(Ontology o, MappingDefinition mapping, Map<String, ClassNode> nameVsNode) {
122 if (null == o || null == nameVsNode || null == mapping)
123 throw new gate.util.LazyProgrammerException("mapping, nameVsNode or ontology-o is null.");
124 ClassNode root = new ClassNode(o);
125 Iterator<OClass> itops = o.getOClasses(true).iterator();
126 Vector<ClassNode> kids = new Vector<ClassNode>();
127 while (itops.hasNext()) {
128 ClassNode node = new ClassNode(itops.next());
129 nameVsNode.put(node.toString(),node);
130 kids.add(node);
131 } // while
132
133 root.source = o;
134 root.setChildren(kids);
135 Vector<ClassNode> parents = kids;
136 Vector<ClassNode> allKids;
137 do {
138 allKids = new Vector<ClassNode>();
139 for ( int i= 0 ; i < parents.size() ; i++ ) {
140 ClassNode parent = parents.get(i);
141
142 OClass ocl = (OClass) parent.getSource();
143 if (0 == ocl.getSubClasses(OConstants.Closure.DIRECT_CLOSURE).size()) {
144 continue;
145 } // if 0 children
146
147 Iterator<OClass> kidsi = ocl.getSubClasses(OConstants.Closure.DIRECT_CLOSURE).iterator();
148
149 kids = new Vector<ClassNode>();
150 while ( kidsi.hasNext()) {
151 ClassNode cn = new ClassNode(kidsi.next());
152 kids.add(cn);
153 nameVsNode.put(cn.toString(),cn);
154 } // while kidsi
155 parent.setChildren(kids);
156 allKids.addAll(kids);
157
158 } // for i
159 parents = allKids;
160 } while (0 < allKids.size());
161
162 // display mapping
163 Iterator<MappingNode> inodes = mapping.iterator();
164 MappingNode mn;
165 while (inodes.hasNext()) {
166 mn = inodes.next();
167 URL turl = null;
168 try { turl = new URL(mn.getOntologyID());
169 } catch (java.net.MalformedURLException x) {
170 }
171 if ( null != turl ){
172 Ontology o2 = null;
173 try { o2 = OntologyUtilities.getOntology(turl);
174 } catch (gate.creole.ResourceInstantiationException x) {
175 }
176 if ( o2 != null && o2.equals(o) ) {
177 ClassNode cmn = new ClassNode(mn);
178 ClassNode cn = nameVsNode.get(mn.getClassID());
179 if (null!= cn) {
180 cn.children.add(cn.children.size(),cmn);
181 }
182 }// if from the same ontology
183 } // turl != null
184 }// while inodes
185
186
187 return root;
188 }//createRootNode()
189
190 /**Constructs a root class node from an ontology
191 * @param o the ontology */
192 public ClassNode(Ontology o) {
193 name = o.getName();
194 }
195
196 /**Constructs a class node given an ontology class
197 * @param clas ontology class */
198 public ClassNode(OClass clas) {
199 name = clas.getName();
200 source = clas;
201 }
202
203 /**Constructs a class node given an ontology instance
204 * @param instance ontology instance */
205 public ClassNode(OInstance instance) {
206 name = instance.getName();
207 source = instance;
208 }
209
210 /**
211 * Constructs a class node given a mapping node
212 * @param mapNode mapping node */
213 public ClassNode(MappingNode mapNode) {
214 name = mapNode.getList();
215 source = mapNode;
216 }
217
218 public int getIndexOfChild(Object child) {
219 return children.indexOf(child);
220 }
221
222 public Iterator getChildren() {
223 return children.iterator();
224 }
225
226 public void setChildren(Vector<ClassNode> chldrn ) {
227 children = chldrn;
228 }
229
230 public Vector children() {
231 return children;
232 }
233
234 public String toString() {
235 return name;
236 }
237
238 public int getChildCount() {
239 return children.size();
240 }
241
242 public IFolder getChild(int index) {
243 return children.get(index);
244 }
245
246 public boolean equals(Object o) {
247 boolean result = false;
248 if (o instanceof ClassNode) {
249 ClassNode node = (ClassNode) o;
250 result = node.source.equals(this.source);
251 }
252 return result;
253 }
254
255 /**Gets the Source object
256 * @return the source object e.g. an gate.creole.TClass
257 * or a gate.creole.Ontology */
258 public Object getSource(){
259 return source;
260 }
261
262 /**Sets the source object
263 * @param o the source object to be set */
264 public void setSource(Object o) {
265 source = o;
266 }
267
268 /**Renames this class node
269 * @param newName the new name of the node */
270 public void rename(String newName) {
271 name = newName;
272 }
273
274 /**Removes a sub class
275 * @param sub the sub class to be removed*/
276 public void removeSubNode(ClassNode sub) {
277 if ( children.contains(sub) ) {
278 children.remove(sub);
279 Object source = this.getSource();
280 if (source instanceof OClass) {
281 OClass c = (OClass) source;
282 if (sub.getSource() instanceof OClass)
283 c.removeSubClass((OClass)sub.getSource());
284 else if (sub.getSource() instanceof OInstance &&
285 c.getOntology() instanceof Ontology)
286 ((Ontology)c.getOntology()).removeOInstance((OInstance) sub.getSource());
287 } else if ( source instanceof Ontology) {
288 Ontology o = (Ontology) source;
289 o.removeOClass((OClass)sub.getSource());
290 } else if (source instanceof OInstance) {
291 //cannot remove anything from an instance
292 return;
293 } else {
294 throw new GateRuntimeException(
295 "Can not remove a sub node from a classnode.\n"
296 +"The source is neither an Ontology neither TClass");
297 } // else
298 } // if contains
299 } // removeSubNode
300
301 /**Adds a sub node
302 * @param sub the sub node to be added */
303 public void addSubNode(ClassNode sub) {
304 if ( ! children.contains(sub) ) {
305 Object source = this.getSource();
306 if ( source instanceof OClass) {
307 OClass c = (OClass)source;
308 if (!(sub.getSource() instanceof OClass) &&
309 !(sub.getSource() instanceof OInstance))
310 throw new GateRuntimeException(
311 "The sub node's source is not an instance of TClass or OInstance");
312 if (sub.getSource() instanceof OClass) {
313 OClass sc = (OClass) sub.getSource();
314 c.addSubClass(sc);
315 // this code originally used the deprecated method addOClass(URI, byte)
316 // with the byte constant indicating a class, without checking for
317 // sc not being an anonymous class.
318 c.getOntology().addOClass((OURI)sc.getONodeID());
319 children.add(sub);
320 }
321 if (sub.getSource() instanceof OInstance &&
322 c.getOntology() instanceof Ontology){
323 OInstance inst = (OInstance) sub.getSource();
324 if(!((Ontology)c.getOntology()).containsOInstance(inst.getOURI())) {
325 Iterator<OClass> instClasses =
326 inst.getOClasses(OConstants.Closure.DIRECT_CLOSURE).iterator();
327 while(instClasses.hasNext()) {
328 ((Ontology)c.getOntology()).addOInstance(inst.getOURI(), instClasses.next());
329 }
330 }
331
332 children.add(sub);
333 }
334
335 } else {
336 if (source instanceof Ontology) {
337 Ontology o = (Ontology) source;
338 if (!(sub.getSource() instanceof OClass))
339 throw new GateRuntimeException("The sub node's source is not an instance of TClass");
340 OClass sc = (OClass)sub.getSource();
341 o.addOClass((OURI)sc.getONodeID());
342 children.add(sub);
343 } else {
344 throw new GateRuntimeException(
345 "cannot add a sub node to something which "
346 +"is neither an Ontology neither an TClass");
347 } // else
348 } // else
349 } // if ! contains
350 } // addSubNode()
351
352 /*--- Transferable interface implementation ---*/
353 public boolean isDataFlavorSupported(DataFlavor df) {
354 return df.equals(CLASS_NODE_FLAVOR);
355 }
356
357 public Object getTransferData(DataFlavor df)
358 throws UnsupportedFlavorException, IOException {
359 if (df.equals(CLASS_NODE_FLAVOR)) {
360 return this;
361 }
362 else throw new UnsupportedFlavorException(df);
363 }
364
365 public DataFlavor[] getTransferDataFlavors() {
366 return flavors;
367 }
368
369
370 } // class ClassNode
|