Re-designed taxonomic tree content provider (currently set to TaxTreeContentProvider...
[taxeditor.git] / eclipseprojects / eu.etaxonomy.taxeditor / src / eu / etaxonomy / taxeditor / TaxEditorPlugin.java
index 0aba7b993b226062fd0f620d5eb40e62cac5dd52..c48d5854bbb3c3245748c551e7dab897dfe6b0f3 100644 (file)
@@ -1,4 +1,3 @@
-\r
 /**\r
  * Copyright (C) 2007 EDIT\r
  * European Distributed Institute of Taxonomy \r
 package eu.etaxonomy.taxeditor;\r
 \r
 import java.net.URL;\r
-import java.util.ArrayList;\r
 import java.util.Collection;\r
 import java.util.HashMap;\r
 import java.util.HashSet;\r
-import java.util.List;\r
 import java.util.Map;\r
 import java.util.ResourceBundle;\r
 import java.util.Set;\r
@@ -29,7 +26,6 @@ import org.eclipse.core.databinding.observable.set.WritableSet;
 import org.eclipse.core.runtime.FileLocator;\r
 import org.eclipse.core.runtime.IPath;\r
 import org.eclipse.core.runtime.Path;\r
-import org.eclipse.core.runtime.Platform;\r
 import org.eclipse.jface.databinding.swt.SWTObservables;\r
 import org.eclipse.jface.preference.IPreferenceStore;\r
 import org.eclipse.jface.resource.FontRegistry;\r
@@ -63,6 +59,7 @@ import eu.etaxonomy.cdm.model.name.Rank;
 import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
 import eu.etaxonomy.cdm.model.taxon.Taxon;\r
 import eu.etaxonomy.taxeditor.model.CdmUtil;\r
+import eu.etaxonomy.taxeditor.view.TaxonomicTreeView;\r
 \r
 /**\r
  * The class controlling the plug-in life cycle.\r
@@ -96,24 +93,61 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
                logger.info("Info");\r
                logger.warn("Warn");\r
                logger.trace("Trace");\r
+       }\r
 \r
+       /*\r
+        * (non-Javadoc)\r
+        * \r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)\r
+        */\r
+       public void start(BundleContext context) throws Exception {\r
+               super.start(context);\r
+               plugin = this;\r
+               \r
                boolean initDatastore = false;\r
-               initDatastore = true;\r
+\r
+               // If the preferences INITIALIZED has not been set, the IF clause\r
+               // will return false, i.e. datastore will be initialized first\r
+               // time the application is run after being installed.\r
+               boolean initialized = getPreferenceStore()\r
+                               .getBoolean(ITaxEditorConstants.INITIALIZED);\r
+               \r
+//             initialized = false;\r
+               if (!initialized) {\r
+                       logger.warn("Initializing datastore");\r
+                       initDatastore = true;\r
+\r
+                       getPreferenceStore()\r
+                                       .setValue(ITaxEditorConstants.INITIALIZED, true);\r
+               } else {\r
+                       logger.warn("Datastore already initialized");\r
+               }\r
+\r
                if (initDatastore) {\r
                        dbSchemaValidation = DbSchemaValidation.CREATE;\r
                }\r
 \r
                cdmApp = getCdmApp();\r
 \r
-               if (initDatastore) {\r
-                       initDatastore();\r
-               }\r
+//             if (initDatastore) {\r
+//                     initDatastore();\r
+//             }\r
+               \r
        }\r
 \r
+       /*\r
+        * (non-Javadoc)\r
+        * \r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)\r
+        */\r
+       public void stop(BundleContext context) throws Exception {\r
+               stopTransaction();\r
+               plugin = null;\r
+               super.stop(context);\r
+       }\r
+       \r
        void initDatastore() {\r
 \r
-//             if (1 == 1) return;\r
-               \r
                boolean useSoraya = true;\r
                // useSoraya = false;\r
                Taxon genusTaxon;\r
@@ -173,27 +207,6 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
                // System.exit(-1);\r
        }\r
 \r
-       /*\r
-        * (non-Javadoc)\r
-        * \r
-        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)\r
-        */\r
-       public void start(BundleContext context) throws Exception {\r
-               super.start(context);\r
-               plugin = this;\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * \r
-        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)\r
-        */\r
-       public void stop(BundleContext context) throws Exception {\r
-               stopTransaction();\r
-               plugin = null;\r
-               super.stop(context);\r
-       }\r
-\r
        /**\r
         * Returns the shared instance\r
         * \r
@@ -215,16 +228,17 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
        public CdmApplicationController getCdmApp() {\r
                if (cdmApp == null) {\r
                        try {\r
-//                             ICdmDataSource ds = CdmDataSource.NewH2EmbeddedInstance("cdm", "sa", "");\r
-//                             cdmApp = CdmApplicationController\r
-//                                             .NewInstance(ds, dbSchemaValidation);\r
-                               cdmApp = CdmApplicationController.NewInstance(dbSchemaValidation); \r
-                               \r
+                               // ICdmDataSource ds =\r
+                               // CdmDataSource.NewH2EmbeddedInstance("cdm", "sa", "");\r
+                               // cdmApp = CdmApplicationController\r
+                               // .NewInstance(ds, dbSchemaValidation);\r
+                               cdmApp = CdmApplicationController\r
+                                               .NewInstance(dbSchemaValidation);\r
+\r
                                startTransaction();\r
-//                             Object txStatus = cdmApp.startTransaction();\r
-//                             cdmApp.commitTransaction((TransactionStatus) txStatus);\r
-                               \r
-                               \r
+                               // Object txStatus = cdmApp.startTransaction();\r
+                               // cdmApp.commitTransaction((TransactionStatus) txStatus);\r
+\r
                        } catch (DataSourceNotFoundException e) {\r
                                // TODO Auto-generated catch block\r
                                e.printStackTrace();\r
@@ -235,13 +249,13 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
                }\r
                return cdmApp;\r
        }\r
-       \r
+\r
        public void startTransaction() {\r
                if (cdmApp != null) {\r
                        txStatus = cdmApp.startTransaction();\r
                }\r
        }\r
-       \r
+\r
        public void stopTransaction() {\r
                if (txStatus != null) {\r
                        cdmApp.commitTransaction(txStatus);\r
@@ -304,43 +318,43 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
        private FormColors formColors;\r
 \r
        protected void initializeImageRegistry(ImageRegistry registry) {\r
-               registerImage(registry, ITaxEditorConstants.EDIT_ICON, "edit_16x16.ico"); \r
+               registerImage(registry, ITaxEditorConstants.EDIT_ICON, "edit_16x16.ico");\r
                registerImage(registry, ITaxEditorConstants.WARNING_ICON,\r
-                               "warn_tsk.gif"); \r
+                               "warn_tsk.gif");\r
                registerImage(registry, ITaxEditorConstants.ACCEPTED_TAXON_ICON,\r
-                               "accepted_small.gif"); \r
+                               "accepted_small.gif");\r
                registerImage(registry, ITaxEditorConstants.HOMOTYPIC_SYN_ICON,\r
-                               "homosyn_no_bg.gif"); \r
+                               "homosyn_no_bg.gif");\r
                registerImage(registry,\r
                                ITaxEditorConstants.HOMOTYPIC_SYN_ORIGINAL_ICON,\r
-                               "homosyn_original_no_bg.gif"); \r
+                               "homosyn_original_no_bg.gif");\r
                registerImage(registry, ITaxEditorConstants.HETEROTYPIC_SYN_ICON,\r
-                               "heterosyn_no_bg.gif"); \r
+                               "heterosyn_no_bg.gif");\r
                registerImage(registry,\r
                                ITaxEditorConstants.HETEROTYPIC_SYN_ORIGINAL_ICON,\r
-                               "heterosyn_original_no_bg.gif");                \r
+                               "heterosyn_original_no_bg.gif");\r
                registerImage(registry, ITaxEditorConstants.MISAPPLIED_NAME_ICON,\r
-                               "misapplied_no_bg.gif"); \r
+                               "misapplied_no_bg.gif");\r
                registerImage(registry, ITaxEditorConstants.AUTONYM_ICON,\r
-                               "autonym_no_bg.gif"); \r
+                               "autonym_no_bg.gif");\r
                registerImage(registry, ITaxEditorConstants.BASIONYM_ICON,\r
                                "basionym_no_bg.gif");\r
                registerImage(registry, ITaxEditorConstants.ORTHOGRAPHIC_VARIANT_ICON,\r
-                               "orthovariant_no_bg.gif");              \r
-               registerImage(registry, ITaxEditorConstants.DB_ICON, "db.gif"); \r
-               registerImage(registry, ITaxEditorConstants.MOVE_ICON, "correction_change.gif"); \r
+                               "orthovariant_no_bg.gif");\r
+               registerImage(registry, ITaxEditorConstants.DB_ICON, "db.gif");\r
+               registerImage(registry, ITaxEditorConstants.MOVE_ICON,\r
+                               "correction_change.gif");\r
                registerImage(registry, ITaxEditorConstants.ACTIVE_DELETE_ICON,\r
                                "delete_edit.gif");\r
                registerImage(registry, ITaxEditorConstants.SYNONYM_TO_TAXON_ICON,\r
                                "change.gif");\r
-               registerImage(registry, ITaxEditorConstants.OPEN_TAXON_ICON,\r
-                               "open.gif");            \r
+               registerImage(registry, ITaxEditorConstants.OPEN_TAXON_ICON, "open.gif");\r
                registerImage(registry, ITaxEditorConstants.ADD_CHILD_TAXON_ICON,\r
                                "new_child.gif");\r
-               registerImage(registry, ITaxEditorConstants.SWAP_SYNONYM_AND_TAXON_ICON,\r
-                               "swap2.gif");\r
+               registerImage(registry,\r
+                               ITaxEditorConstants.SWAP_SYNONYM_AND_TAXON_ICON, "swap2.gif");\r
                registerImage(registry, ITaxEditorConstants.QUICK_ADD_ICON,\r
-                               "quick_add.gif");               \r
+                               "quick_add.gif");\r
                registerImage(registry, ITaxEditorConstants.TAXON_TO_SYNONYM_ICON,\r
                                "tax_to_syn.gif");\r
        }\r
@@ -391,7 +405,8 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
         * PREFERENCES\r
         **************************************************************************/\r
        protected void initializeDefaultPreferences(IPreferenceStore store) {\r
-//             Platform.getPreferencesService().getBoolean(qualifier, key, defaultValue, contexts)\r
+               // Platform.getPreferencesService().getBoolean(qualifier, key,\r
+               // defaultValue, contexts)\r
                store.setDefault(ITaxEditorConstants.CODE_PREFERENCE,\r
                                ITaxEditorConstants.DEFAULT_CODE_PREFERENCE);\r
        }\r
@@ -405,28 +420,32 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
                                UUID.fromString("f3593c18-a8d2-4e51-bdad-0befbf8fb2d1"));\r
        }\r
 \r
