/*
* OntologyTreePanel.java
*
* Niraj Aswani, 12/March/07
*
* $Id: OntologyTreePanel.html,v 1.0 2007/03/12 16:13:01 niraj Exp $
*/
package gate.creole.ontology.ocat;
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import gate.*;
import gate.creole.ontology.AnnotationProperty;
import gate.creole.ontology.DatatypeProperty;
import gate.creole.ontology.Literal;
import gate.creole.ontology.OClass;
import gate.creole.ontology.OConstants;
import gate.creole.ontology.OInstance;
import gate.creole.ontology.ObjectProperty;
import gate.creole.ontology.Ontology;
import gate.creole.ontology.RDFProperty;
import com.ontotext.gate.vr.ClassNode;
import com.ontotext.gate.vr.OntoTreeModel;
import gate.swing.*;
import java.util.*;
import java.util.List;
import com.ontotext.gate.vr.IFolder;
import gate.gui.docview.*;
/**
* This class provides a GUI frame for the OCAT tool, where one of the
* components is the OntologyTree, the other one is Ontology Options and so on.
*
* @author niraj
*/
public class OntologyTreePanel extends JPanel {
/**
* Serial version ID
*/
private static final long serialVersionUID = 3618419328190592304L;
/** Instance of JTree used to store information about ontology classes */
protected JTree currentOntologyTree;
/** The current currentOntologyTreeModel */
private OntoTreeModel currentOntologyTreeModel;
/** ToolBars that displays the different options */
private JToolBar leftToolBar;
/** OntologyViewerOptions instance */
protected OntologyViewerOptions ontologyViewerOptions;
/**
* Stores all the various ontology2OntoTreeModels for different ontologies
*/
protected HashMap<Ontology, OntoTreeModel> ontology2OntoTreeModels;
/** Stores various color schemes for different ontology classes */
protected HashMap<Ontology, HashMap<String, Color>> ontology2ColorSchemesMap;
/** Current ontologyColorScheme */
protected HashMap<String, Color> currentOResource2ColorMap;
/** This stores Class selection map for each individual loaded ontology */
protected HashMap<Ontology, HashMap<String, Boolean>> ontology2OResourceSelectionMap;
/** Class Selection map for the current ontology */
protected HashMap<String, Boolean> currentOResource2IsSelectedMap;
/** This stores Class selection map for each individual loaded ontology */
protected HashMap<Ontology, Set<RDFProperty>> ontology2PropertiesMap;
/** Class Selection map for the current ontology */
protected Set<RDFProperty> currentProperties;
/**
* This stores instances and the classes that instance belongs to
*/
protected HashMap<Ontology, HashMap<String, Set<OClass>>> ontology2PropValuesAndInstances2ClassesMap;
/**
* instances of the ontology and their classes
*/
protected HashMap<String, Set<OClass>> currentPropValuesAndInstances2ClassesMap;
/** Central Textual Document View */
private TextualDocumentView textView;
/**
* Current Annotation Map that stores the annotation in arraylist for each
* concept
*/
protected HashMap<String, ArrayList<Annotation>> currentOResourceName2AnnotationsListMap;
/** Instance of colorGenerator */
private ColorGenerator colorGenerator;
/** Current Ontology */
private Ontology currentOntology;
/**
* OntologyTreeListener that listens to the selection of ontology classes
*/
protected OntologyTreeListener ontoTreeListener;
/** Instance of ontology Viewer */
protected OntologyViewer ontoViewer;
/**
* Indicates whether the annotation window is being shown or not
*/
protected boolean showingAnnotationWindow = false;
/** Constructor */
public OntologyTreePanel(OntologyViewer ontoViewer) {
this.ontoViewer = ontoViewer;
this.textView = ontoViewer.documentTextualDocumentView;
this.ontologyViewerOptions = new OntologyViewerOptions(this);
ontology2ColorSchemesMap = new HashMap<Ontology, HashMap<String, Color>>();
ontology2PropValuesAndInstances2ClassesMap =
new HashMap<Ontology, HashMap<String, Set<OClass>>>();
ontology2OntoTreeModels = new HashMap<Ontology, OntoTreeModel>();
currentOResource2ColorMap = new HashMap<String, Color>();
ontology2OResourceSelectionMap =
new HashMap<Ontology, HashMap<String, Boolean>>();
currentOResource2IsSelectedMap = new HashMap<String, Boolean>();
ontology2PropertiesMap = new HashMap<Ontology, Set<RDFProperty>>();
colorGenerator = new ColorGenerator();
initGUI();
}
/**
* This method finds out the ClassNode node in the ontology Tree for given
* class
*
* @param classValue
* @return
*/
public ClassNode getFirstNode(String classValue) {
// lets first convert this classValue into the className
int index = classValue.lastIndexOf("#");
if(index < 0) index = classValue.lastIndexOf("/");
if(index < 0) index = classValue.lastIndexOf(":");
if(index >= 0) {
classValue = classValue.substring(index + 1, classValue.length());
}
ClassNode currentNode = (ClassNode)currentOntologyTree.getModel().getRoot();
return getFirstClassNode(currentNode, classValue);
}
/**
* Internal recursive method to find out the Node for given class Value under
* the heirarchy of given node
*
* @param node
* @param classValue
* @return
*/
private ClassNode getFirstClassNode(ClassNode node, String classValue) {
if(node.toString().intern() == classValue.intern()) { return node; }
Iterator children = node.getChildren();
while(children.hasNext()) {
ClassNode tempNode = (ClassNode)children.next();
ClassNode returnedNode = getFirstClassNode(tempNode, classValue);
if(returnedNode != null) { return returnedNode; }
}
return null;
}
/**
* This method finds out the ClassNode node in the ontology Tree for given
* class
*
* @param classValue
* @return
*/
public List<ClassNode> getNode(String classValue) {
// lets first convert this classValue into the className
int index = classValue.lastIndexOf("#");
if(index < 0) index = classValue.lastIndexOf("/");
if(index < 0) index = classValue.lastIndexOf(":");
if(index >= 0) {
classValue = classValue.substring(index + 1, classValue.length());
}
ClassNode currentNode = (ClassNode)currentOntologyTree.getModel().getRoot();
return getClassNode(currentNode, classValue);
}
/**
* Internal recursive method to find out the Node for given class Value under
* the heirarchy of given node
*
* @param node
* @param classValue
* @return
*/
private List<ClassNode> getClassNode(ClassNode node, String classValue) {
List<ClassNode> cNodes = new ArrayList<ClassNode>();
if(node.toString().equalsIgnoreCase(classValue)) {
cNodes.add(node);
return cNodes;
}
Iterator children = node.getChildren();
while(children.hasNext()) {
ClassNode tempNode = (ClassNode)children.next();
List<ClassNode> returnedNodes = getClassNode(tempNode, classValue);
if(returnedNodes != null) {
cNodes.addAll(returnedNodes);
}
}
return cNodes;
}
/** Deletes the Annotations from the document */
public void deleteAnnotation(Annotation annot) {
// and now removing from the actual document
AnnotationSet set = ontoViewer.getDocument().getAnnotations();
if(!(set.remove(annot))) {
Map annotSetMap = ontoViewer.getDocument().getNamedAnnotationSets();
if(annotSetMap != null) {
java.util.List<String> setNames =
new ArrayList<String>(annotSetMap.keySet());
Collections.sort(setNames);
Iterator<String> setsIter = setNames.iterator();
while(setsIter.hasNext()) {
set = ontoViewer.getDocument().getAnnotations(setsIter.next());
if(set.remove(annot)) { return; }
}
}
}
}
/** Returns the current ontology */
public Ontology getCurrentOntology() {
return currentOntology;
}
/** Returns the instance of highlighter */
public javax.swing.text.Highlighter getHighlighter() {
return ((JTextArea)((JScrollPane)textView.getGUI()).getViewport().getView())
.getHighlighter();
}
/** Returns the associated color for the given class */
public Color getHighlightColor(String classVal) {
return (Color)currentOResource2ColorMap.get(classVal);
}
/** Initialize the GUI */
private void initGUI() {
currentOntologyTree = new JTree();
ToolTipManager.sharedInstance().registerComponent(currentOntologyTree);
currentOntologyTree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
this.setLayout(new BorderLayout());
this.add(new JScrollPane(currentOntologyTree), BorderLayout.CENTER);
leftToolBar = new JToolBar(JToolBar.VERTICAL);
leftToolBar.setFloatable(false);
// this.add(leftToolBar, BorderLayout.WEST);
ontoTreeListener = new OntologyTreeListener(this);
currentOntologyTree.addMouseListener(ontoTreeListener);
CheckRenderer cellRenderer = new CheckRenderer(this);
currentOntologyTree.setCellRenderer(cellRenderer);
}
/** A method to show an empty ontology tree */
public void showEmptyOntologyTree() {
currentOntology = null;
currentOntologyTreeModel = null;
currentOResource2ColorMap = null;
currentOResource2IsSelectedMap = null;
currentProperties = null;
currentOntologyTree.setVisible(false);
ontoTreeListener.removeHighlights();
}
/**
* This method is called to remove the stored ontology model and free up the
* memory with other resources occupied by the removed ontology
*/
public void removeOntologyTreeModel(Ontology ontology,
boolean wasCurrentlySelected) {
this.ontology2OntoTreeModels.remove(ontology);
this.ontology2ColorSchemesMap.remove(ontology);
this.ontology2OResourceSelectionMap.remove(ontology);
this.ontology2PropValuesAndInstances2ClassesMap.remove(ontology);
this.ontology2PropertiesMap.remove(ontology);
if(ontology2OntoTreeModels == null || ontology2OntoTreeModels.size() == 0) {
showEmptyOntologyTree();
}
}
/**
* This method is used to plot the ontology on the tree and generate/load the
* respective data in the memory
*
* @param ontology
* - the ontology to be ploted
* @param currentOResourceName2AnnotationsListMap
* - the annotationMap which contains Key=concept(String)
* Value=annotations(ArrayList)
*/
public void showOntologyInOntologyTreeGUI(Ontology ontology,
HashMap<String, ArrayList<Annotation>> annotMap) {
this.currentOResourceName2AnnotationsListMap = annotMap;
if(currentOntology != null && currentOResource2ColorMap != null)
ontology2ColorSchemesMap.put(currentOntology, currentOResource2ColorMap);
if(currentOntology != null && currentOResource2IsSelectedMap != null)
ontology2OResourceSelectionMap.put(currentOntology,
currentOResource2IsSelectedMap);
if(currentOntology != null && currentOntologyTreeModel != null
&& ontology2OntoTreeModels.containsKey(currentOntology))
ontology2OntoTreeModels.put(currentOntology, currentOntologyTreeModel);
if(currentOntology != null
&& currentPropValuesAndInstances2ClassesMap != null
&& ontology2OntoTreeModels.containsKey(currentOntology))
ontology2PropValuesAndInstances2ClassesMap.put(currentOntology,
currentPropValuesAndInstances2ClassesMap);
if(currentOntology != null && currentProperties != null
&& ontology2OntoTreeModels.containsKey(currentOntology))
ontology2PropertiesMap.put(currentOntology, currentProperties);
currentOntology = ontology;
ClassNode root = null;
// lets create the new model for this new selected ontology
if(ontology2OntoTreeModels != null
&& ontology2OntoTreeModels.containsKey(ontology)) {
currentOntologyTreeModel = ontology2OntoTreeModels.get(ontology);
currentOResource2ColorMap = ontology2ColorSchemesMap.get(ontology);
currentOResource2IsSelectedMap =
ontology2OResourceSelectionMap.get(ontology);
currentPropValuesAndInstances2ClassesMap =
ontology2PropValuesAndInstances2ClassesMap.get(ontology);
currentProperties = ontology2PropertiesMap.get(ontology);
}
else {
root =
ClassNode.createRootNode(ontology, true, ontologyViewerOptions
.showAnonymousClasses());
HashMap<String, Color> newColorScheme = new HashMap<String, Color>();
setColorScheme(root, newColorScheme);
currentOResource2ColorMap = newColorScheme;
ontology2ColorSchemesMap.put(ontology, newColorScheme);
currentOntologyTreeModel = new OntoTreeModel(root);
ontology2OntoTreeModels.put(ontology, currentOntologyTreeModel);
HashMap<String, Boolean> newClassSelection =
new HashMap<String, Boolean>();
setOntoTreeClassSelection(root, newClassSelection);
currentOResource2IsSelectedMap = newClassSelection;
ontology2OResourceSelectionMap.put(ontology, newClassSelection);
currentProperties = obtainProperties(ontology);
ontology2PropertiesMap.put(ontology, currentProperties);
currentPropValuesAndInstances2ClassesMap =
obtainPVnInst2ClassesMap(ontology, currentProperties);
ontology2PropValuesAndInstances2ClassesMap.put(ontology,
currentPropValuesAndInstances2ClassesMap);
}
currentOntologyTree.setModel(currentOntologyTreeModel);
// update the GUI part of the Tree
currentOntologyTree.invalidate();
}
/**
* This method returns the properties available in the ontology
*
* @param ontology
* @return
*/
private Set<RDFProperty> obtainProperties(Ontology ontology) {
Set<RDFProperty> toReturn = new HashSet<RDFProperty>();
// lets add all properties
Set<RDFProperty> props = ontology.getPropertyDefinitions();
Iterator<RDFProperty> iter = props.iterator();
while(iter.hasNext()) {
final RDFProperty p = iter.next();
if(p instanceof AnnotationProperty || p instanceof DatatypeProperty
|| p instanceof ObjectProperty) {
toReturn.add(p);
continue;
}
}
return toReturn;
}
/**
* This method iterates through each instance of the ontology and obtains its
* all set properties. For each set property, obtains its value and add it to
* the returning map as a key. A set of direct classes of the instance then
* becomes the value for this key.
*
* @param ontology
* @return
*/
private HashMap<String, Set<OClass>> obtainPVnInst2ClassesMap(
Ontology ontology, Set<RDFProperty> propertySet) {
HashMap<String, Set<OClass>> map = new HashMap<String, Set<OClass>>();
Set<OInstance> instances = ontology.getOInstances();
Iterator<OInstance> instIter = instances.iterator();
while(instIter.hasNext()) {
OInstance anInst = instIter.next();
Set<OClass> classes = anInst.getOClasses(OConstants.DIRECT_CLOSURE);
updatePVnInst2ClassesMap(anInst, propertySet, classes, map);
}
return map;
}
/**
* This method iterates through each instance of the ontology and obtains its
* all set properties. For each set property, obtains its value and add it to
* the returning map as a key. A set of direct classes of the instance then
* becomes the value for this key.
*
* @param ontology
* @return
*/
public void updatePVnInst2ClassesMap(OInstance anInst,
Set<RDFProperty> propertySet, Set<OClass> classes,
HashMap<String, Set<OClass>> map) {
String anInstName = anInst.getName();
if(map.containsKey(anInstName.toLowerCase())) {
Set<OClass> availableClasses = map.get(anInstName.toLowerCase());
availableClasses.addAll(classes);
}
else {
map.put(anInstName.toLowerCase(), classes);
}
Iterator<RDFProperty> propertyIter = propertySet.iterator();
while(propertyIter.hasNext()) {
RDFProperty anRDFProp = propertyIter.next();
Set<String> stringValues = new HashSet<String>();
// here we check what type of property it is
if(anRDFProp instanceof AnnotationProperty) {
java.util.List<Literal> values =
anInst.getAnnotationPropertyValues((AnnotationProperty)anRDFProp);
for(int i = 0; i < values.size(); i++) {
stringValues.add(values.get(i).getValue().toLowerCase());
}
}
else if(anRDFProp instanceof DatatypeProperty) {
java.util.List<Literal> values =
anInst.getDatatypePropertyValues((DatatypeProperty)anRDFProp);
for(int i = 0; i < values.size(); i++) {
stringValues.add(values.get(i).getValue().toLowerCase());
}
}
else if(anRDFProp instanceof ObjectProperty) {
java.util.List<OInstance> values =
anInst.getObjectPropertyValues((ObjectProperty)anRDFProp);
for(int i = 0; i < values.size(); i++) {
stringValues.add(values.get(i).toString().toLowerCase());
}
}
if(stringValues.isEmpty()) continue;
Iterator<String> stringValIter = stringValues.iterator();
while(stringValIter.hasNext()) {
String aValue = stringValIter.next();
if(map.containsKey(aValue)) {
Set<OClass> availableClasses = map.get(aValue);
availableClasses.addAll(classes);
}
else {
map.put(aValue, classes);
}
}
}
}
/**
* For every ontology it generates the colors only once at the begining which
* should remain same throughout the programe
*
* @param root
* - the root (top class) of the ontology
* @param colorScheme
* - and the colorScheme hashmap Key=conceptName, Value:associated
* color map. if provided as a new fresh instance of hashmap with
* size zero, it parses through the whole ontology and generate the
* random color instances for all the classes and stores them in the
* provided colorScheme hashmap
*/
public void setColorScheme(IFolder root, HashMap<String, Color> colorScheme) {
if(!colorScheme.containsKey(root.toString())) {
colorScheme.put(root.toString(),
AnnotationSetsView.getColor(root.toString()));
Iterator children = root.getChildren();
while(children.hasNext()) {
setColorScheme((IFolder)children.next(), colorScheme);
}
}
}
/**
* This is to initialise the classSelection as false to all the classes
*
* @param root
* @param classSelection
*/
public void setOntoTreeClassSelection(IFolder root,
HashMap<String, Boolean> classSelection) {
if(!classSelection.containsKey(root.toString())) {
classSelection.put(root.toString(), new Boolean(true));
Iterator children = root.getChildren();
while(children.hasNext()) {
setOntoTreeClassSelection((IFolder)children.next(), classSelection);
}
}
}
/**
* returns the currentOntologyTree Panel
*
* @return
*/
public Component getGUI() {
return this;
}
/**
* This method select/deselect the classes in the classSelectionMap
*
* @param className
* @param value
*/
public void setSelected(String className, boolean value) {
currentOResource2IsSelectedMap.put(className, new Boolean(value));
ontology2OResourceSelectionMap.put(currentOntology,
currentOResource2IsSelectedMap);
}
public void setColor(String className, Color col) {
currentOResource2ColorMap.put(className, col);
ontology2ColorSchemesMap.put(currentOntology, currentOResource2ColorMap);
}
public Set<String> getAllClassNames() {
Set<String> toReturn = new HashSet<String>();
for(String aResource : currentOResource2IsSelectedMap.keySet()) {
if(currentOntology.getOResourceByName(aResource) instanceof OClass) {
toReturn.add(aResource);
}
}
return toReturn;
}
public Set<String> getAllInstanceNames() {
Set<String> toReturn = new HashSet<String>();
for(String aResource : currentOResource2IsSelectedMap.keySet()) {
if(currentOntology.getOResourceByName(aResource) instanceof OInstance) {
toReturn.add(aResource);
}
}
return toReturn;
}
}