Log in Help
Print
Homereleasesgate-8.4-build5748-ALLpluginsOntology_Toolssrccomontotextgatevr 〉 ClassNode.java
 
package com.ontotext.gate.vr;

import gate.creole.gazetteer.MappingDefinition;
import gate.creole.gazetteer.MappingNode;
import gate.creole.ontology.AnonymousClass;
import gate.creole.ontology.OClass;
import gate.creole.ontology.OConstants;
import gate.creole.ontology.OInstance;
import gate.creole.ontology.OURI;
import gate.creole.ontology.Ontology;
import gate.util.GateRuntimeException;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

/** Represents a single class node from the visualized ontology */
public class ClassNode implements IFolder, Transferable, Cloneable,
		Serializable {

	private static final long serialVersionUID = 3258128055154063414L;

	/** flavor used for drag and drop */
	final public static DataFlavor CLASS_NODE_FLAVOR = new DataFlavor(
			ClassNode.class, "Class Node");

	static DataFlavor flavors[] = { CLASS_NODE_FLAVOR };

	private String name;
	private Vector<ClassNode> children = new Vector<ClassNode>();
	private Object source;

	/**
	 * create a structure representing the class hierarchy of an ontology
	 * 
	 * @return the root node of the structure
	 */
	public static ClassNode createRootNode(Ontology o) {
		return createRootNode(o, false, false);
	}

	public static ClassNode createRootNode(Ontology o,
			boolean includeInstances, boolean includeAnonymousClasses) {
		if (null == o)
			throw new NullPointerException("ontology is null.");

		ClassNode root = new ClassNode(o);
		Iterator<OClass> itops = o.getOClasses(true).iterator();
		Vector<ClassNode> kids = new Vector<ClassNode>();
		if (includeAnonymousClasses) {
			while (itops.hasNext()) {
				ClassNode node = new ClassNode(itops.next());
				kids.add(node);
			} // while
		} else {
			while (itops.hasNext()) {
				OClass aClass = itops.next();
				if (aClass instanceof AnonymousClass) {
					continue;
				}
				ClassNode node = new ClassNode(aClass);
				kids.add(node);
			} // while
		}

		root.source = o;
		root.setChildren(kids);
		Vector<ClassNode> parents = kids;
		Vector<ClassNode> allKids;
		do {
			allKids = new Vector<ClassNode>();
			for (int i = 0; i < parents.size(); i++) {
				ClassNode parent = parents.get(i);
				kids = new Vector<ClassNode>();

				// skip this one if it's an instance
				if (parent.getSource() instanceof OInstance)
					continue;

				OClass ocl = (OClass) parent.getSource();

				// if we include instances, then get them too
				if (includeInstances && (o instanceof Ontology)) {
					Ontology kb = (Ontology) o;
					Set<OInstance> instances = kb.getOInstances(ocl,
							OConstants.Closure.DIRECT_CLOSURE);
					if (instances != null && !instances.isEmpty()) {
						Iterator<OInstance> insti = instances.iterator();
						while (insti.hasNext())
							kids.add(new ClassNode(insti.next()));
					}
				}

				if (0 == ocl.getSubClasses(OConstants.Closure.DIRECT_CLOSURE)
						.size()) {
					if (!kids.isEmpty())
						// add the instances as children, but do not add them
						// for future
						// traversal to allKids
						parent.setChildren(kids);
					continue;
				} // if 0 children

				Iterator<OClass> kidsi = ocl.getSubClasses(
						OConstants.Closure.DIRECT_CLOSURE).iterator();

				while (kidsi.hasNext()) {
					OClass aClass = kidsi.next();
					if (!includeAnonymousClasses
							&& aClass instanceof AnonymousClass)
						continue;
					kids.add(new ClassNode(aClass));
				} // while kidsi
				parent.setChildren(kids);
				allKids.addAll(kids);

			} // for i
			parents = allKids;
		} while (0 < allKids.size());

		return root;
	}// createRootNode()

	/**
	 * Creates a structure representing the class hierarchy of an ontology and
	 * the gazetteerLists mapped to it.
	 * 
	 * @param o
	 *            an ontology
	 * @param mapping
	 *            mapping definition
	 * @param nameVsNode
	 *            : this is actually a return value: should be initialized
	 *            before passing to this method and afterwards one can find a
	 *            mapping of class names vs class nodes there.
	 * @return the root node of the structure
	 */
	@SuppressWarnings("deprecation")
	public static ClassNode createRootNode(Ontology o,
			MappingDefinition mapping, Map<String, ClassNode> nameVsNode) {
		if (null == o || null == nameVsNode || null == mapping)
			throw new NullPointerException(
					"mapping, nameVsNode or ontology-o is null.");
		ClassNode root = new ClassNode(o);
		Iterator<OClass> itops = o.getOClasses(true).iterator();
		Vector<ClassNode> kids = new Vector<ClassNode>();
		while (itops.hasNext()) {
			ClassNode node = new ClassNode(itops.next());
			nameVsNode.put(node.toString(), node);
			kids.add(node);
		} // while

		root.source = o;
		root.setChildren(kids);
		Vector<ClassNode> parents = kids;
		Vector<ClassNode> allKids;
		do {
			allKids = new Vector<ClassNode>();
			for (int i = 0; i < parents.size(); i++) {
				ClassNode parent = parents.get(i);

				OClass ocl = (OClass) parent.getSource();
				if (0 == ocl.getSubClasses(OConstants.Closure.DIRECT_CLOSURE)
						.size()) {
					continue;
				} // if 0 children

				Iterator<OClass> kidsi = ocl.getSubClasses(
						OConstants.Closure.DIRECT_CLOSURE).iterator();

				kids = new Vector<ClassNode>();
				while (kidsi.hasNext()) {
					ClassNode cn = new ClassNode(kidsi.next());
					kids.add(cn);
					nameVsNode.put(cn.toString(), cn);
				} // while kidsi
				parent.setChildren(kids);
				allKids.addAll(kids);

			} // for i
			parents = allKids;
		} while (0 < allKids.size());

		// display mapping
		Iterator<MappingNode> inodes = mapping.iterator();
		MappingNode mn;
		while (inodes.hasNext()) {
			mn = inodes.next();
			URL turl = null;
			try {
				turl = new URL(mn.getOntologyID());
			} catch (java.net.MalformedURLException x) {
			}
			if (null != turl) {
				Ontology o2 = null;
				try {
					o2 = gate.creole.ontology.OntologyUtilities.getOntology(turl);
				} catch (gate.creole.ResourceInstantiationException x) {
				}
				if (o2 != null && o2.equals(o)) {
					ClassNode cmn = new ClassNode(mn);
					ClassNode cn = nameVsNode.get(mn.getClassID());
					if (null != cn) {
						cn.children.add(cn.children.size(), cmn);
					}
				}// if from the same ontology
			} // turl != null
		}// while inodes

		return root;
	}// createRootNode()

	/**
	 * Constructs a root class node from an ontology
	 * 
	 * @param o
	 *            the ontology
	 */
	public ClassNode(Ontology o) {
		name = o.getName();
	}

	/**
	 * Constructs a class node given an ontology class
	 * 
	 * @param clas
	 *            ontology class
	 */
	public ClassNode(OClass clas) {
		name = clas.getName();
		source = clas;
	}

	/**
	 * Constructs a class node given an ontology instance
	 * 
	 * @param instance
	 *            ontology instance
	 */
	public ClassNode(OInstance instance) {
		name = instance.getName();
		source = instance;
	}

	/**
	 * Constructs a class node given a mapping node
	 * 
	 * @param mapNode
	 *            mapping node
	 */
	public ClassNode(MappingNode mapNode) {
		name = mapNode.getList();
		source = mapNode;
	}

	public int getIndexOfChild(Object child) {
		return children.indexOf(child);
	}

	public Iterator<ClassNode> getChildren() {
		return children.iterator();
	}

	public void setChildren(Vector<ClassNode> chldrn) {
		children = chldrn;
	}

	public Vector<ClassNode> children() {
		return children;
	}

	public String toString() {
		return name;
	}

	public int getChildCount() {
		return children.size();
	}

	public IFolder getChild(int index) {
		return children.get(index);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((source == null) ? 0 : source.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ClassNode other = (ClassNode) obj;
		if (source == null) {
			if (other.source != null)
				return false;
		} else if (!source.equals(other.source))
			return false;
		return true;
	}

	/**
	 * Gets the Source object
	 * 
	 * @return the source object e.g. an gate.creole.TClass or a
	 *         gate.creole.Ontology
	 */
	public Object getSource() {
		return source;
	}

	/**
	 * Sets the source object
	 * 
	 * @param o
	 *            the source object to be set
	 */
	public void setSource(Object o) {
		source = o;
	}

	/**
	 * Renames this class node
	 * 
	 * @param newName
	 *            the new name of the node
	 */
	public void rename(String newName) {
		name = newName;
	}

	/**
	 * Removes a sub class
	 * 
	 * @param sub
	 *            the sub class to be removed
	 */
	public void removeSubNode(ClassNode sub) {
		if (children.contains(sub)) {
			children.remove(sub);
			Object source = this.getSource();
			if (source instanceof OClass) {
				OClass c = (OClass) source;
				if (sub.getSource() instanceof OClass)
					c.removeSubClass((OClass) sub.getSource());
				else if (sub.getSource() instanceof OInstance
						&& c.getOntology() instanceof Ontology)
					((Ontology) c.getOntology())
							.removeOInstance((OInstance) sub.getSource());
			} else if (source instanceof Ontology) {
				Ontology o = (Ontology) source;
				o.removeOClass((OClass) sub.getSource());
			} else if (source instanceof OInstance) {
				// cannot remove anything from an instance
				return;
			} else {
				throw new GateRuntimeException(
						"Can not remove a sub node from a classnode.\n"
								+ "The source is neither an Ontology neither TClass");
			} // else
		} // if contains
	} // removeSubNode

	/**
	 * Adds a sub node
	 * 
	 * @param sub
	 *            the sub node to be added
	 */
	public void addSubNode(ClassNode sub) {
		if (!children.contains(sub)) {
			Object source = this.getSource();
			if (source instanceof OClass) {
				OClass c = (OClass) source;
				if (!(sub.getSource() instanceof OClass)
						&& !(sub.getSource() instanceof OInstance))
					throw new GateRuntimeException(
							"The sub node's source is not an instance of TClass or OInstance");
				if (sub.getSource() instanceof OClass) {
					OClass sc = (OClass) sub.getSource();
					c.addSubClass(sc);
					// this code originally used the deprecated method
					// addOClass(URI, byte)
					// with the byte constant indicating a class, without
					// checking for
					// sc not being an anonymous class.
					c.getOntology().addOClass((OURI) sc.getONodeID());
					children.add(sub);
				}
				if (sub.getSource() instanceof OInstance
						&& c.getOntology() instanceof Ontology) {
					OInstance inst = (OInstance) sub.getSource();
					if (!((Ontology) c.getOntology()).containsOInstance(inst
							.getOURI())) {
						Iterator<OClass> instClasses = inst.getOClasses(
								OConstants.Closure.DIRECT_CLOSURE).iterator();
						while (instClasses.hasNext()) {
							((Ontology) c.getOntology()).addOInstance(
									inst.getOURI(), instClasses.next());
						}
					}

					children.add(sub);
				}

			} else {
				if (source instanceof Ontology) {
					Ontology o = (Ontology) source;
					if (!(sub.getSource() instanceof OClass))
						throw new GateRuntimeException(
								"The sub node's source is not an instance of TClass");
					OClass sc = (OClass) sub.getSource();
					o.addOClass((OURI) sc.getONodeID());
					children.add(sub);
				} else {
					throw new GateRuntimeException(
							"cannot add a sub node to something which "
									+ "is neither an Ontology neither an TClass");
				} // else
			} // else
		} // if ! contains
	} // addSubNode()

	/*--- Transferable interface implementation ---*/
	public boolean isDataFlavorSupported(DataFlavor df) {
		return df.equals(CLASS_NODE_FLAVOR);
	}

	public Object getTransferData(DataFlavor df)
			throws UnsupportedFlavorException, IOException {
		if (df.equals(CLASS_NODE_FLAVOR)) {
			return this;
		} else
			throw new UnsupportedFlavorException(df);
	}

	public DataFlavor[] getTransferDataFlavors() {
		return flavors;
	}

} // class ClassNode