-       private List<Taxon> sessionRootTaxa;\r
+//     private List<Taxon> sessionRootTaxa;\r
+       private Set<Taxon> sessionRootTaxa;\r
        /**\r
-        * The taxonomic tree content provider observes this set for changes,\r
-        *      and makes the appropriate changes to the tree.\r
+        * The taxonomic tree content provider observes this set for changes, and\r
+        * makes the appropriate changes to the tree.\r
         */\r
        private IObservableSet observableSessionTaxonSet;\r
        /**\r
         * This map of taxa to their taxonomic children is used by\r
         * NameTreeContentProvider's getChildren method.\r
         * \r
-        * key = taxon, value = key's child taxa \r
-        * Note that a map can have a key == null, i.e. no parent taxon\r
-        */     \r
+        * key = taxon, value = key's child taxa Note that a map can have a key ==\r
+        * null, i.e. no parent taxon\r
+        */\r
        private HashMap<Taxon, Set<Taxon>> sessionTaxonomicChildrenMap;\r
 \r
-       public List<Taxon> getSessionRootTaxa() {\r
+       public Set<Taxon> getSessionRootTaxa() {\r
+//     public List<Taxon> getSessionRootTaxa() {\r
                if (sessionRootTaxa == null) {\r
-                       sessionRootTaxa = new ArrayList<Taxon>();\r
-                       sessionRootTaxa\r
-                                       .addAll(getCdmApp().getTaxonService().getRootTaxa(getSec(), null, false));\r
+//                     sessionRootTaxa = new ArrayList<Taxon>();\r
+                       sessionRootTaxa = new HashSet<Taxon>();\r
+                       sessionRootTaxa.addAll(getCdmApp().getTaxonService().getRootTaxa(\r
+                                       getSec(), null, false));\r
                        addSessionTaxa(sessionRootTaxa);\r
                }\r
+               logger.warn(sessionRootTaxa.size() + " taxa in root taxa");\r
                return sessionRootTaxa;\r
        }\r
 \r
@@ -438,13 +457,28 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
        }\r
 \r
        /**\r
-        * Returns a set of any child taxa for this taxon that have already been \r
+        * Returns a set of any child taxa for this taxon that have already been\r
         * requested during this session.\r
         * \r
         * @param parentTaxon\r
         * @return\r
         */\r
        public Set<Taxon> getSessionTaxonomicChildren(Taxon parentTaxon) {\r
+               if (!getTaxonomicChildrenMap().containsKey(parentTaxon)) {\r
+                       if (parentTaxon == null) {\r
+                               getTaxonomicChildrenMap().put(parentTaxon, getSessionRootTaxa());\r
+                       } else {\r
+                       \r
+                               // BUG deleted taxon where re-appearing as NULL children\r
+                               Set<Taxon> childTaxa = new HashSet<Taxon>();\r
+                               for (Taxon taxon : parentTaxon.getTaxonomicChildren()) {\r
+                                       if (taxon != null) {\r
+                                               childTaxa.add(taxon);\r
+                                       }\r
+                               }\r
+                               getTaxonomicChildrenMap().put(parentTaxon, childTaxa);\r
+                       }\r
+               }\r
                return getTaxonomicChildrenMap().get(parentTaxon);\r
        }\r
 \r
