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