OntologyEditor.java
0001 /*
0002  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
0003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
0004  *
0005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
0006  *  software, licenced under the GNU Library General Public License,
0007  *  Version 2, June 1991 (in the distribution as file licence.html,
0008  *  and also available at http://gate.ac.uk/gate/licence.html).
0009  *
0010  *  Niraj Aswani, 09/March/07
0011  *
0012  *  $Id: OntologyEditor.html,v 1.0 2007/03/09 16:13:01 niraj Exp $
0013  */
0014 package gate.gui.ontology;
0015 
0016 import gate.Resource;
0017 import gate.creole.AbstractVisualResource;
0018 import gate.creole.ResourceInstantiationException;
0019 import gate.creole.ontology.*;
0020 import gate.event.*;
0021 import gate.gui.*;
0022 import gate.swing.XJTable;
0023 import java.awt.*;
0024 import java.awt.datatransfer.Transferable;
0025 import java.awt.dnd.DnDConstants;
0026 import java.awt.dnd.DragGestureEvent;
0027 import java.awt.dnd.DragGestureListener;
0028 import java.awt.dnd.DragGestureRecognizer;
0029 import java.awt.dnd.DragSource;
0030 import java.awt.dnd.DragSourceContext;
0031 import java.awt.dnd.DragSourceDragEvent;
0032 import java.awt.dnd.DragSourceDropEvent;
0033 import java.awt.dnd.DragSourceEvent;
0034 import java.awt.dnd.DragSourceListener;
0035 import java.awt.dnd.DropTarget;
0036 import java.awt.dnd.DropTargetDragEvent;
0037 import java.awt.dnd.DropTargetDropEvent;
0038 import java.awt.dnd.DropTargetEvent;
0039 import java.awt.dnd.DropTargetListener;
0040 import java.awt.event.ActionEvent;
0041 import java.awt.event.ActionListener;
0042 import java.awt.event.ComponentEvent;
0043 import java.awt.event.ComponentListener;
0044 import java.awt.event.MouseAdapter;
0045 import java.awt.event.MouseEvent;
0046 import java.util.*;
0047 import java.util.List;
0048 import javax.swing.*;
0049 import javax.swing.border.TitledBorder;
0050 import javax.swing.event.TreeSelectionEvent;
0051 import javax.swing.event.TreeSelectionListener;
0052 import javax.swing.tree.*;
0053 
0054 
0055 /**
0056  * The GUI for the Ontology Editor
0057  
0058  @author niraj
0059  
0060  */
0061 public class OntologyEditor extends AbstractVisualResource
0062                                                           implements
0063                                                           ResizableVisualResource,
0064                                                           OntologyModificationListener {
0065 
0066   private static final long serialVersionUID = 3257847701214345265L;
0067 
0068   /*
0069    * (non-Javadoc)
0070    
0071    * @see gate.creole.AbstractVisualResource#setTarget(java.lang.Object)
0072    */
0073   public void setTarget(Object target) {
0074     this.ontology = (Ontology)target;
0075     selectedNodes = new ArrayList<DefaultMutableTreeNode>();
0076     detailsTableModel.setOntology(ontology);
0077     topClassAction.setOntology(ontology);
0078     subClassAction.setOntology(ontology);
0079     instanceAction.setOntology(ontology);
0080     annotationPropertyAction.setOntology(ontology);
0081     datatypePropertyAction.setOntology(ontology);
0082     objectPropertyAction.setOntology(ontology);
0083     symmetricPropertyAction.setOntology(ontology);
0084     transitivePropertyAction.setOntology(ontology);
0085     deleteOntoResourceAction.setOntology(ontology);
0086     restrictionAction.setOntology(ontology);
0087     ontology.removeOntologyModificationListener(this);
0088     rebuildModel();
0089     ontology.addOntologyModificationListener(this);
0090   }
0091 
0092   /**
0093    * Init method, that creates this object and returns this object as a
0094    * resource
0095    */
0096   public Resource init() throws ResourceInstantiationException {
0097     super.init();
0098     initLocalData();
0099     initGUIComponents();
0100     initListeners();
0101     return this;
0102   }
0103 
0104   /**
0105    * Initialize the local data
0106    */
0107   protected void initLocalData() {
0108     itemComparator = new OntologyItemComparator();
0109     listeners = new ArrayList<TreeNodeSelectionListener>();
0110   }
0111 
0112   /**
0113    * Initialize the GUI Components
0114    */
0115   protected void initGUIComponents() {
0116     this.setLayout(new BorderLayout());
0117     mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
0118     this.add(mainSplit, BorderLayout.CENTER);
0119     tabbedPane = new JTabbedPane();
0120     mainSplit.setLeftComponent(tabbedPane);
0121 
0122     rootNode = new DefaultMutableTreeNode(null, true);
0123     treeModel = new DefaultTreeModel(rootNode);
0124     tree = new DnDJTree(treeModel);
0125     tree.setRootVisible(false);
0126     tree.setShowsRootHandles(true);
0127     tree.setCellRenderer(new OntoTreeCellRenderer());
0128     tree.getSelectionModel().setSelectionMode(
0129             TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
0130     scroller = new JScrollPane(tree);
0131 
0132     // enable tooltips for the tree
0133     ToolTipManager.sharedInstance().registerComponent(tree);
0134     tabbedPane.addTab("Classes & Instances", scroller);
0135     scroller.setBorder(new TitledBorder("Classes and Instances"));
0136     // ----------------------------------------------
0137 
0138     propertyRootNode = new DefaultMutableTreeNode(null, true);
0139     propertyTreeModel = new DefaultTreeModel(propertyRootNode);
0140     propertyTree = new DnDJTree(propertyTreeModel);
0141     propertyTree.setRootVisible(false);
0142     propertyTree.setShowsRootHandles(true);
0143     propertyTree.setCellRenderer(new OntoTreeCellRenderer());
0144     propertyTree.getSelectionModel().setSelectionMode(
0145             TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
0146     propertyScroller = new JScrollPane(propertyTree);
0147     // enable tooltips for the tree
0148     ToolTipManager.sharedInstance().registerComponent(propertyTree);
0149     tabbedPane.addTab("Properties", propertyScroller);
0150     propertyScroller.setBorder(new TitledBorder("Properties"));
0151     // -----------------------------------------------
0152     detailsTableModel = new DetailsTableModel();
0153     // ----------------
0154     propertyDetailsTableModel = new PropertyDetailsTableModel();
0155     // ----------------
0156     detailsTable = new XJTable(detailsTableModel);
0157     ((XJTable)detailsTable).setSortable(false);
0158     DetailsTableCellRenderer renderer = new DetailsTableCellRenderer();
0159     detailsTable.getColumnModel().getColumn(DetailsTableModel.EXPANDED_COLUMN)
0160             .setCellRenderer(renderer);
0161     detailsTable.getColumnModel().getColumn(DetailsTableModel.LABEL_COLUMN)
0162             .setCellRenderer(renderer);
0163     detailsTable.getColumnModel().getColumn(DetailsTableModel.VALUE_COLUMN)
0164             .setCellRenderer(renderer);
0165     detailsTable.getColumnModel().getColumn(DetailsTableModel.DELETE_COLUMN)
0166             .setCellRenderer(renderer);
0167 
0168     detailsTable.setShowGrid(false);
0169     detailsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
0170     detailsTable.setColumnSelectionAllowed(true);
0171     detailsTable.setRowSelectionAllowed(true);
0172     detailsTable.setTableHeader(null);
0173     detailsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
0174     detailsTableScroller = new JScrollPane(detailsTable);
0175     detailsTableScroller.getViewport().setOpaque(true);
0176     detailsTableScroller.getViewport().setBackground(
0177             detailsTable.getBackground());
0178     mainSplit.setRightComponent(detailsTableScroller);
0179 
0180     // -------------------
0181     propertyDetailsTable = new XJTable(propertyDetailsTableModel);
0182     ((XJTable)propertyDetailsTable).setSortable(false);
0183     PropertyDetailsTableCellRenderer propertyRenderer = new PropertyDetailsTableCellRenderer(
0184             propertyDetailsTableModel);
0185     propertyDetailsTable.getColumnModel().getColumn(
0186             PropertyDetailsTableModel.EXPANDED_COLUMN).setCellRenderer(
0187             propertyRenderer);
0188     propertyDetailsTable.getColumnModel().getColumn(
0189             PropertyDetailsTableModel.LABEL_COLUMN).setCellRenderer(
0190             propertyRenderer);
0191     propertyDetailsTable.getColumnModel().getColumn(
0192             PropertyDetailsTableModel.VALUE_COLUMN).setCellRenderer(
0193             propertyRenderer);
0194     propertyDetailsTable.getColumnModel().getColumn(
0195             PropertyDetailsTableModel.DELETE_COLUMN).setCellRenderer(
0196             propertyRenderer);
0197 
0198     propertyDetailsTable.setShowGrid(false);
0199     propertyDetailsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
0200     propertyDetailsTable.setColumnSelectionAllowed(true);
0201     propertyDetailsTable.setRowSelectionAllowed(true);
0202     propertyDetailsTable.setTableHeader(null);
0203     propertyDetailsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
0204 
0205     propertyDetailsTableScroller = new JScrollPane(propertyDetailsTable);
0206     propertyDetailsTableScroller.getViewport().setOpaque(true);
0207     propertyDetailsTableScroller.getViewport().setBackground(
0208             propertyDetailsTable.getBackground());
0209 
0210     // --------------------
0211 
0212     toolBar = new JToolBar(JToolBar.HORIZONTAL);
0213     searchAction = new SearchAction("", MainFrame.getIcon("ontology-search"),
0214             this);
0215     search = new JButton(searchAction);
0216     search.setToolTipText("Advanced search in the ontology");
0217 
0218 
0219     topClassAction = new TopClassAction("", MainFrame
0220             .getIcon("ontology-topclass"));
0221     topClass = new JButton(topClassAction);
0222     topClass.setToolTipText("Add New Top Class");
0223 
0224     refreshOntologyBtn = 
0225       new JButton(MainFrame.getIcon("crystal-clear-action-reload-small"));
0226     refreshOntologyBtn.setToolTipText("Rebuilds the ontology tree");
0227     refreshOntologyBtn.addActionListener(new ActionListener() {
0228       public void actionPerformed(ActionEvent ae) {
0229         rebuildModel();
0230       }
0231     });
0232     
0233     subClassAction = new SubClassAction("", MainFrame
0234             .getIcon("ontology-subclass"));
0235     addTreeNodeSelectionListener(subClassAction);
0236     subClass = new JButton(subClassAction);
0237     subClass.setToolTipText("Add New Sub Class");
0238     subClass.setEnabled(false);
0239 
0240     instanceAction = new InstanceAction("", MainFrame
0241             .getIcon("ontology-instance"));
0242     addTreeNodeSelectionListener(instanceAction);
0243     instance = new JButton(instanceAction);
0244     instance.setToolTipText("Add New Instance");
0245     instance.setEnabled(false);
0246 
0247     annotationPropertyAction = new AnnotationPropertyAction("", MainFrame
0248             .getIcon("ontology-annotation-property"));
0249     annotationProperty = new JButton(annotationPropertyAction);
0250     annotationProperty.setToolTipText("Add New Annotation Property");
0251     annotationProperty.setEnabled(false);
0252 
0253     datatypePropertyAction = new DatatypePropertyAction("", MainFrame
0254             .getIcon("ontology-datatype-property"));
0255     addTreeNodeSelectionListener(datatypePropertyAction);
0256     datatypeProperty = new JButton(datatypePropertyAction);
0257     datatypeProperty.setToolTipText("Add New Datatype Property");
0258     datatypeProperty.setEnabled(false);
0259 
0260     objectPropertyAction = new ObjectPropertyAction("", MainFrame
0261             .getIcon("ontology-object-property"));
0262     addTreeNodeSelectionListener(objectPropertyAction);
0263     objectProperty = new JButton(objectPropertyAction);
0264     objectProperty.setToolTipText("Add New Object Property");
0265     objectProperty.setEnabled(false);
0266 
0267     symmetricPropertyAction = new SymmetricPropertyAction("", MainFrame
0268             .getIcon("ontology-symmetric-property"));
0269     addTreeNodeSelectionListener(symmetricPropertyAction);
0270     symmetricProperty = new JButton(symmetricPropertyAction);
0271     symmetricProperty.setToolTipText("Add New Symmetric Property");
0272     symmetricProperty.setEnabled(false);
0273 
0274     transitivePropertyAction = new TransitivePropertyAction("", MainFrame
0275             .getIcon("ontology-transitive-property"));
0276     addTreeNodeSelectionListener(transitivePropertyAction);
0277     transitiveProperty = new JButton(transitivePropertyAction);
0278     transitiveProperty.setToolTipText("Add New Transitive Property");
0279     transitiveProperty.setEnabled(false);
0280 
0281     deleteOntoResourceAction = new DeleteOntologyResourceAction("", MainFrame
0282             .getIcon("ontology-delete"));
0283     restrictionAction = new RestrictionAction("", MainFrame
0284             .getIcon("ontology-restriction"));
0285 
0286     addTreeNodeSelectionListener(deleteOntoResourceAction);
0287     delete = new JButton(deleteOntoResourceAction);
0288     delete.setToolTipText("Delete the selected nodes");
0289     delete.setEnabled(false);
0290 
0291     restriction = new JButton(restrictionAction);
0292     restriction.setToolTipText("Add New Restriction");
0293     restriction.setEnabled(false);
0294     
0295     toolBar.setFloatable(false);
0296     toolBar.add(topClass);
0297     toolBar.add(subClass);
0298     toolBar.add(restriction);
0299     toolBar.add(instance);
0300     toolBar.add(annotationProperty);
0301     toolBar.add(datatypeProperty);
0302     toolBar.add(objectProperty);
0303     toolBar.add(symmetricProperty);
0304     toolBar.add(transitiveProperty);
0305     toolBar.add(delete);
0306     toolBar.add(search);
0307     toolBar.add(refreshOntologyBtn);
0308     this.add(toolBar, BorderLayout.NORTH);
0309   }
0310 
0311   private void updateSelection(JTree treeToUse, Component componentToUpdate) {
0312     int[] selectedRows = treeToUse.getSelectionRows();
0313     if(selectedRows != null && selectedRows.length > 0) {
0314       selectedNodes.clear();
0315       for(int i = 0; i < selectedRows.length; i++) {
0316         DefaultMutableTreeNode node1 = (DefaultMutableTreeNode)treeToUse
0317                 .getPathForRow(selectedRows[i]).getLastPathComponent();
0318         selectedNodes.add(node1);
0319       }
0320       if(treeToUse == tree) {
0321         detailsTableModel
0322                 .setItem(((OResourceNode)((DefaultMutableTreeNode)selectedNodes
0323                         .get(0)).getUserObject()).getResource());
0324       }
0325       else {
0326         propertyDetailsTableModel
0327                 .setItem(((OResourceNode)((DefaultMutableTreeNode)selectedNodes
0328                         .get(0)).getUserObject()).getResource());
0329 
0330       }
0331       enableDisableToolBarComponents();
0332       fireTreeNodeSelectionChanged(selectedNodes);
0333       if(treeToUse == tree)
0334         propertyTree.clearSelection();
0335       else tree.clearSelection();
0336     }
0337     mainSplit.setRightComponent(componentToUpdate);
0338     mainSplit.updateUI();
0339   }
0340 
0341   /**
0342    * Initializes various listeners
0343    */
0344   protected void initListeners() {
0345     tree.getSelectionModel().addTreeSelectionListener(
0346             new TreeSelectionListener() {
0347               public void valueChanged(TreeSelectionEvent e) {
0348                 updateSelection(tree, detailsTableScroller);
0349               }
0350             });
0351     propertyTree.getSelectionModel().addTreeSelectionListener(
0352             new TreeSelectionListener() {
0353               public void valueChanged(TreeSelectionEvent e) {
0354                 updateSelection(propertyTree, propertyDetailsTableScroller);
0355               }
0356             });
0357 
0358     mainSplit.addComponentListener(new ComponentListener() {
0359       public void componentHidden(ComponentEvent e) {
0360       }
0361 
0362       public void componentMoved(ComponentEvent e) {
0363       }
0364 
0365       public void componentResized(ComponentEvent e) {
0366         mainSplit.setDividerLocation(0.4);
0367       }
0368 
0369       public void componentShown(ComponentEvent e) {
0370       }
0371     });
0372 
0373     tree.addMouseListener(new MouseAdapter() {
0374       public void mouseClicked(MouseEvent me) {
0375         if(SwingUtilities.isRightMouseButton(me)) {
0376           if(selectedNodes == null || selectedNodes.size() != 1return;
0377           final JPopupMenu menu = new JPopupMenu();
0378           final JMenu addProperty = new JMenu("Properties");
0379           final OResource candidate = (OResource)((OResourceNode)((DefaultMutableTreeNode)selectedNodes
0380                   .get(0)).getUserObject()).getResource();
0381           menu.add(addProperty);
0382           final JMenuItem sameAs = new JMenuItem(candidate instanceof OClass
0383                   "Equivalent Class"
0384                   "Same As Instance");
0385           menu.add(sameAs);
0386           final JMenuItem subClass = new JMenuItem("Add SubClass", MainFrame
0387                   .getIcon("ontology-subclass"));
0388           final JMenuItem instance = new JMenuItem("Add Instance", MainFrame
0389                   .getIcon("ontology-instance"));
0390           final JMenuItem delete = new JMenuItem("Delete", MainFrame
0391                   .getIcon("delete"));
0392           if(candidate instanceof OClass) {
0393             menu.add(subClass);
0394             menu.add(instance);
0395 
0396             // invoke new sub class action
0397             subClass.addActionListener(new ActionListener() {
0398               public void actionPerformed(ActionEvent ae) {
0399                 subClassAction.actionPerformed(ae);
0400               }
0401             });
0402 
0403             // invoke new instance action
0404             instance.addActionListener(new ActionListener() {
0405               public void actionPerformed(ActionEvent ae) {
0406                 instanceAction.actionPerformed(ae);
0407               }
0408             });
0409 
0410             // invoke same as action
0411             sameAs.addActionListener(new ActionListener() {
0412               public void actionPerformed(ActionEvent ae) {
0413                 Set<OClass> oclasses = ontology.getOClasses(false);
0414                 ArrayList<OClass> classList = new ArrayList<OClass>();
0415                 Iterator<OClass> classIter = oclasses.iterator();
0416                 while(classIter.hasNext()) {
0417                   OClass aClass = classIter.next();
0418                   classList.add(aClass);
0419                 }
0420 
0421                 // the selected class shouldn't appear in the list
0422                 classList.remove(candidate);
0423                 ValuesSelectionAction vsa = new ValuesSelectionAction();
0424                 String[] classArray = new String[classList.size()];
0425                 for(int i = 0; i < classArray.length; i++) {
0426                   classArray[i= classList.get(i).getURI().toString();
0427                 }
0428                 vsa.showGUI(candidate.getName() " is equivalent to :",
0429                         classArray, new String[0], false, null);
0430                 String[] selectedValues = vsa.getSelectedValues();
0431                 for(int i = 0; i < selectedValues.length; i++) {
0432                   OClass byName = (OClass)ontology
0433                           .getOResourceFromMap(selectedValues[i]);
0434                   if(byName == nullcontinue;
0435                   ((OClass)candidate).setEquivalentClassAs(byName);
0436                 }
0437                 TreePath path = tree.getSelectionPath();
0438                 tree.setSelectionRow(0);
0439                 tree.setSelectionPath(path);
0440                 return;
0441               }
0442             });
0443           }
0444 
0445           // same as action for OInstance
0446           if(candidate instanceof OInstance) {
0447             sameAs.addActionListener(new ActionListener() {
0448               public void actionPerformed(ActionEvent ae) {
0449                 Set<OInstance> instances = ontology.getOInstances();
0450                 ArrayList<OInstance> instancesList = new ArrayList<OInstance>();
0451                 Iterator<OInstance> instancesIter = instances.iterator();
0452                 while(instancesIter.hasNext()) {
0453                   OInstance instance = instancesIter.next();
0454                   instancesList.add(instance);
0455                 }
0456                 instancesList.remove(candidate);
0457                 ValuesSelectionAction vsa = new ValuesSelectionAction();
0458                 String[] instancesArray = new String[instancesList.size()];
0459                 for(int i = 0; i < instancesArray.length; i++) {
0460                   instancesArray[i= instancesList.get(i).getURI().toString();
0461                 }
0462                 vsa.showGUI(candidate.getName() " is same As :",
0463                         instancesArray, new String[0], false, null);
0464                 String[] selectedValues = vsa.getSelectedValues();
0465                 for(int i = 0; i < selectedValues.length; i++) {
0466                   OInstance byName = (OInstance)ontology
0467                           .getOResourceFromMap(selectedValues[i]);
0468                   if(byName == nullcontinue;
0469                   ((OInstance)candidate).setSameInstanceAs(byName);
0470                 }
0471                 TreePath path = tree.getSelectionPath();
0472                 tree.setSelectionRow(0);
0473                 tree.setSelectionPath(path);
0474                 return;
0475               }
0476             });
0477           }
0478 
0479           // add the delete button here
0480           menu.add(delete);
0481           delete.addActionListener(new ActionListener() {
0482             public void actionPerformed(ActionEvent ae) {
0483               deleteOntoResourceAction.actionPerformed(ae);
0484             }
0485           });
0486 
0487           int propertyCounter = 0;
0488           JMenu whereToAdd = addProperty;
0489 
0490           // finally add properties
0491           Set<RDFProperty> props = ontology.getPropertyDefinitions();
0492           Iterator<RDFProperty> iter = props.iterator();
0493           while(iter.hasNext()) {
0494             final RDFProperty p = iter.next();
0495 
0496             if(propertyCounter > 10) {
0497               JMenu newMenu = new JMenu("More >");
0498               whereToAdd.add(newMenu);
0499               whereToAdd = newMenu;
0500               propertyCounter = 0;
0501               whereToAdd.setEnabled(false);
0502             }
0503 
0504             // if property is an annotation property
0505             if(instanceof AnnotationProperty) {
0506               JMenuItem item = new JMenuItem(new AnnotationPropertyValueAction(
0507                 p.getName(), candidate, (AnnotationPropertyp));
0508               whereToAdd.setEnabled(true);
0509               whereToAdd.add(item);
0510               propertyCounter++;
0511               continue;
0512             }
0513 
0514             // if it is a datatype property
0515             if(candidate instanceof OInstance
0516             && p instanceof DatatypeProperty
0517             && p.isValidDomain(candidate)) {
0518               JMenuItem item = new JMenuItem(new DatatypePropertyValueAction(
0519                 p.getName(), candidate, (DatatypePropertyp));
0520               whereToAdd.add(item);
0521               whereToAdd.setEnabled(true);
0522               propertyCounter++;
0523               continue;
0524             }
0525 
0526             // if it is an object property
0527             if(candidate instanceof OInstance
0528             && p instanceof ObjectProperty
0529             && p.isValidDomain(candidate)) {
0530               JMenuItem item = new JMenuItem(new ObjectPropertyValueAction(
0531                 p.getName(), candidate, (ObjectPropertyp, null));
0532               whereToAdd.add(item);
0533               whereToAdd.setEnabled(true);
0534               propertyCounter++;
0535               continue;
0536             }
0537 
0538           }
0539           menu.show(tree, me.getX(), me.getY());
0540           menu.setVisible(true);
0541         }
0542       }
0543     });
0544 
0545     propertyTree.addMouseListener(new MouseAdapter() {
0546       public void mouseClicked(MouseEvent me) {
0547         if(SwingUtilities.isRightMouseButton(me)) {
0548           if(selectedNodes == null || selectedNodes.size() != 1return;
0549           final JPopupMenu menu = new JPopupMenu();
0550           final OResource candidate = ((OResourceNode)((DefaultMutableTreeNode)selectedNodes
0551                   .get(0)).getUserObject()).getResource();
0552           final JMenuItem sameAs = new JMenuItem("Equivalent Property");
0553           final JMenuItem delete = new JMenuItem("Delete", MainFrame
0554                   .getIcon("delete"));
0555           final JCheckBoxMenuItem functional = new JCheckBoxMenuItem(
0556                   "Functional");
0557           final JCheckBoxMenuItem inverseFunctional = new JCheckBoxMenuItem(
0558                   "InverseFunctional");
0559           menu.add(sameAs);
0560           if(candidate instanceof AnnotationProperty) {
0561             return;
0562           }
0563           final Set<RDFProperty> props = new HashSet<RDFProperty>();
0564           if(candidate instanceof ObjectProperty) {
0565             props.addAll(ontology.getObjectProperties());
0566             functional.setSelected(((ObjectProperty)candidate).isFunctional());
0567             inverseFunctional.setSelected(((ObjectProperty)candidate)
0568                     .isInverseFunctional());
0569             functional.addActionListener(new ActionListener() {
0570               public void actionPerformed(ActionEvent ae) {
0571                 ((ObjectProperty)candidate).setFunctional(functional
0572                         .isSelected());
0573               }
0574             });
0575             inverseFunctional.addActionListener(new ActionListener() {
0576               public void actionPerformed(ActionEvent ae) {
0577                 ((ObjectProperty)candidate)
0578                         .setInverseFunctional(inverseFunctional.isSelected());
0579               }
0580             });
0581             menu.add(functional);
0582             menu.add(inverseFunctional);
0583           }
0584           else if(candidate instanceof DatatypeProperty) {
0585             props.addAll(ontology.getDatatypeProperties());
0586           }
0587           else {
0588             props.addAll(ontology.getRDFProperties());
0589           }
0590           sameAs.addActionListener(new ActionListener() {
0591             public void actionPerformed(ActionEvent ae) {
0592               props.remove(candidate);
0593               Iterator<RDFProperty> iter = props.iterator();
0594               ValuesSelectionAction vsa = new ValuesSelectionAction();
0595               String[] propArray = new String[props.size()];
0596               for(int i = 0; i < propArray.length; i++) {
0597                 propArray[i= iter.next().getURI().toString();
0598               }
0599               vsa.showGUI(candidate.getName() " is equivalent to :",
0600                       propArray, new String[0], false, null);
0601               String[] selectedValues = vsa.getSelectedValues();
0602               for(int i = 0; i < selectedValues.length; i++) {
0603                 RDFProperty byName = (RDFProperty)ontology
0604                         .getOResourceFromMap(selectedValues[i]);
0605                 if(byName == nullcontinue;
0606                 ((RDFProperty)candidate).setEquivalentPropertyAs(byName);
0607               }
0608               TreePath path = propertyTree.getSelectionPath();
0609               propertyTree.setSelectionRow(0);
0610               propertyTree.setSelectionPath(path);
0611               return;
0612             }
0613           });
0614 
0615           menu.add(delete);
0616           delete.addActionListener(new ActionListener() {
0617             public void actionPerformed(ActionEvent ae) {
0618               deleteOntoResourceAction.actionPerformed(ae);
0619             }
0620           });
0621 
0622           JMenu addProperty = new JMenu("Properties");
0623           Set<RDFProperty> rdfprops = ontology.getPropertyDefinitions();
0624           Iterator<RDFProperty> iter = rdfprops.iterator();
0625           menu.add(addProperty);
0626           
0627           JMenu whereToAdd = addProperty;
0628           int propertyCounter = 0;
0629 
0630           while(iter.hasNext()) {
0631             final RDFProperty p = iter.next();
0632 
0633             if(propertyCounter > 10) {
0634               JMenu newMenu = new JMenu("More >");
0635               whereToAdd.add(newMenu);
0636               whereToAdd = newMenu;
0637               propertyCounter = 0;
0638               whereToAdd.setEnabled(false);
0639             }
0640 
0641             if(instanceof AnnotationProperty) {
0642               JMenuItem item = new JMenuItem(p.getName(), MainFrame
0643                       .getIcon("ontology-annotation-property"));
0644               whereToAdd.add(item);
0645               whereToAdd.setEnabled(true);
0646               propertyCounter++;
0647 
0648               item.addActionListener(new ActionListener() {
0649                 public void actionPerformed(ActionEvent ae) {
0650                   String value = JOptionPane.showInputDialog(
0651                     MainFrame.getInstance(),
0652                     "Enter Value for property :" + p.getName());
0653                   if(value != null) {
0654                     candidate.addAnnotationPropertyValue((AnnotationProperty)p,
0655                             new Literal(value));
0656                   }
0657                   TreePath path = propertyTree.getSelectionPath();
0658                   propertyTree.setSelectionRow(0);
0659                   propertyTree.setSelectionPath(path);
0660                   return;
0661                 }
0662               });
0663             }
0664           }
0665           menu.show(propertyTree, me.getX(), me.getY());
0666           menu.setVisible(true);
0667         }
0668       }
0669     });
0670 
0671     detailsTable.addMouseListener(new MouseAdapter() {
0672       public void mouseClicked(MouseEvent me) {
0673         if(SwingUtilities.isLeftMouseButton(me)) {
0674           int row = detailsTable.getSelectedRow();
0675           int column = detailsTable.getSelectedColumn();
0676           if(row == -|| column == -1) { return}
0677           Object value = detailsTableModel.getValueAt(
0678             row, DetailsTableModel.LABEL_COLUMN);
0679           OResource resource = detailsTableModel.getItem();
0680 
0681           if(value instanceof DetailsGroup) {
0682             if(column == DetailsTableModel.EXPANDED_COLUMN) {
0683               boolean expanded = ((DetailsGroup)value).isExpanded();
0684               ((DetailsGroup)value).setExpanded(!expanded);
0685               detailsTable.updateUI();
0686             }
0687           }
0688 
0689           else if(column == DetailsTableModel.LABEL_COLUMN
0690             && me.getClickCount() == 2) {
0691 
0692             OResource toSelect = null;
0693             JTree treeToSelectIn = null;
0694 
0695             if(value instanceof OClass) {
0696               toSelect = (OResourcevalue;
0697               treeToSelectIn = tree;
0698             }
0699             else if(value instanceof RDFProperty) {
0700               toSelect = (RDFPropertyvalue;
0701               treeToSelectIn = propertyTree;
0702             }
0703             else if(value instanceof PropertyValue) {
0704               toSelect = ((PropertyValuevalue).getProperty();
0705               treeToSelectIn = propertyTree;
0706             }
0707 
0708             if(toSelect != null) {
0709 
0710               treeToSelectIn.setSelectionPath(new TreePath(uri2TreeNodesListMap
0711                       .get(toSelect.getURI().toString()).get(0).getPath()));
0712               treeToSelectIn.scrollPathToVisible(treeToSelectIn
0713                       .getSelectionPath());
0714 
0715               if(treeToSelectIn == tree) {
0716                 tabbedPane.setSelectedComponent(scroller);
0717               }
0718               else {
0719                 tabbedPane.setSelectedComponent(propertyScroller);
0720               }
0721             }
0722           }
0723 
0724           else if(value instanceof PropertyValue
0725             && column == DetailsTableModel.VALUE_COLUMN
0726             && me.getClickCount() == 2) {
0727 
0728             PropertyValue pv = (PropertyValuevalue;
0729             RDFProperty p = pv.getProperty();
0730 
0731             // if it is an object property
0732             if(instanceof ObjectProperty) {
0733               new ObjectPropertyValueAction("", resource,
0734                 (ObjectPropertyp, (OInstance)pv.getValue())
0735                 .actionPerformed(null);
0736             }
0737             // for the other types of data edit directly in cell
0738           }
0739 
0740           else if(value instanceof RDFProperty
0741             && column == DetailsTableModel.VALUE_COLUMN
0742             && me.getClickCount() == 2) {
0743 
0744             final RDFProperty property = (RDFPropertyvalue;
0745             if (property instanceof AnnotationProperty) {
0746               resource.addAnnotationPropertyValue(
0747                 (AnnotationPropertyproperty, new Literal(""));
0748               detailsTableModel.setItem(resource);
0749               SwingUtilities.invokeLater(new Runnable() { public void run() {
0750               for (int rowI = detailsTable.getRowCount()-1; rowI >= 0; rowI--) {
0751                 if (detailsTable.getValueAt(rowI,
0752                     DetailsTableModel.VALUE_COLUMN).equals("")
0753                  && detailsTable.getValueAt(rowI,
0754                     DetailsTableModel.LABEL_COLUMNinstanceof PropertyValue
0755                  && ((PropertyValue)detailsTable.getValueAt(rowI,
0756                   DetailsTableModel.LABEL_COLUMN)).getProperty()
0757                   .equals(property)) {
0758                   detailsTable.editCellAt(rowI, DetailsTableModel.VALUE_COLUMN);
0759                   detailsTable.getEditorComponent().requestFocusInWindow();
0760                   break;
0761                 }
0762               }
0763               }});
0764             }
0765             else if (property instanceof DatatypeProperty
0766                   && resource instanceof OInstance
0767             ) {
0768               String type = ((DatatypeProperty)property)
0769                 .getDataType().getXmlSchemaURIString();
0770               final String literalValue;
0771               if (type.endsWith("boolean")) {
0772                 literalValue = "true";
0773               else if (type.endsWith("date")) {
0774                 literalValue = "01/01/2000";
0775               else if (type.endsWith("time")) {
0776                 literalValue = "12:00";
0777               else if (type.endsWith("decimal")
0778                       || type.endsWith("double")
0779                       || type.endsWith("float")) {
0780                 literalValue = "1.0";
0781               else if (type.endsWith("byte")
0782                       || type.endsWith("unsignedByte")) {
0783                 literalValue = "F";
0784               else if (type.endsWith("int")
0785                       || type.endsWith("integer")
0786                       || type.endsWith("long")
0787                       || type.endsWith("unsignedInt")
0788                       || type.endsWith("unsignedShort")
0789                       || type.endsWith("unsignedLong")
0790                       || type.endsWith("nonNegativeInteger")
0791                       || type.endsWith("positiveInteger")
0792                       || type.endsWith("short")
0793                       || type.endsWith("duration")) {
0794                 literalValue = "1";
0795               else if (type.endsWith("negativeInteger")
0796                       || type.endsWith("nonPositiveInteger")) {
0797                 literalValue = "-1";
0798               else {
0799                 literalValue = "";
0800               }
0801               try {
0802               ((OInstance)resource).addDatatypePropertyValue(
0803                 (DatatypePropertyproperty, new Literal(literalValue,
0804                   ((DatatypeProperty)property).getDataType()));
0805               catch(InvalidValueException e) {
0806                 JOptionPane.showMessageDialog(MainFrame.getInstance(),
0807                         "Incompatible value");
0808                 e.printStackTrace();
0809                 return;
0810               }
0811               detailsTableModel.setItem(resource);
0812               SwingUtilities.invokeLater(new Runnable() { public void run() {
0813               for (int rowI = detailsTable.getRowCount()-1; rowI >= 0; rowI--) {
0814                 if (detailsTable.getValueAt(rowI,
0815                     DetailsTableModel.VALUE_COLUMN).equals(literalValue)
0816                   && detailsTable.getValueAt(rowI,
0817                      DetailsTableModel.LABEL_COLUMNinstanceof PropertyValue
0818                   && ((PropertyValue)detailsTable.getValueAt(rowI,
0819                    DetailsTableModel.LABEL_COLUMN)).getProperty()
0820                    .equals(property)) {
0821                   detailsTable.editCellAt(rowI, DetailsTableModel.VALUE_COLUMN);
0822                   detailsTable.getEditorComponent().requestFocusInWindow();
0823                   break;
0824                 }
0825               }
0826               }});
0827             }
0828             else if (property instanceof ObjectProperty
0829                  && resource instanceof OInstance) {
0830               new ObjectPropertyValueAction("", resource,
0831                 (ObjectPropertyproperty, null).actionPerformed(null);
0832             }
0833           }
0834 
0835           else if(value instanceof PropertyValue
0836             && column == DetailsTableModel.DELETE_COLUMN
0837             && me.getClickCount() == 1) {
0838 
0839             PropertyValue pv = (PropertyValuevalue;
0840 
0841             try {
0842               if(resource instanceof OClass) {
0843                 if(pv.getProperty() instanceof AnnotationProperty) {
0844                   resource.removeAnnotationPropertyValue(
0845                           (AnnotationProperty)pv.getProperty()(Literal)pv
0846                                   .getValue());
0847                 }
0848               }
0849               else {
0850                 OInstance instance = (OInstance)resource;
0851                 if(pv.getProperty() instanceof AnnotationProperty) {
0852                   instance.removeAnnotationPropertyValue((AnnotationProperty)pv
0853                           .getProperty()(Literal)pv.getValue());
0854                 }
0855                 else if(pv.getProperty() instanceof DatatypeProperty) {
0856                   instance.removeDatatypePropertyValue((DatatypeProperty)pv
0857                           .getProperty()(Literal)pv.getValue());
0858                 }
0859                 else if(pv.getProperty() instanceof ObjectProperty) {
0860                   instance.removeObjectPropertyValue((ObjectProperty)pv
0861                           .getProperty()(OInstance)pv.getValue());
0862                 }
0863               }
0864 
0865               SwingUtilities.invokeLater(new Runnable() {
0866                 public void run() {
0867                   TreePath path = tree.getSelectionPath();
0868                   tree.setSelectionRow(0);
0869                   tree.setSelectionPath(path);
0870                 }
0871               });
0872             }
0873             catch(Exception e) {
0874               JOptionPane.showMessageDialog(MainFrame.getInstance(),
0875                       "Cannot delete the property value because \n"
0876                               + e.getMessage());
0877               e.printStackTrace();
0878             }
0879           }
0880         }
0881       }
0882     });
0883 
0884     propertyDetailsTable.addMouseListener(new MouseAdapter() {
0885       public void mouseClicked(MouseEvent me) {
0886         if(SwingUtilities.isLeftMouseButton(me)) {
0887           int[] rows = propertyDetailsTable.getSelectedRows();
0888           int column = propertyDetailsTable.getSelectedColumn();
0889           if(rows == null || rows.length == 0return;
0890 
0891           Object value = propertyDetailsTable.getModel().getValueAt(rows[0]1);
0892           if(value instanceof DetailsGroup) {
0893             if(column == 0) {
0894               boolean expanded = ((DetailsGroup)value).isExpanded();
0895               ((DetailsGroup)value).setExpanded(!expanded);
0896               propertyDetailsTable.updateUI();
0897             }
0898             else {
0899               return;
0900             }
0901           }
0902 
0903           if(value instanceof DetailsGroupreturn;
0904           final Object finalObj = value;
0905 
0906           // find out the selected component in the tree
0907           Object sc = propertyTree.getSelectionPath().getLastPathComponent();
0908           if(sc == null) {
0909             JOptionPane.showMessageDialog(MainFrame.getInstance(),
0910                     "No resource selected in the main ontology tree");
0911             return;
0912           }
0913 
0914           // find out the treenode for the current selection
0915           final DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode)sc;
0916           final OResource resource = ((OResourceNode)dmtn.getUserObject())
0917                   .getResource();
0918 
0919           if((!(finalObj instanceof PropertyValue|| column == 1)
0920                   && me.getClickCount() == 2) {
0921 
0922             OResource toSelect = null;
0923             JTree treeToSelectIn = null;
0924 
0925             if(finalObj instanceof OClass) {
0926               toSelect = (OResource)finalObj;
0927               treeToSelectIn = tree;
0928             }
0929             else if(finalObj instanceof RDFProperty) {
0930               toSelect = (RDFProperty)finalObj;
0931               treeToSelectIn = propertyTree;
0932             }
0933             else if(finalObj instanceof PropertyValue) {
0934               toSelect = ((PropertyValue)finalObj).getProperty();
0935               treeToSelectIn = propertyTree;
0936             }
0937 
0938             if(toSelect != null) {
0939 
0940               treeToSelectIn.setSelectionPath(new TreePath(uri2TreeNodesListMap
0941                       .get(toSelect.getURI().toString()).get(0).getPath()));
0942               treeToSelectIn.scrollPathToVisible(treeToSelectIn
0943                       .getSelectionPath());
0944 
0945               if(treeToSelectIn == tree) {
0946                 tabbedPane.setSelectedComponent(scroller);
0947               }
0948               else {
0949                 tabbedPane.setSelectedComponent(propertyScroller);
0950               }
0951               return;
0952             }
0953           }
0954 
0955           if(finalObj instanceof PropertyValue && column == 2
0956                   && me.getClickCount() == 2) {
0957             PropertyValue pv = (PropertyValue)finalObj;
0958             RDFProperty p = pv.getProperty();
0959             // if property is an annotation property
0960             if(instanceof AnnotationProperty) {
0961               String reply = JOptionPane.showInputDialog(MainFrame
0962                       .getInstance()((Literal)pv.getValue()).getValue(),
0963                       "Value for " + p.getName() " property",
0964                       JOptionPane.QUESTION_MESSAGE);
0965               if(reply != null) {
0966                 resource.removeAnnotationPropertyValue((AnnotationProperty)p,
0967                         (Literal)pv.getValue());
0968                 resource.addAnnotationPropertyValue((AnnotationProperty)p,
0969                         new Literal(reply));
0970               }
0971               TreePath path = propertyTree.getSelectionPath();
0972               propertyTree.setSelectionRow(0);
0973               propertyTree.setSelectionPath(path);
0974               return;
0975             }
0976           }
0977 
0978           if(finalObj instanceof PropertyValue && column == 3
0979                   && me.getClickCount() == 1) {
0980 
0981             PropertyValue pv = (PropertyValue)finalObj;
0982             try {
0983               if(resource instanceof RDFProperty) {
0984                 if(pv.getProperty() instanceof AnnotationProperty) {
0985                   ((RDFProperty)resource).removeAnnotationPropertyValue(
0986                           (AnnotationProperty)pv.getProperty()(Literal)pv
0987                                   .getValue());
0988                 }
0989               }
0990 
0991               SwingUtilities.invokeLater(new Runnable() {
0992                 public void run() {
0993                   TreePath path = propertyTree.getSelectionPath();
0994                   propertyTree.setSelectionRow(0);
0995                   propertyTree.setSelectionPath(path);
0996                 }
0997               });
0998             }
0999             catch(Exception e) {
1000               JOptionPane.showMessageDialog(MainFrame.getInstance(),
1001                       "Cannot delete the property value because \n"
1002                               + e.getMessage());
1003               e.printStackTrace();
1004             }
1005           }
1006         }
1007       }
1008     });
1009   }
1010 
1011   protected class AnnotationPropertyValueAction extends AbstractAction {
1012     public AnnotationPropertyValueAction(String name, OResource oResource,
1013                                          AnnotationProperty property) {
1014       super(name, MainFrame.getIcon("ontology-annotation-property"));
1015       this.oResource = oResource;
1016       this.property = property;
1017     }
1018     public void actionPerformed(ActionEvent e) {
1019       Object inputValue = JOptionPane.showInputDialog(MainFrame.getInstance(),
1020         "<html>Enter a value for the property <b>" +
1021         property.getName() "</b>",
1022         "New property value", JOptionPane.QUESTION_MESSAGE,
1023         MainFrame.getIcon("ontology-annotation-property"), null, null);
1024       if(inputValue != null) {
1025         // add a new property value
1026         oResource.addAnnotationPropertyValue(
1027           property, new Literal((StringinputValue));
1028       }
1029       // reselect instance in the tree to update the table
1030       TreePath path = tree.getSelectionPath();
1031       tree.setSelectionRow(0);
1032       tree.setSelectionPath(path);
1033     }
1034     private OResource oResource;
1035     private AnnotationProperty property;
1036   }
1037 
1038   protected class DatatypePropertyValueAction extends AbstractAction {
1039     public DatatypePropertyValueAction(String name, OResource oResource,
1040                                        DatatypeProperty property) {
1041       super(name, MainFrame.getIcon("ontology-datatype-property"));
1042       this.oResource = oResource;
1043       this.property = property;
1044     }
1045     public void actionPerformed(ActionEvent ae) {
1046       Object inputValue = JOptionPane.showInputDialog(MainFrame.getInstance(),
1047         "<html>Enter a value for the property <b>" +
1048         property.getName() "</b>\n" +
1049         "of type " + property.getDataType().getXmlSchemaURIString()
1050           .replaceFirst("http://www.w3.org/2001/XMLSchema#"""),
1051         "New property value", JOptionPane.QUESTION_MESSAGE,
1052         MainFrame.getIcon("ontology-datatype-property"), null, null);
1053       if(inputValue != null) {
1054         boolean validValue = property.getDataType()
1055           .isValidValue((StringinputValue);
1056         if(!validValue) {
1057           JOptionPane.showMessageDialog(MainFrame.getInstance(),
1058             "Incompatible value: " + inputValue);
1059           return;
1060         }
1061         try {
1062           ((OInstance)oResource).addDatatypePropertyValue(property,
1063             new Literal((StringinputValue, property.getDataType()));
1064         }
1065         catch(InvalidValueException e) {
1066           JOptionPane.showMessageDialog(MainFrame.getInstance(),
1067             "Incompatible value.\n" + e.getMessage());
1068           return;
1069         }
1070       }
1071       TreePath path = tree.getSelectionPath();
1072       tree.setSelectionRow(0);
1073       tree.setSelectionPath(path);
1074     }
1075     private OResource oResource;
1076     private DatatypeProperty property;
1077   }
1078 
1079   protected class ObjectPropertyValueAction extends AbstractAction {
1080     public ObjectPropertyValueAction(String name, OResource oResource,
1081                                      ObjectProperty property,
1082                                      OInstance oldValue) {
1083       super(name, MainFrame.getIcon("ontology-object-property"));
1084       this.oResource = oResource;
1085       this.property = property;
1086       this.oldValue = oldValue;
1087     }
1088     public void actionPerformed(ActionEvent ae) {
1089       Set<OInstance> instances = ontology.getOInstances();
1090       ArrayList<String> validInstances = new ArrayList<String>();
1091       for (OInstance instance : instances) {
1092         if (property.isValidRange(instance)) {
1093           validInstances.add(instance.getURI().toString());
1094         }
1095       }
1096       ValuesSelectionAction vsa = new ValuesSelectionAction();
1097       int choice = vsa.showGUI("New property value",
1098         validInstances.toArray(new String[validInstances.size()]),
1099         oldValue != null ?
1100           new String[]{oldValue.getONodeID().toString()} new String[]{},
1101         false, MainFrame.getIcon("ontology-object-property"));
1102       if (choice != JOptionPane.OK_OPTION) { return}
1103       if (oldValue != null) {
1104         ((OInstance)oResource).removeObjectPropertyValue(property, oldValue);
1105       }
1106       String[] selectedValues = vsa.getSelectedValues();
1107       for(int i = 0; i < selectedValues.length; i++) {
1108         OInstance byName = (OInstance)
1109           ontology.getOResourceFromMap(selectedValues[i]);
1110         if(byName == null) { continue}
1111         try {
1112           ((OInstance)oResource).addObjectPropertyValue(property, byName);
1113         }
1114         catch(InvalidValueException e) {
1115           JOptionPane.showMessageDialog(MainFrame.getInstance(),
1116             "Incompatible value.\n" + e.getMessage());
1117           return;
1118         }
1119       }
1120       TreePath path = tree.getSelectionPath();
1121       tree.setSelectionRow(0);
1122       tree.setSelectionPath(path);
1123     }
1124     private OResource oResource;
1125     private ObjectProperty property;
1126     private OInstance oldValue;
1127   }
1128 
1129   protected void expandNode(JTree tree) {
1130     for(int i = 0; i < tree.getRowCount(); i++) {
1131       tree.expandRow(i);
1132     }
1133   }
1134 
1135   /**
1136    * Enable-disable toolBar components
1137    */
1138   private void enableDisableToolBarComponents() {
1139     boolean allClasses = true;
1140     boolean allProperties = true;
1141     boolean allInstances = true;
1142     for (DefaultMutableTreeNode node : selectedNodes) {
1143       OResource res = ((OResourceNodenode.getUserObject()).getResource();
1144       if (res instanceof OClass) {
1145         allProperties = false;
1146         allInstances = false;
1147       else if (res instanceof OInstance) {
1148         allClasses = false;
1149         allProperties = false;
1150       else {
1151         allInstances = false;
1152         allClasses = false;
1153       }
1154     }
1155     if (selectedNodes.isEmpty()) {
1156       topClass.setEnabled(false);
1157       subClass.setEnabled(false);
1158       instance.setEnabled(false);
1159       annotationProperty.setEnabled(false);
1160       datatypeProperty.setEnabled(false);
1161       objectProperty.setEnabled(false);
1162       symmetricProperty.setEnabled(false);
1163       transitiveProperty.setEnabled(false);
1164       delete.setEnabled(false);
1165       restriction.setEnabled(false);
1166     }
1167     else if(allClasses) {
1168       topClass.setEnabled(true);
1169       subClass.setEnabled(true);
1170       instance.setEnabled(true);
1171       annotationProperty.setEnabled(true);
1172       datatypeProperty.setEnabled(true);
1173       objectProperty.setEnabled(true);
1174       symmetricProperty.setEnabled(true);
1175       transitiveProperty.setEnabled(true);
1176       delete.setEnabled(true);
1177       restriction.setEnabled(true);
1178     }
1179     else if(allInstances) {
1180       topClass.setEnabled(true);
1181       subClass.setEnabled(false);
1182       instance.setEnabled(false);
1183       annotationProperty.setEnabled(true);
1184       datatypeProperty.setEnabled(false);
1185       objectProperty.setEnabled(false);
1186       symmetricProperty.setEnabled(false);
1187       transitiveProperty.setEnabled(false);
1188       delete.setEnabled(true);
1189       restriction.setEnabled(false);
1190     }
1191     else if(allProperties) {
1192       topClass.setEnabled(false);
1193       subClass.setEnabled(false);
1194       instance.setEnabled(false);
1195       annotationProperty.setEnabled(true);
1196       datatypeProperty.setEnabled(true);
1197       objectProperty.setEnabled(true);
1198       symmetricProperty.setEnabled(true);
1199       transitiveProperty.setEnabled(true);
1200       delete.setEnabled(true);
1201       restriction.setEnabled(true);
1202     }
1203     else {
1204       topClass.setEnabled(false);
1205       subClass.setEnabled(false);
1206       instance.setEnabled(false);
1207       annotationProperty.setEnabled(true);
1208       datatypeProperty.setEnabled(false);
1209       objectProperty.setEnabled(false);
1210       symmetricProperty.setEnabled(false);
1211       transitiveProperty.setEnabled(false);
1212       delete.setEnabled(true);
1213       restriction.setEnabled(false);
1214     }
1215   }
1216 
1217   /**
1218    * Called when the target of this editor has changed
1219    */
1220   protected void rebuildModel() {
1221     rootNode.removeAllChildren();
1222     propertyRootNode.removeAllChildren();
1223     if(ontologyClassesURIs == null)
1224       ontologyClassesURIs = new ArrayList<String>();
1225     else ontologyClassesURIs.clear();
1226     uri2TreeNodesListMap = new HashMap<String, ArrayList<DefaultMutableTreeNode>>();
1227     reverseMap = new HashMap<DefaultMutableTreeNode, URI>();
1228     List<OResource> rootClasses = new ArrayList<OResource>(ontology
1229             .getOClasses(true));
1230     Collections.sort(rootClasses, itemComparator);
1231     addChidrenRec(rootNode, rootClasses, itemComparator);
1232     List<RDFProperty> props = new ArrayList<RDFProperty>(ontology
1233             .getPropertyDefinitions());
1234     List<RDFProperty> subList = new ArrayList<RDFProperty>();
1235     for(int i = 0; i < props.size(); i++) {
1236       RDFProperty prop = props.get(i);
1237       if(prop instanceof AnnotationProperty) {
1238         subList.add(prop);
1239         continue;
1240       }
1241       Set<RDFProperty> set = prop.getSuperProperties(OConstants.Closure.DIRECT_CLOSURE);
1242       if(set != null && !set.isEmpty()) {
1243         continue;
1244       }
1245       else {
1246         subList.add(prop);
1247       }
1248     }
1249     Collections.sort(subList, itemComparator);
1250     addPropertyChidrenRec(propertyRootNode, subList, itemComparator);
1251     datatypePropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
1252     objectPropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
1253     symmetricPropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
1254     transitivePropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
1255     SwingUtilities.invokeLater(new Runnable() {
1256       public void run() {
1257         treeModel.nodeStructureChanged(rootNode);
1258         tree.setSelectionInterval(00);
1259         // expand the root
1260         tree.expandPath(new TreePath(rootNode));
1261         // expand the entire tree
1262         for(int i = 0; i < tree.getRowCount(); i++)
1263           tree.expandRow(i);
1264         propertyTreeModel.nodeStructureChanged(propertyRootNode);
1265         // expand the root
1266         propertyTree.expandPath(new TreePath(propertyRootNode));
1267         // expand the entire tree
1268         for(int i = 0; i < propertyTree.getRowCount(); i++)
1269           propertyTree.expandRow(i);
1270         // detailsTableModel.fireTableDataChanged();
1271         // propertyDetailsTableModel.fireTableDataChanged();
1272       }
1273     });
1274   }
1275 
1276   /**
1277    * Adds the children nodes to a node using values from a list of
1278    * classes and instances.
1279    
1280    @param parent the parent node.
1281    @param children the List<OResource> of children objects.
1282    @param comparator the Comparator used to sort the children.
1283    */
1284   protected void addChidrenRec(DefaultMutableTreeNode parent,
1285           List<OResource> children, Comparator comparator) {
1286     for(OResource aChild : children) {
1287       DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(
1288               new OResourceNode(aChild));
1289       parent.add(childNode);
1290       
1291       // we maintain a map of ontology resources and their representing
1292       // tree
1293       // nodes
1294       ArrayList<DefaultMutableTreeNode> list = uri2TreeNodesListMap.get(aChild
1295               .getURI().toString());
1296       if(list == null) {
1297         list = new ArrayList<DefaultMutableTreeNode>();
1298         uri2TreeNodesListMap.put(aChild.getURI().toString(), list);
1299       }
1300       list.add(childNode);
1301       reverseMap.put(childNode, aChild.getURI());
1302       if(aChild instanceof OClass) {
1303         if(!ontologyClassesURIs.contains(aChild.getURI().toString()))
1304           ontologyClassesURIs.add(aChild.getURI().toString());
1305         childNode.setAllowsChildren(true);
1306         // add all the subclasses
1307         OClass aClass = (OClass)aChild;
1308         List<OResource> childList = new ArrayList<OResource>(aClass
1309                 .getSubClasses(OConstants.Closure.DIRECT_CLOSURE));
1310         Collections.sort(childList, comparator);
1311         addChidrenRec(childNode, childList, comparator);
1312         childList = new ArrayList<OResource>(ontology.getOInstances(aClass,
1313                 OConstants.Closure.DIRECT_CLOSURE));
1314         Collections.sort(childList, comparator);
1315         addChidrenRec(childNode, childList, comparator);
1316       }
1317       else if(aChild instanceof OInstance) {
1318         childNode.setAllowsChildren(false);
1319       }
1320       tree.expandPath(new TreePath(childNode.getPath()));
1321     }
1322     
1323   }
1324 
1325   /**
1326    * Adds the children nodes to a node using values from a list of
1327    * classes and instances.
1328    
1329    @param parent the parent node.
1330    @param children the lsit of children objects.
1331    @param comparator the Comparator used to sort the children.
1332    */
1333   protected void addPropertyChidrenRec(DefaultMutableTreeNode parent,
1334           List<RDFProperty> children, Comparator comparator) {
1335     for(RDFProperty aChild : children) {
1336       DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(
1337               new OResourceNode(aChild));
1338       parent.add(childNode);
1339       // we maintain a map of ontology resources and their representing
1340       // tree
1341       // nodes
1342       ArrayList<DefaultMutableTreeNode> list = uri2TreeNodesListMap.get(aChild
1343               .getURI().toString());
1344       if(list == null) {
1345         list = new ArrayList<DefaultMutableTreeNode>();
1346         uri2TreeNodesListMap.put(aChild.getURI().toString(), list);
1347       }
1348       list.add(childNode);
1349       reverseMap.put(childNode, aChild.getURI());
1350       if(aChild instanceof AnnotationProperty) {
1351         childNode.setAllowsChildren(false);
1352       }
1353       else {
1354         childNode.setAllowsChildren(true);
1355         // add all the sub properties
1356         List<RDFProperty> childList = new ArrayList<RDFProperty>(aChild
1357                 .getSubProperties(OConstants.Closure.DIRECT_CLOSURE));
1358         Collections.sort(childList, comparator);
1359         addPropertyChidrenRec(childNode, childList, comparator);
1360       }
1361       propertyTree.expandPath(new TreePath(childNode.getPath()));
1362     }
1363   }
1364 
1365   public void processGateEvent(GateEvent e) {
1366     // ignore
1367   }
1368 
1369   /**
1370    * Update the class tree model. To call when a class is added.
1371    
1372    @param aClass class to add
1373    */
1374   protected void classIsAdded(OClass aClass) {
1375     // we first obtain its superClasses
1376     Set<OClass> superClasses = aClass.getSuperClasses(OConstants.Closure.DIRECT_CLOSURE);
1377     List<OResource> list = new ArrayList<OResource>();
1378     list.add(aClass);
1379     if(superClasses == null || superClasses.isEmpty()) {
1380       // this is a root node
1381       addChidrenRec(rootNode, list, itemComparator);
1382       treeModel.nodeStructureChanged(rootNode);
1383     }
1384     else {
1385       List<OClass> cs = new ArrayList<OClass>(superClasses);
1386       Collections.sort(cs, itemComparator);
1387       for(OClass c : cs) {
1388         ArrayList<DefaultMutableTreeNode> superNodeList = uri2TreeNodesListMap
1389                 .get(c.getURI().toString());
1390         if(superNodeList == null) {
1391           // this is a result of two classes being created as a result
1392           // of only one addition
1393           // e.g. create a cardinality restriction and it will create a
1394           // fictivenode as well
1395           // so lets first add it
1396           classIsAdded(c);
1397           // no need to go any further, as refreshing the super node
1398           // will automatically refresh the children nodes
1399           continue;
1400         }
1401 
1402         for(int i = 0; i < superNodeList.size(); i++) {
1403           DefaultMutableTreeNode node = superNodeList.get(i);
1404           addChidrenRec(node, list, itemComparator);
1405           treeModel.nodeStructureChanged(node);
1406         }
1407       }
1408     }
1409   }
1410 
1411   /**
1412    * Update the property tree model. To call when a property is added.
1413    *
1414    @param p property to add
1415    */
1416   protected void propertyIsAdded(RDFProperty p) {
1417     // we first obtain its superProperty
1418     if(instanceof AnnotationProperty) {
1419       List<RDFProperty> list = new ArrayList<RDFProperty>();
1420       list.add(p);
1421       addPropertyChidrenRec(propertyRootNode, list, itemComparator);
1422       propertyTreeModel.nodeStructureChanged(propertyRootNode);
1423       return;
1424     }
1425     Set<RDFProperty> superProperties = p
1426             .getSuperProperties(OConstants.Closure.DIRECT_CLOSURE);
1427     List<RDFProperty> list = new ArrayList<RDFProperty>();
1428     list.add(p);
1429     if(superProperties == null || superProperties.isEmpty()) {
1430       // this is a root node
1431       addPropertyChidrenRec(propertyRootNode, list, itemComparator);
1432       propertyTreeModel.nodeStructureChanged(propertyRootNode);
1433     }
1434     else {
1435       List<RDFProperty> sps = new ArrayList<RDFProperty>(superProperties);
1436       Collections.sort(sps, itemComparator);
1437       for(RDFProperty r : sps) {
1438         ArrayList<DefaultMutableTreeNode> superNodeList = uri2TreeNodesListMap
1439                 .get(r.getURI().toString());
1440         for(int i = 0; i < superNodeList.size(); i++) {
1441           DefaultMutableTreeNode node = superNodeList.get(i);
1442           addPropertyChidrenRec(node, list, itemComparator);
1443           propertyTreeModel.nodeStructureChanged(node);
1444         }
1445       }
1446     }
1447   }
1448 
1449   /**
1450    * Update the class tree model. To call when an instance is added.
1451    *
1452    @param anInstance instance to add
1453    */
1454   protected void instanceIsAdded(OInstance anInstance) {
1455     ArrayList<DefaultMutableTreeNode> newList = uri2TreeNodesListMap
1456             .get(anInstance.getURI().toString());
1457     if(newList != null) {
1458       for(int i = 0; i < newList.size(); i++) {
1459         DefaultMutableTreeNode node = newList.get(i);
1460         removeFromMap(treeModel, node);
1461       }
1462     }
1463     Set<OClass> superClasses = anInstance
1464             .getOClasses(OConstants.Closure.DIRECT_CLOSURE);
1465     List<OResource> list = new ArrayList<OResource>();
1466     list.add(anInstance);
1467     Iterator<OClass> iter = superClasses.iterator();
1468     while(iter.hasNext()) {
1469       OClass aClass = iter.next();
1470       ArrayList<DefaultMutableTreeNode> superNodeList = uri2TreeNodesListMap
1471               .get(aClass.getURI().toString());
1472       for(int i = 0; i < superNodeList.size(); i++) {
1473         DefaultMutableTreeNode node = superNodeList.get(i);
1474         addChidrenRec(node, list, itemComparator);
1475         treeModel.nodeStructureChanged(node);
1476       }
1477     }
1478   }
1479 
1480   private void removeFromMap(DefaultTreeModel model, DefaultMutableTreeNode node) {
1481     if(!node.isLeaf()) {
1482       Enumeration enumeration = node.children();
1483       ArrayList children = new ArrayList();
1484       while(enumeration.hasMoreElements()) {
1485         children.add(enumeration.nextElement());
1486       }
1487       for(int i = 0; i < children.size(); i++) {
1488         removeFromMap(model, (DefaultMutableTreeNode)children.get(i));
1489       }
1490     }
1491     URI rURI = reverseMap.get(node);
1492     reverseMap.remove(node);
1493     ArrayList<DefaultMutableTreeNode> list = uri2TreeNodesListMap.get(rURI
1494             .toString());
1495     list.remove(node);
1496     if(list.isEmpty()) uri2TreeNodesListMap.remove(rURI.toString());
1497 
1498     model.removeNodeFromParent(node);
1499   }
1500 
1501   /**
1502    * Update the property tree model. To call when a subproperty is added.
1503    *
1504    @param p subproperty to add
1505    */
1506   protected void subPropertyIsAdded(RDFProperty p) {
1507     ArrayList<DefaultMutableTreeNode> nodesList = uri2TreeNodesListMap.get(p
1508             .getURI().toString());
1509     // p is a property where the subProperty is added
1510     // the property which is added as a subProperty might not have any
1511     // super RDFProperty before
1512     // so we first remove it from the propertyTree
1513     Set<RDFProperty> props = p.getSubProperties(OConstants.Closure.DIRECT_CLOSURE);
1514     List<RDFProperty> ps = new ArrayList<RDFProperty>(props);
1515     Collections.sort(ps, itemComparator);
1516     for(RDFProperty subP : ps) {
1517       ArrayList<DefaultMutableTreeNode> subNodesList = uri2TreeNodesListMap
1518               .get(subP.getURI().toString());
1519       if(subNodesList != null) {
1520         for(int i = 0; i < subNodesList.size(); i++) {
1521           DefaultMutableTreeNode node = subNodesList.get(i);
1522           removeFromMap(propertyTreeModel, node);
1523           propertyTreeModel.nodeStructureChanged(node.getParent());
1524         }
1525       }
1526       if(subNodesList != null && nodesList != null) {
1527         // and each of this node needs to be added again
1528         for(int i = 0; i < nodesList.size(); i++) {
1529           DefaultMutableTreeNode superNode = nodesList.get(i);
1530           List<RDFProperty> list = new ArrayList<RDFProperty>();
1531           list.add(subP);
1532           addPropertyChidrenRec(superNode, list, itemComparator);
1533           propertyTreeModel.nodeStructureChanged(superNode);
1534         }
1535       }
1536     }
1537   }
1538 
1539   /**
1540    * Update the property tree model. To call when a subproperty is deleted.
1541    *
1542    @param p subproperty to delete
1543    */
1544   protected void subPropertyIsDeleted(RDFProperty p) {
1545     ArrayList<DefaultMutableTreeNode> nodeList = uri2TreeNodesListMap.get(p
1546             .getURI().toString());
1547     if(nodeList == null || nodeList.isEmpty()) {
1548       // this is already deleted
1549       return;
1550     }
1551     // p is a property where the subProperty is deleted
1552     // we don't know which property is deleted
1553     // so we remove the property p from the tree and add it again
1554     for(int i = 0; i < nodeList.size(); i++) {
1555       DefaultMutableTreeNode node = nodeList.get(i);
1556       removeFromMap(propertyTreeModel, node);
1557       propertyTreeModel.nodeStructureChanged(node.getParent());
1558     }
1559     // now we need to add it again
1560     Set<RDFProperty> superProperties = p
1561             .getSuperProperties(OConstants.Closure.DIRECT_CLOSURE);
1562     List<RDFProperty> list = new ArrayList<RDFProperty>();
1563     list.add(p);
1564     if(superProperties != null) {
1565       List<RDFProperty> rps = new ArrayList<RDFProperty>(superProperties);
1566       Collections.sort(rps, itemComparator);
1567       for(RDFProperty superP : rps) {
1568         nodeList = uri2TreeNodesListMap.get(superP.getURI().toString());
1569         for(int i = 0; i < nodeList.size(); i++) {
1570           DefaultMutableTreeNode superNode = nodeList.get(i);
1571           addPropertyChidrenRec(superNode, list, itemComparator);
1572           propertyTreeModel.nodeStructureChanged(superNode);
1573         }
1574       }
1575     }
1576     else {
1577       addPropertyChidrenRec(propertyRootNode, list, itemComparator);
1578       propertyTreeModel.nodeStructureChanged(propertyRootNode);
1579     }
1580   }
1581 
1582   /**
1583    * Update the class tree model. To call when a subclass is added.
1584    *
1585    @param c subclass to add
1586    */
1587   protected void subClassIsAdded(OClass c) {
1588     ArrayList<DefaultMutableTreeNode> nodesList = uri2TreeNodesListMap.get(c
1589             .getURI().toString());
1590     // c is a class where the subClass is added
1591     // the class which is added as a subClass might not have any
1592     // super Class before
1593     // so we first remove it from the tree
1594     Set<OClass> classes = c.getSubClasses(OClass.Closure.DIRECT_CLOSURE);
1595     List<OClass> cs = new ArrayList<OClass>(classes);
1596     Collections.sort(cs, itemComparator);
1597     for(OClass subC : cs) {
1598       ArrayList<DefaultMutableTreeNode> subNodesList = uri2TreeNodesListMap
1599               .get(subC.getURI().toString());
1600       if(subNodesList != null) {
1601         for(int i = 0; i < subNodesList.size(); i++) {
1602           DefaultMutableTreeNode node = subNodesList.get(i);
1603           removeFromMap(treeModel, node);
1604           treeModel.nodeStructureChanged(node.getParent());
1605         }
1606       }
1607       if(subNodesList != null && nodesList != null) {
1608         // and each of this node needs to be added again
1609         List<OResource> list = new ArrayList<OResource>();
1610         list.add(subC);
1611         for(int i = 0; i < nodesList.size(); i++) {
1612           DefaultMutableTreeNode superNode = nodesList.get(i);
1613           addChidrenRec(superNode, list, itemComparator);
1614           treeModel.nodeStructureChanged(superNode);
1615         }
1616       }
1617     }
1618   }
1619 
1620   /**
1621    * Update the class tree model. To call when a subclass is deleted.
1622    *
1623    @param c subclass to delete
1624    */
1625   protected void subClassIsDeleted(OClass c) {
1626     ArrayList<DefaultMutableTreeNode> nodeList = uri2TreeNodesListMap.get(c
1627             .getURI().toString());
1628     if(nodeList == null || nodeList.isEmpty()) {
1629       // this is already deleted
1630       return;
1631     }
1632 
1633     List<OResource> toAdd = new ArrayList<OResource>();
1634 
1635     // c is a class whose subClass is deleted
1636     // we don't know which class is deleted
1637     // so we remove the class c from the tree and add it again
1638     boolean firstTime = true;
1639     for(int i = 0; i < nodeList.size(); i++) {
1640       DefaultMutableTreeNode node = nodeList.get(i);
1641       if(firstTime) {
1642         OClass parentClass = (OClass)this.ontology
1643                 .getOResourceFromMap(reverseMap.get(node).toString());
1644         firstTime = false;
1645         // find out which class is deleted
1646         Enumeration e = node.children();
1647         if(e != null) {
1648           while(e.hasMoreElements()) {
1649             DefaultMutableTreeNode aNode = (DefaultMutableTreeNode)e
1650                     .nextElement();
1651             URI rURI = reverseMap.get(aNode);
1652             // lets check with the ontology if this instance is still
1653             // there
1654             OResource res = this.ontology.getOResourceFromMap(rURI.toString());
1655             if(res != null) {
1656               // lets check if its parents is the current node
1657               if(res instanceof OClass) {
1658                 if(((OClass)res).isSubClassOf(parentClass,
1659                         OConstants.Closure.DIRECT_CLOSURE)) {
1660                   // continue;
1661                 }
1662                 else {
1663                   // that's it this is the class which should be added
1664                   // at the top of tree
1665                   toAdd.add((OClass)res);
1666                   break;
1667                 }
1668               }
1669             }
1670           }
1671         }
1672       }
1673       removeFromMap(treeModel, node);
1674       treeModel.nodeStructureChanged(node.getParent());
1675     }
1676 
1677     // now we need to add it again
1678     Set<OClass> superClasses = c.getSuperClasses(OConstants.Closure.DIRECT_CLOSURE);
1679     List<OResource> list = new ArrayList<OResource>();
1680     list.add(c);
1681 
1682     if(superClasses != null && !superClasses.isEmpty()) {
1683       List<OClass> cs = new ArrayList<OClass>(superClasses);
1684       Collections.sort(cs, itemComparator);
1685       for(OClass superC : cs) {
1686         nodeList = uri2TreeNodesListMap.get(superC.getURI().toString());
1687         for(int i = 0; i < nodeList.size(); i++) {
1688           DefaultMutableTreeNode superNode = nodeList.get(i);
1689           addChidrenRec(superNode, list, itemComparator);
1690           treeModel.nodeStructureChanged(superNode);
1691         }
1692       }
1693     }
1694     else {
1695       addChidrenRec(rootNode, list, itemComparator);
1696       treeModel.nodeStructureChanged(rootNode);
1697     }
1698 
1699     if(!toAdd.isEmpty()) {
1700       addChidrenRec(rootNode, toAdd, itemComparator);
1701       treeModel.nodeStructureChanged(rootNode);
1702     }
1703   }
1704 
1705   public void resourcesRemoved(final Ontology ontology, final String[] resources) {
1706     if(this.ontology != ontology) {
1707       return;
1708     }
1709 
1710     // ok before we refresh our gui, lets find out the resource which
1711     // was deleted originally from the
1712     // gui. Deleting a resource results in deleting other resources as
1713     // well. The last resource in the resources is the one which was
1714     // asked from a user to delete.
1715     String deletedResourceURI = resources[resources.length - 1];
1716     DefaultMutableTreeNode aNode = uri2TreeNodesListMap.get(deletedResourceURI)
1717             .get(0);
1718 
1719     DefaultMutableTreeNode probableParentNode = null;
1720     if(aNode.getParent() == null) {
1721       OResource res = ((OResourceNode)aNode.getUserObject()).getResource();
1722       if(res instanceof RDFProperty) {
1723         probableParentNode = propertyRootNode;
1724       }
1725       else {
1726         probableParentNode = rootNode;
1727       }
1728     }
1729     else {
1730       probableParentNode = (DefaultMutableTreeNode)aNode.getParent();
1731     }
1732 
1733     final DefaultMutableTreeNode parentNode = probableParentNode;
1734     final URI parentURI = reverseMap.get(parentNode);
1735 
1736     SwingUtilities.invokeLater(new Runnable() {
1737       public void run() {
1738         // first hide the tree
1739         scroller.getViewport().setView(new JLabel("PLease wait, updating..."));
1740         propertyScroller.getViewport().setView(
1741                 new JLabel("Please wait, updating..."));
1742         // now update the tree
1743         // we can use a normal thread here
1744         Runnable treeUpdater = new Runnable() {
1745           public void run() {
1746             // this is not in the swing thread
1747             // update the tree...
1748             ontologyClassesURIs.removeAll(Arrays.asList(resources));
1749             final HashSet<DefaultMutableTreeNode> nodesToRefresh = new HashSet<DefaultMutableTreeNode>();
1750             for(int i = 0; i < resources.length; i++) {
1751               ArrayList<DefaultMutableTreeNode> nodeList = uri2TreeNodesListMap
1752                       .get(resources[i]);
1753               if(nodeList != null) {
1754                 for(int j = 0; j < nodeList.size(); j++) {
1755                   DefaultMutableTreeNode node = nodeList.get(j);
1756                   DefaultTreeModel modelToUse = ((OResourceNode)node
1757                           .getUserObject()).getResource() instanceof RDFProperty
1758                           ? propertyTreeModel
1759                           : treeModel;
1760                   if(node.getParent() != null) {
1761                     nodesToRefresh
1762                             .add((DefaultMutableTreeNode)node.getParent());
1763                   else if(modelToUse == treeModel) {
1764                     nodesToRefresh.add(rootNode);
1765                   else {
1766                     nodesToRefresh.add(propertyRootNode);
1767                   }
1768                   removeFromMap(modelToUse, node);
1769                   modelToUse.nodeStructureChanged(node.getParent());
1770                 }
1771               }
1772             }
1773 
1774             // now we need to show back the tree
1775             // go back to the swing thread
1776             SwingUtilities.invokeLater(new Runnable() {
1777               public void run() {
1778                 // show the tree again
1779                 scroller.getViewport().setView(tree);
1780                 propertyScroller.getViewport().setView(propertyTree);
1781                 // ask the tree to refresh
1782                 tree.invalidate();
1783                 propertyTree.invalidate();
1784 
1785                 for(DefaultMutableTreeNode parentNode : nodesToRefresh) {
1786                   if(!reverseMap.containsKey(parentNode&& parentNode != rootNode && parentNode != propertyRootNodecontinue;
1787                   
1788                   if(parentNode != rootNode && parentNode != propertyRootNode) {
1789                     OResource parentResource = ((OResourceNode)parentNode
1790                             .getUserObject()).getResource();
1791                     if(parentResource instanceof RDFProperty) {
1792                       List<RDFProperty> children = new ArrayList<RDFProperty>(
1793                               ((RDFProperty)parentResource)
1794                                       .getSubProperties(OConstants.Closure.DIRECT_CLOSURE));
1795                       Enumeration en = parentNode.children();
1796                       while(en.hasMoreElements()) {
1797                         DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode)en
1798                                 .nextElement();
1799                         String toCompare = ((OResourceNode)dmtn.getUserObject())
1800                                 .getResource().getURI().toString();
1801                         List<OResource> delete = new ArrayList<OResource>();
1802                         for(OResource aRes : children) {
1803                           if(toCompare.equals(aRes.getURI().toString())) {
1804                             delete.add(aRes);
1805                           }
1806                         }
1807                         children.removeAll(delete);
1808                       }
1809 
1810                       addPropertyChidrenRec(parentNode, children,
1811                               itemComparator);
1812                       propertyTreeModel.nodeStructureChanged(parentNode);
1813                       propertyTree.setSelectionPath(new TreePath(parentNode
1814                               .getPath()));
1815                     }
1816                     else {
1817                       List<OResource> children = new ArrayList<OResource>(
1818                               ((OClass)parentResource)
1819                                       .getSubClasses(OConstants.Closure.DIRECT_CLOSURE));
1820                       children.addAll(ontology
1821                               .getOInstances((OClass)parentResource,
1822                                       OConstants.Closure.DIRECT_CLOSURE));
1823                       Enumeration en = parentNode.children();
1824                       while(en.hasMoreElements()) {
1825                         DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode)en
1826                                 .nextElement();
1827                         String toCompare = ((OResourceNode)dmtn.getUserObject())
1828                                 .getResource().getURI().toString();
1829                         List<OResource> delete = new ArrayList<OResource>();
1830                         for(OResource aRes : children) {
1831                           if(toCompare.equals(aRes.getURI().toString())) {
1832                             delete.add(aRes);
1833                           }
1834                         }
1835                         children.removeAll(delete);
1836                       }
1837                       addChidrenRec(parentNode, children, itemComparator);
1838                       treeModel.nodeStructureChanged(parentNode);
1839                       tree.setSelectionPath(new TreePath(parentNode.getPath()));
1840                     }
1841                   }
1842                   else if(parentNode == rootNode) {
1843                     if(tree.getRowCount() 0) {
1844                       List<OResource> children = new ArrayList<OResource>(
1845                               ontology.getOClasses(true));
1846 
1847                       Enumeration en = parentNode.children();
1848                       while(en.hasMoreElements()) {
1849                         DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode)en
1850                                 .nextElement();
1851                         if(dmtn.getLevel() != 1continue;
1852                         String toCompare = ((OResourceNode)dmtn.getUserObject())
1853                                 .getResource().getURI().toString();
1854                         List<OResource> delete = new ArrayList<OResource>();
1855                         for(OResource aRes : children) {
1856                           if(toCompare.equals(aRes.getURI().toString())) {
1857                             delete.add(aRes);
1858                           }
1859                         }
1860                         children.removeAll(delete);
1861                       }
1862                       addChidrenRec(rootNode, children, itemComparator);
1863                       treeModel.nodeStructureChanged(rootNode);
1864                       tree.setSelectionRow(0);
1865                     }
1866                   }
1867                   else {
1868                     if(propertyTree.getRowCount() 0) {
1869                       List<RDFProperty> props = new ArrayList<RDFProperty>(
1870                               ontology.getPropertyDefinitions());
1871                       List<RDFProperty> subList = new ArrayList<RDFProperty>();
1872                       for(int i = 0; i < props.size(); i++) {
1873                         RDFProperty prop = props.get(i);
1874                         if(prop instanceof AnnotationProperty) {
1875                           subList.add(prop);
1876                           continue;
1877                         }
1878                         Set<RDFProperty> set = prop
1879                                 .getSuperProperties(OConstants.Closure.DIRECT_CLOSURE);
1880                         if(set != null && !set.isEmpty()) {
1881                           continue;
1882                         }
1883                         else {
1884                           subList.add(prop);
1885                         }
1886                       }
1887                       Collections.sort(subList, itemComparator);
1888                       Enumeration en = parentNode.children();
1889                       while(en.hasMoreElements()) {
1890                         DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode)en
1891                                 .nextElement();
1892                         if(dmtn.getLevel() != 1continue;
1893                         String toCompare = ((OResourceNode)dmtn.getUserObject())
1894                                 .getResource().getURI().toString();
1895                         List<OResource> delete = new ArrayList<OResource>();
1896                         for(OResource aRes : subList) {
1897                           if(toCompare.equals(aRes.getURI().toString())) {
1898                             delete.add(aRes);
1899                           }
1900                         }
1901                         subList.removeAll(delete);
1902                       }
1903 
1904                       addPropertyChidrenRec(propertyRootNode, subList,
1905                               itemComparator);
1906                       propertyTreeModel.nodeStructureChanged(propertyRootNode);
1907                       propertyTree.setSelectionRow(0);
1908                     }
1909                   }
1910                 }
1911               }
1912             });
1913           }
1914         };
1915         treeUpdater.run();
1916       }
1917     });
1918   }
1919 
1920   public void resourceAdded(Ontology ontology, OResource resource) {
1921     if(this.ontology != ontology) {
1922       return;
1923     }
1924     boolean isItTree = true;
1925     TreePath path = tree.getSelectionPath();
1926     if(path == null) {
1927       isItTree = false;
1928       path = propertyTree.getSelectionPath();
1929     }
1930 
1931     if(resource instanceof OClass) {
1932       classIsAdded((OClass)resource);
1933       expandNode(tree);
1934     }
1935     else if(resource instanceof RDFProperty) {
1936       propertyIsAdded((RDFProperty)resource);
1937       expandNode(propertyTree);
1938     }
1939     else if(resource instanceof OInstance) {
1940       instanceIsAdded((OInstance)resource);
1941       expandNode(tree);
1942     }
1943     datatypePropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
1944     objectPropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
1945     symmetricPropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
1946     transitivePropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
1947 
1948     if(isItTree) {
1949       DefaultMutableTreeNode aNode = uri2TreeNodesListMap.get(
1950               resource.getURI().toString()).get(0);
1951       tree.setSelectionPath(new TreePath(aNode.getPath()));
1952     }
1953     else {
1954       DefaultMutableTreeNode aNode = uri2TreeNodesListMap.get(
1955               resource.getURI().toString()).get(0);
1956       propertyTree.setSelectionPath(new TreePath(aNode.getPath()));
1957     }
1958     return;
1959   }
1960 
1961   public void resourceRelationChanged(Ontology ontology, OResource resource1,
1962           OResource resouce2, int eventType) {
1963     this.ontologyModified(ontology, resource1, eventType);
1964   }
1965 
1966   public void resourcePropertyValueChanged(Ontology ontology,
1967           OResource resource, RDFProperty property, Object value, int eventType) {
1968     this.ontologyModified(ontology, resource, eventType);
1969   }
1970 
1971   /**
1972    * This method is invoked from ontology whenever it is modified
1973    */
1974   public void ontologyModified(Ontology ontology, OResource resource,
1975           int eventType) {
1976     if(this.ontology != ontology) {
1977       return;
1978     }
1979     boolean isItTree = true;
1980     TreePath path = tree.getSelectionPath();
1981     if(path == null) {
1982       isItTree = false;
1983       path = propertyTree.getSelectionPath();
1984     }
1985 
1986     switch(eventType) {
1987       case OConstants.SUB_PROPERTY_ADDED_EVENT:
1988         subPropertyIsAdded((RDFProperty)resource);
1989         break;
1990       case OConstants.SUB_PROPERTY_REMOVED_EVENT:
1991         subPropertyIsDeleted((RDFProperty)resource);
1992         break;
1993       case OConstants.SUB_CLASS_ADDED_EVENT:
1994         subClassIsAdded((OClass)resource);
1995         break;
1996       case OConstants.SUB_CLASS_REMOVED_EVENT:
1997         subClassIsDeleted((OClass)resource);
1998         break;
1999     }
2000 
2001     switch(eventType) {
2002       case OConstants.SUB_PROPERTY_ADDED_EVENT:
2003       case OConstants.SUB_PROPERTY_REMOVED_EVENT:
2004         expandNode(propertyTree);
2005         break;
2006       default:
2007         expandNode(tree);
2008         break;
2009     }
2010     datatypePropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
2011     objectPropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
2012     symmetricPropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
2013     transitivePropertyAction.setOntologyClassesURIs(ontologyClassesURIs);
2014     if(isItTree) {
2015       tree.setSelectionPath(path);
2016       DefaultMutableTreeNode aNode = uri2TreeNodesListMap.get(
2017               resource.getURI().toString()).get(0);
2018       tree.setSelectionPath(new TreePath(aNode.getPath()));
2019     }
2020     else {
2021       propertyTree.setSelectionPath(path);
2022       DefaultMutableTreeNode aNode = uri2TreeNodesListMap.get(
2023               resource.getURI().toString()).get(0);
2024       propertyTree.setSelectionPath(new TreePath(aNode.getPath()));
2025     }
2026   }
2027 
2028   /**
2029    * This method is called whenever ontology is reset. 
2030    
2031    @param ontology
2032    */
2033   public void ontologyReset(Ontology ontology) {
2034     if(this.ontology != ontology) {
2035       return;
2036     }
2037     rebuildModel();
2038   }
2039 
2040   public void addTreeNodeSelectionListener(TreeNodeSelectionListener listener) {
2041     this.listeners.add(listener);
2042   }
2043 
2044   public void removeTreeNodeSelectionListener(TreeNodeSelectionListener listener) {
2045     this.listeners.remove(listener);
2046   }
2047 
2048   private void fireTreeNodeSelectionChanged(
2049           ArrayList<DefaultMutableTreeNode> nodes) {
2050     for(int i = 0; i < listeners.size(); i++) {
2051       listeners.get(i).selectionChanged(nodes);
2052     }
2053   }
2054 
2055   class DnDJTree extends JTree implements DragGestureListener,
2056                               DropTargetListener, DragSourceListener {
2057 
2058     /** Variables needed for DnD */
2059     private DragSource dragSource = null;
2060 
2061     private DragSourceContext dragSourceContext = null;
2062 
2063     private DefaultMutableTreeNode selectedNode = null;
2064 
2065     private TreePath selectedTreePath = null;
2066 
2067     /**
2068      * Constructor
2069      
2070      @param model tree model
2071      */
2072     public DnDJTree(TreeModel model) {
2073       super(model);
2074       dragSource = DragSource.getDefaultDragSource();
2075       DragGestureRecognizer dgr = dragSource
2076               .createDefaultDragGestureRecognizer(this,
2077                       DnDConstants.ACTION_MOVE, this);
2078       DropTarget dropTarget = new DropTarget(this, this);
2079     }
2080 
2081     /** DragGestureListener interface method */
2082     public void dragGestureRecognized(DragGestureEvent e) {
2083       // Get the selected node
2084       if(selectedNodes.isEmpty()) {
2085         selectedNode = null;
2086         selectedTreePath = null;
2087         return;
2088       }
2089 
2090       selectedNode = selectedNodes.get(0);
2091       selectedTreePath = new TreePath(selectedNode.getPath());
2092       DefaultMutableTreeNode dragNode = selectedNode;
2093 
2094       if(dragNode != null) {
2095 
2096         // Get the Transferable Object
2097         Transferable transferable = (Transferable)dragNode.getUserObject();
2098 
2099         // Select the appropriate cursor;
2100         Cursor cursor = DragSource.DefaultCopyNoDrop;
2101         int action = e.getDragAction();
2102         if(action == DnDConstants.ACTION_MOVE)
2103           cursor = DragSource.DefaultMoveNoDrop;
2104 
2105         // begin the drag
2106         dragSource.startDrag(e, cursor, transferable, this);
2107       }
2108     }
2109 
2110     /** DragSourceListener interface method */
2111     public void dragDropEnd(DragSourceDropEvent dsde) {
2112     }
2113 
2114     /** DragSourceListener interface method */
2115     public void dragEnter(DragSourceDragEvent dsde) {
2116     }
2117 
2118     /** DragSourceListener interface method */
2119     public void dragOver(DragSourceDragEvent dsde) {
2120     }
2121 
2122     /** DragSourceListener interface method */
2123     public void dropActionChanged(DragSourceDragEvent dsde) {
2124     }
2125 
2126     /** DragSourceListener interface method */
2127     public void dragExit(DragSourceEvent dsde) {
2128     }
2129 
2130     /**
2131      * DropTargetListener interface method - What we do when drag is
2132      * released
2133      */
2134     public void drop(DropTargetDropEvent e) {
2135       /*
2136        * Transferable tr = e.getTransferable();
2137        
2138        * DefaultMutableTreeNode node =
2139        * (DefaultMutableTreeNode)selectedTreePath
2140        * .getLastPathComponent(); OResource source =
2141        * ((OResourceNode)node.getUserObject()).getResource();
2142        
2143        * if(source instanceof OInstance) { e.rejectDrop();
2144        * SwingUtilities.invokeLater(new Runnable() { public void run() {
2145        * JOptionPane.showMessageDialog(MainFrame.getInstance(),
2146        * "Instances are not allowed to be moved!", "Error Dialog",
2147        * JOptionPane.ERROR_MESSAGE); } }); return; } // now check if the
2148        * class to be moved under the class is not a // super class of
2149        * the later. // get new parent node Point loc = e.getLocation();
2150        * TreePath destinationPath = getPathForLocation(loc.x, loc.y);
2151        * if(destinationPath == null) { e.rejectDrop(); return; }
2152        
2153        * OResource target =
2154        * ((OResourceNode)((DefaultMutableTreeNode)destinationPath
2155        * .getLastPathComponent()).getUserObject()).getResource();
2156        
2157        * if(target instanceof OInstance) { e.rejectDrop();
2158        * SwingUtilities.invokeLater(new Runnable() { public void run() {
2159        * JOptionPane.showMessageDialog(MainFrame.getInstance(), "Invalid
2160        * Operation!", "Error Dialog", JOptionPane.ERROR_MESSAGE); } });
2161        * return; }
2162        
2163        * if(source instanceof OClass && target instanceof OClass) {
2164        * if(((OClass)target).isSubClassOf((OClass)source,
2165        * OConstants.TRANSITIVE_CLOSURE)) { e.rejectDrop();
2166        * SwingUtilities.invokeLater(new Runnable() { public void run() {
2167        * JOptionPane.showMessageDialog(MainFrame.getInstance(), "A super
2168        * class can not be set as a sub class!", "Error Dialog",
2169        * JOptionPane.ERROR_MESSAGE); } }); return; } }
2170        
2171        * if(source instanceof RDFProperty && target instanceof
2172        * RDFProperty) {
2173        * if(((RDFProperty)target).isSubPropertyOf((RDFProperty)source,
2174        * OConstants.TRANSITIVE_CLOSURE)) { e.rejectDrop();
2175        * SwingUtilities.invokeLater(new Runnable() { public void run() {
2176        * JOptionPane.showMessageDialog(MainFrame.getInstance(), "A super
2177        * property can not be set as a sub property!", "Error Dialog",
2178        * JOptionPane.ERROR_MESSAGE); } });
2179        
2180        * return; }
2181        
2182        * if(source instanceof AnnotationProperty || target instanceof
2183        * AnnotationProperty) { e.rejectDrop();
2184        * SwingUtilities.invokeLater(new Runnable() { public void run() {
2185        * JOptionPane .showMessageDialog( MainFrame.getInstance(),
2186        * "Annotation Properties cannot be set as sub or super
2187        * properties!", "Error Dialog", JOptionPane.ERROR_MESSAGE); } });
2188        * return; } }
2189        
2190        * if(!source.getClass().getName().equals(target.getClass().getName())) {
2191        * e.rejectDrop(); SwingUtilities.invokeLater(new Runnable() {
2192        * public void run() {
2193        * JOptionPane.showMessageDialog(MainFrame.getInstance(), "Invalid
2194        * Operation!", "Error Dialog", JOptionPane.ERROR_MESSAGE); } });
2195        * return; }
2196        
2197        * if(source instanceof OClass && target instanceof OClass) { //
2198        * first find out the source's super classes OClass sc =
2199        * (OClass)source; Set<OClass> superClasses = sc
2200        * .getSuperClasses(OConstants.DIRECT_CLOSURE); // lets check if
2201        * the
2202        
2203        * for(OClass sClass : superClasses) { sClass.removeSubClass(sc); }
2204        
2205        * ((OClass)target).addSubClass(sc);
2206        
2207        * return; }
2208        
2209        * if(source instanceof RDFProperty && target instanceof
2210        * RDFProperty) { // first find out the source's super classes
2211        * RDFProperty sp = (RDFProperty)source; Set<RDFProperty>
2212        * superProps = sp .getSuperProperties(OConstants.DIRECT_CLOSURE);
2213        
2214        * for(RDFProperty sProp : superProps) {
2215        * sProp.removeSubProperty(sp); }
2216        
2217        * ((RDFProperty)target).addSubProperty(sp);
2218        
2219        * return; }
2220        
2221        */
2222       int action = e.getDropAction();
2223       e.rejectDrop();
2224       e.getDropTargetContext().dropComplete(false);
2225       SwingUtilities.invokeLater(new Runnable() {
2226         public void run() {
2227           JOptionPane
2228                   .showMessageDialog(
2229                           MainFrame.getInstance(),
2230                           "This feature is being implemented and will be provided soon",
2231                           "Coming Soon!", JOptionPane.INFORMATION_MESSAGE);
2232         }
2233       });
2234     // end of method
2235 
2236     /** DropTaregetListener interface method */
2237     public void dragEnter(DropTargetDragEvent e) {
2238     }
2239 
2240     /** DropTaregetListener interface method */
2241     public void dragExit(DropTargetEvent e) {
2242     }
2243 
2244     /** DropTaregetListener interface method */
2245     public void dragOver(DropTargetDragEvent e) {
2246     }
2247 
2248     /** DropTaregetListener interface method */
2249     public void dropActionChanged(DropTargetDragEvent e) {
2250     }
2251 
2252   // end of DnDJTree
2253 
2254   public void selectResourceInClassTree(final OResource resource) {
2255     SwingUtilities.invokeLater(new Runnable() { public void run() {
2256       tabbedPane.setSelectedComponent(scroller);
2257       tree.setSelectionPath(new TreePath(uri2TreeNodesListMap.get(
2258         resource.getURI().toString()).get(0).getPath()));
2259       tree.scrollPathToVisible(tree.getSelectionPath());
2260     }});
2261   }
2262   /**
2263    * the ontology instance
2264    */
2265   protected Ontology ontology;
2266 
2267   /**
2268    * Ontology Item Comparator
2269    */
2270   protected OntologyItemComparator itemComparator;
2271 
2272   /**
2273    * The tree view.
2274    */
2275   protected DnDJTree tree;
2276 
2277   /**
2278    * The property treeView
2279    */
2280   protected DnDJTree propertyTree;
2281 
2282   /**
2283    * The mode, for the tree.
2284    */
2285   protected DefaultTreeModel treeModel;
2286 
2287   /**
2288    * The property model, for the tree
2289    */
2290   protected DefaultTreeModel propertyTreeModel;
2291 
2292   /**
2293    * The list view used to display item details
2294    */
2295   protected JTable detailsTable;
2296 
2297   protected JTable propertyDetailsTable;
2298 
2299   protected DetailsTableModel detailsTableModel;
2300 
2301   protected PropertyDetailsTableModel propertyDetailsTableModel;
2302 
2303   /**
2304    * The main split
2305    */
2306   protected JSplitPane mainSplit;
2307 
2308   /**
2309    * The root node of the tree.
2310    */
2311   protected DefaultMutableTreeNode rootNode;
2312 
2313   /**
2314    * The property root node of the tree
2315    */
2316   protected DefaultMutableTreeNode propertyRootNode;
2317 
2318   protected JScrollPane detailsTableScroller, propertyDetailsTableScroller;
2319 
2320   /**
2321    * ToolBar
2322    */
2323   protected JToolBar toolBar;
2324 
2325   protected JButton queryBtn;
2326 
2327   protected JButton refreshOntologyBtn;
2328   
2329   protected JButton topClass;
2330 
2331   protected JButton subClass;
2332 
2333   protected JButton restriction;
2334 
2335   protected JButton instance;
2336 
2337   protected JButton annotationProperty;
2338 
2339   protected JButton datatypeProperty;
2340 
2341   protected JButton objectProperty;
2342 
2343   protected JButton symmetricProperty;
2344 
2345   protected JButton transitiveProperty;
2346 
2347   protected JButton delete;
2348 
2349   protected JButton search;
2350 
2351   protected ArrayList<DefaultMutableTreeNode> selectedNodes;
2352 
2353   protected ArrayList<String> ontologyClassesURIs;
2354 
2355   protected SearchAction searchAction;
2356 
2357   protected TopClassAction topClassAction;
2358 
2359   protected SubClassAction subClassAction;
2360 
2361   protected InstanceAction instanceAction;
2362 
2363   protected AnnotationPropertyAction annotationPropertyAction;
2364 
2365   protected DatatypePropertyAction datatypePropertyAction;
2366 
2367   protected ObjectPropertyAction objectPropertyAction;
2368 
2369   protected SymmetricPropertyAction symmetricPropertyAction;
2370 
2371   protected TransitivePropertyAction transitivePropertyAction;
2372 
2373   protected DeleteOntologyResourceAction deleteOntoResourceAction;
2374 
2375   protected RestrictionAction restrictionAction;
2376 
2377   protected ArrayList<TreeNodeSelectionListener> listeners;
2378 
2379   protected HashMap<String, ArrayList<DefaultMutableTreeNode>> uri2TreeNodesListMap;
2380 
2381   protected HashMap<DefaultMutableTreeNode, URI> reverseMap;
2382 
2383   protected JScrollPane propertyScroller, scroller;
2384 
2385   protected JTabbedPane tabbedPane;
2386 }