@@ -458,17 +492,18 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
                }\r
                return observableSessionTaxonSet;\r
        }\r
-       \r
+\r
        /**\r
-        * Recursive function to clear the hashmap of a taxon's children used in this session, \r
-        *      and the childrens' children, etc.\r
+        * Recursive function to clear the hashmap of a taxon's children used in\r
+        * this session, and the childrens' children, etc.\r
         * \r
         * @param taxon\r
         */\r
        private void clearTaxonomicChildren(Taxon taxon) {\r
                Set<Taxon> children = getSessionTaxonomicChildren(taxon);\r
                if (children != null) {\r
-                       logger.warn(children.size() + " children in " + CdmUtil.getDisplayName(taxon));\r
+                       logger.warn(children.size() + " children in "\r
+                                       + CdmUtil.getDisplayName(taxon));\r
                        for (Taxon child : children) {\r
                                clearTaxonomicChildren(child);\r
                        }\r
@@ -476,28 +511,30 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
                        getObservableSessionTaxa().removeAll(children);\r
                }\r
        }\r
-       \r
+\r
        /**\r
         * Remove taxon from all session collections\r
         * \r
         * @param taxon\r
         */\r
        public void removeSessionTaxon(Taxon taxon) {\r
-               \r
+\r
                // Recursively remove all children, children's children, etc.\r
                clearTaxonomicChildren(taxon);\r
-               \r
+\r
                Taxon parentTaxon = taxon.getTaxonomicParent();\r
-               \r
+\r
                // Remove from parent's child map, or from root taxa\r
                if (parentTaxon == null) {\r
                        getSessionRootTaxa().remove(taxon);\r
                } else {\r
-                       getTaxonomicChildrenMap().get(parentTaxon).remove(taxon);\r
+                       getSessionTaxonomicChildren(parentTaxon).remove(taxon);\r
                }\r
-               \r
+\r
                // Remove from session taxa\r
                getObservableSessionTaxa().remove(taxon);\r
+               \r
+               UiUtil.getTreeViewer().remove(taxon);\r
        }\r
 \r
        public void addSessionTaxa(Collection<Taxon> taxa) {\r
@@ -508,35 +545,50 @@ public class TaxEditorPlugin extends AbstractUIPlugin {
 \r
        /**\r
         * Whenever a taxon is opened, either for editing or for display in the\r
-        *      taxonomic tree, it should be added to the collections of taxa used\r
-        *      during this session.\r
+        * taxonomic tree, it should be added to the collections of taxa used during\r
+        * this session.\r
         * \r
         * @param taxon\r
         */\r
        public void addSessionTaxon(Taxon taxon) {\r
-               \r
+\r
                // Add taxon to session taxa if not already there\r
                if (!(getObservableSessionTaxa().contains(taxon))) {\r
                        getObservableSessionTaxa().add(taxon);\r
                }\r
                \r
                Taxon parentTaxon = taxon.getTaxonomicParent();\r
-               \r
+\r
                // If taxon has no parent, add it to root taxa\r
                if (parentTaxon == null) {\r
                        if (!(getSessionRootTaxa().contains(taxon))) {\r
                                getSessionRootTaxa().add(taxon);\r
                        }\r
                }\r
-               \r
+\r
                // Add taxon to its parent's child map\r
-               Set<Taxon> parentChildren = getTaxonomicChildrenMap().get(parentTaxon);\r
-               if (parentChildren == null) {\r
-                       parentChildren = new HashSet<Taxon>();\r
-                       getTaxonomicChildrenMap().put(parentTaxon, parentChildren);\r
+               getSessionTaxonomicChildren(parentTaxon).add(taxon);\r
+                               \r
+               if (taxonomicTreeView != null) {\r
+               \r
+                       UiUtil.getTreeViewer().remove(taxon);\r
+                       \r
+                       if (parentTaxon == null) {\r
+                               logger.warn("Resetting input");\r
+                               UiUtil.getTreeViewer().setInput(getSessionRootTaxa());\r
+                       } else {\r
+                               UiUtil.getTreeViewer().add(parentTaxon, taxon);                 \r
+                       }\r
+               \r
                }\r
-               parentChildren.add(taxon);\r
-       }       \r
+       }\r
+\r
+       \r
+       private TaxonomicTreeView taxonomicTreeView;\r
+       \r
+       public void setTaxonomicTree(TaxonomicTreeView taxonomicTreeView) {\r
+               this.taxonomicTreeView = taxonomicTreeView;\r
+       }\r
        \r
        /***************************************************************************\r
         * RANKS\r