fixes #805 and started to work on #835
authorn.hoffmann <n.hoffmann@localhost>
Tue, 7 Jul 2009 12:16:57 +0000 (12:16 +0000)
committern.hoffmann <n.hoffmann@localhost>
Tue, 7 Jul 2009 12:16:57 +0000 (12:16 +0000)
20 files changed:
.gitattributes
taxeditor-editor/plugin.xml
taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/DuplicateArbitrator.java [new file with mode: 0644]
taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/MultiPageTaxonEditor.java
taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/MultiPageTaxonEditorAdapterFactory.java [new file with mode: 0644]
taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/name/NameComposite.java
taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/name/TaxonNameEditor.java
taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/name/TaxonSearchDialog.java
taxeditor-store/plugin.xml
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/datasource/CdmDataSourceRepository.java
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/datasource/ChooseDatasourceDialog.java [new file with mode: 0644]
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/dialogs/LoginDialog.java
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/TaxeditorLoginModule.java [deleted file]
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/CdmStore.java
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/LoginManager.java [new file with mode: 0644]
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/StoreUtil.java
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/user/AuthenticatedUserBar.java
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/user/view/UserManagerLabelProvider.java
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/user/wizard/UserWizard.java
taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/user/wizard/UserWizardPage.java

index 88760cf6ad171928a640404e806a233ef2a75435..cda63a367453c01b5e860f0fdabfc736fd5c8116 100644 (file)
@@ -683,6 +683,7 @@ taxeditor-editor/plugin.xml -text
 taxeditor-editor/pom.xml -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/AbstractTaxonEditor.java -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/CompositeBorderDecorator.java -text
+taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/DuplicateArbitrator.java -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/EditorUtil.java -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/ErrorAnnotation.java -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/FreeTextElementFactory.java -text
@@ -695,6 +696,7 @@ taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/LineBreakListener.j
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/LineWrapSquigglesStrategy.java -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/LineWrapSupport.java -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/MultiPageTaxonEditor.java -text
+taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/MultiPageTaxonEditorAdapterFactory.java -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/MultiPageTaxonEditorDataChangeBehaviour.java -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/Page.java -text
 taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/ParseListener.java -text
@@ -989,6 +991,7 @@ taxeditor-store/icons/warn_tsk.gif -text
 taxeditor-store/plugin.xml -text
 taxeditor-store/pom.xml -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/datasource/CdmDataSourceRepository.java -text
+taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/datasource/ChooseDatasourceDialog.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/datasource/handler/AbstractDataSourceHandler.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/datasource/handler/ChangeConnectionHandler.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/datasource/handler/CreateDataSourceHandler.java -text
@@ -1036,7 +1039,6 @@ taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/ImagesHelper.java -te
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/NameHelper.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/Resources.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/SynonymHelper.java -text
-taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/TaxeditorLoginModule.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/TaxonHelper.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/TaxonTransfer.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/TimeHelper.java -text
@@ -1089,6 +1091,7 @@ taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/preference/wizards/FeatureW
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/preference/wizards/FeatureWizardEditPage.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/preference/wizards/FeatureWizardPage.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/CdmStore.java -text
+taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/LoginManager.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/StoreUtil.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/VocabularyStore.java -text
 taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/internal/TaxeditorStorePlugin.java -text
index c248fd3bf4232941365c55c508b63a4507cb874c..4c00d264b5e90ceb6c34ea9b5409de5ea79012ff 100644 (file)
             type="eu.etaxonomy.taxeditor.propertysheet.name.SynonymPropertySource">
       </propertyTester>
    </extension>
+      <extension
+            point="org.eclipse.core.runtime.adapters">
+         <factory
+               adaptableType="eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor"
+               class="eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditorAdapterFactory">
+            <adapter
+                  type="eu.etaxonomy.taxeditor.editor.DuplicateArbitrator">
+            </adapter>
+         </factory>
+      </extension>
 </plugin>
diff --git a/taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/DuplicateArbitrator.java b/taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/DuplicateArbitrator.java
new file mode 100644 (file)
index 0000000..866f942
--- /dev/null
@@ -0,0 +1,166 @@
+/**
+* Copyright (C) 2007 EDIT
+* European Distributed Institute of Taxonomy 
+* http://www.e-taxonomy.eu
+* 
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+
+package eu.etaxonomy.taxeditor.editor;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.model.name.NonViralName;
+import eu.etaxonomy.cdm.model.name.TaxonNameBase;
+import eu.etaxonomy.cdm.model.reference.ReferenceBase;
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;
+import eu.etaxonomy.taxeditor.editor.name.NameComposite;
+import eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+
+/**
+ * This class is supposed to handle possible duplications of cdm entities
+ * for a specific editor
+ * 
+ * TODO break dependency to editor
+ * 
+ * @author n.hoffmann
+ * @created 03.07.2009
+ * @version 1.0
+ *
+ */
+public class DuplicateArbitrator {
+       private static final Logger logger = Logger.getLogger(DuplicateArbitrator.class);
+       
+       /**
+        * The editor this arbitrator should manage possible duplicates for
+        */
+       private MultiPageTaxonEditor editor;
+       private TaxonNameEditor nameEditor;
+       private Set<NameComposite<TaxonBase>> dirtyNames;
+       
+       private Map<TaxonBase, ReferenceBase> duplicateReferences;
+
+       private Map<TaxonBase, TaxonNameBase> duplicateNames;
+
+       /**
+        * @param adaptableObject
+        */
+       public DuplicateArbitrator(MultiPageTaxonEditor editor) {
+               this.editor = editor;
+               
+               nameEditor = (TaxonNameEditor) editor.getPage(Page.NAME);
+               
+               duplicateReferences = new HashMap<TaxonBase, ReferenceBase>();
+               duplicateNames = new HashMap<TaxonBase, TaxonNameBase>();
+       }
+
+       /**
+        * Provide strategies on how to handle possible duplications
+        */
+       public void arbitrate() {
+               // iterate over all names that were edited
+               for(NameComposite composite : nameEditor.getDirtyNames()){
+                       logger.warn("Found " + composite + " with possible duplicates");
+                       
+                       // since we are dealing with NameComposites getData should always return a TaxonBase
+                       // also we do not want to handle viral names at the moment
+//                     NonViralName name = (NonViralName) ((TaxonBase) composite.getData()).getName();
+                       
+                       TaxonBase taxonBase = HibernateProxyHelper.deproxy(composite.getData(), TaxonBase.class);
+                       
+                       // TODO decide what entities are candidates for duplicate detection
+                       checkDuplicateLatinNames(taxonBase);
+                       checkDuplicateAuthors(taxonBase);
+                       checkDuplicateNomenclaturalReference(taxonBase);
+                       
+                       
+               }
+               
+               solveDuplicates();
+               
+       }
+
+       /**
+        * Provides strategies to solve found duplicates
+        * This can either happen automatically or through user input
+        */
+       private void solveDuplicates() {
+               /* 
+                * TODO first idea that comes to mind would be to present the user 
+                * a dialog with all possible duplicates and let her mark which entities 
+                * she wants to use
+                * 
+                * If we have sophisticated equals methods that guarantee full equality and 
+                * there is only one match of an entity we might want to resolve the duplication
+                * automatically.  
+                */             
+               
+               // debug
+               for(ReferenceBase reference : duplicateReferences.values()){
+                       logger.warn(reference);
+               }
+               for(TaxonNameBase name : duplicateNames.values()){
+                       logger.warn(name);
+               }
+               
+       }
+
+       /**
+        * @param name
+        */
+       private void checkDuplicateNomenclaturalReference(TaxonBase taxonBase) {
+               
+               NonViralName name = getName(taxonBase);
+               
+               ReferenceBase referenceBase = name.getNomenclaturalReference();
+               
+               // query datasource for the reference
+               List<ReferenceBase> result = CdmStore.getReferenceService().getReferencesByTitle(referenceBase.getTitleCache());
+               
+               // if query delivers results, place possible duplicate in map
+               for(ReferenceBase duplicateReference : result){
+                       duplicateReferences.put(taxonBase, duplicateReference);
+               }
+               
+       }
+
+       /**
+        * @param name
+        */
+       private void checkDuplicateAuthors(TaxonBase taxonBase) {
+               // see checkDuplicateNomenclaturalReference for implementation
+       }
+
+       /**
+        * @param name
+        */
+       private void checkDuplicateLatinNames(TaxonBase taxonBase) {
+               NonViralName name = getName(taxonBase);
+               
+               List<NonViralName> result = CdmStore.getNameService().findNamesByTitle(name.getTitleCache());
+               
+               for(Object object: result ){
+                       TaxonNameBase duplicateName = HibernateProxyHelper.deproxy(object, TaxonNameBase.class);
+                       duplicateNames.put(taxonBase, duplicateName);
+               }
+       }
+       
+       /**
+        * Helper method to get the NonViralName of a taxon base.
+        * 
+        * @param taxonBase
+        * @return
+        */
+       private NonViralName getName(TaxonBase taxonBase){
+               return HibernateProxyHelper.deproxy(taxonBase.getName(), NonViralName.class);
+       }
+
+}
index 286baaba891f4f225ded3d06564a14bbc5298aec..afadeb49554f10fbd6b16e54274a85a129307d40 100644 (file)
@@ -102,6 +102,14 @@ public class MultiPageTaxonEditor extends MultiPageEditorPart implements IConver
        @Override\r
        public void doSave(IProgressMonitor monitor) {\r
 \r
+               //handle existing names and authors\r
+               DuplicateArbitrator duplicateArbitrator = (DuplicateArbitrator) getAdapter(DuplicateArbitrator.class);\r
+               \r
+               if(duplicateArbitrator != null){\r
+                       duplicateArbitrator.arbitrate();\r
+               }\r
+               \r
+               \r
                if( ! conversation.isBound()){\r
                        conversation.bind();\r
                }\r
diff --git a/taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/MultiPageTaxonEditorAdapterFactory.java b/taxeditor-editor/src/main/java/eu/etaxonomy/taxeditor/editor/MultiPageTaxonEditorAdapterFactory.java
new file mode 100644 (file)
index 0000000..90b8d6a
--- /dev/null
@@ -0,0 +1,35 @@
+/**
+ * 
+ */
+package eu.etaxonomy.taxeditor.editor;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+
+/**
+ * @author n.hoffmann
+ *
+ */
+public class MultiPageTaxonEditorAdapterFactory implements IAdapterFactory {
+
+       /* (non-Javadoc)
+        * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+        */
+       public Object getAdapter(Object adaptableObject, Class adapterType) {
+               
+               if((adaptableObject instanceof MultiPageTaxonEditor)  && adapterType.equals(DuplicateArbitrator.class)){
+                       return new DuplicateArbitrator((MultiPageTaxonEditor) adaptableObject);
+               }
+               
+               return null;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+        */
+       public Class[] getAdapterList() {
+               return new Class[]{
+                               DuplicateArbitrator.class
+               };
+       }
+
+}
index 418fb3b53e2a204dac1b3b2aac27154fadee3c53..3264e1398ea6da98457cbcfc13421424a4261b7c 100644 (file)
@@ -116,6 +116,12 @@ public abstract class NameComposite<T extends TaxonBase> extends GroupedComposit
        private boolean isUseParser = false;\r
 \r
        protected boolean isParsing;\r
+       \r
+       /**\r
+        * Whether this NameComposite has unsaved changes \r
+        */\r
+       private boolean isDirty = false;\r
+       \r
        private T taxonBase;\r
        \r
        /**\r
@@ -225,7 +231,7 @@ public abstract class NameComposite<T extends TaxonBase> extends GroupedComposit
                }\r
 \r
                // Any entry of text means the taxon has been changed\r
-               setDirty(true);\r
+               setDirty();\r
                \r
                // The parser is no longer active\r
                isParsing = false;\r
@@ -298,12 +304,14 @@ public abstract class NameComposite<T extends TaxonBase> extends GroupedComposit
        }       \r
        \r
        public boolean isDirty(){\r
-               \r
-               TaxonNameBase<?, ?> name = getName();\r
-               \r
-               \r
-               \r
-               return false;\r
+               return isDirty;\r
+       }\r
+       \r
+       protected void setDirty(){\r
+               // propagate to editor\r
+               super.setDirty(true);\r
+               // set the dirty state for this composite\r
+               isDirty = true;\r
        }\r
 \r
        /**\r
index 0e6533fcc7acd23511ebc1de5b24a5c7158a684a..062d1eedb6156515f79a210fccee1848d4ce25e5 100644 (file)
@@ -12,6 +12,7 @@ package eu.etaxonomy.taxeditor.editor.name;
 import java.beans.PropertyChangeEvent;\r
 import java.beans.PropertyChangeListener;\r
 import java.util.HashMap;\r
+import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.Set;\r
@@ -37,6 +38,7 @@ import org.eclipse.ui.forms.widgets.FormToolkit;
 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;\r
 import eu.etaxonomy.cdm.model.taxon.Synonym;\r
 import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
 import eu.etaxonomy.taxeditor.editor.AbstractTaxonEditor;\r
@@ -61,7 +63,6 @@ public class TaxonNameEditor extends AbstractTaxonEditor
                \r
        private static final String ID = "eu.etaxonomy.taxeditor.taxonNameEditor";\r
 \r
-       \r
        public TaxonNameEditor(MultiPageTaxonEditor editor){\r
                super(editor);\r
        }\r
@@ -319,6 +320,20 @@ public class TaxonNameEditor extends AbstractTaxonEditor
                return TaxonNameEditor.ID;\r
        }\r
        \r
+       /**\r
+        * @return a Set containing all composites that have been edited\r
+        */\r
+       public Set<NameComposite<TaxonBase>> getDirtyNames(){\r
+               Set<NameComposite<TaxonBase>> dirtyNames = new HashSet<NameComposite<TaxonBase>>();\r
+               \r
+               for(GroupedComposite composite : getGroupedComposites()){\r
+                       if(composite instanceof NameComposite && ((NameComposite)composite).isDirty()){\r
+                               dirtyNames.add((NameComposite) composite);\r
+                       }\r
+               }\r
+               \r
+               return dirtyNames;\r
+       }\r
        \r
        /***********************************************************************/\r
        \r
index 1e732a92bd92f4660dca1c7d0cfebdc17f4d7301..126d307609e5490a0828eb984c7c51a5b839aee4 100644 (file)
@@ -24,7 +24,7 @@ import eu.etaxonomy.taxeditor.store.CdmStore;
  */\r
 public class TaxonSearchDialog extends NameSearchDialog {\r
        \r
-       protected String dialogTitle = "Search for a taxib in datasource";\r
+       protected String dialogTitle = "Search for a taxon in datasource";\r
        protected String dialogMessage = "Enter a search term for a taxon, using '*' as a wildcard.";\r
 \r
        private Taxon taxon;\r
index 65c6d83057cb3a1f9dafabe46b4c0bc6a00d6129..7abec9746ed5c25f66097e65d7f35078ceac3494 100644 (file)
          </command>
       </menuContribution>
       <menuContribution
-            locationURI="DISABLEDtoolbar:org.eclipse.ui.main.toolbar">
+            locationURI="toolbar:org.eclipse.ui.trim.status">
          <toolbar
-               id="eu.etaxonomy.taxeditor.store.authentication.toolbar">
+               id="eu.etaxonomy.taxeditor.store.authentication.trim.toolbar">
             <control
                   class="eu.etaxonomy.taxeditor.user.AuthenticatedUserBar">
             </control>
index 4488d294fcdeadfb75db04ef377989cd68f81a71..8b90fca9f4cc33c4ccb300f2899bafdf3abe53a9 100644 (file)
@@ -47,25 +47,12 @@ public class CdmDataSourceRepository{
        private static ICdmDataSource currentDataSource;\r
        private static CdmDataSourceRepository repository;\r
        private XMLMemento memento;\r
-       private String currentDataSourceName;\r
+       private String lastUsedDataSourceName;\r
        \r
        public CdmDataSourceRepository(){\r
 \r
-               \r
                memento = readMemento();                \r
-               \r
-               \r
-               try {\r
-                       currentDataSourceName = memento != null ? memento.getString(CURRENT_DATASOURCE) : DEFAULT_DATASOURCE_NAME;\r
-                       currentDataSource = CdmPersistentDataSource.NewInstance(currentDataSourceName);\r
-               } catch (DataSourceNotFoundException e) {\r
-                       // fallback creates a new default\r
-                       ICdmDataSource h2DataSource = CdmDataSource.NewH2EmbeddedInstance(\r
-                                       DEFAULT_DATASOURCE_NAME, "sa", "");\r
-                       save(h2DataSource.getName(), h2DataSource);\r
-                       setCurrentDataSource(h2DataSource);\r
-               }\r
-               \r
+               lastUsedDataSourceName = memento != null ? memento.getString(CURRENT_DATASOURCE) : DEFAULT_DATASOURCE_NAME;             \r
        }\r
        \r
        public static CdmDataSourceRepository getDefault() {\r
@@ -91,15 +78,38 @@ public class CdmDataSourceRepository{
                return dataSources;\r
        }\r
                \r
-       \r
+       /**\r
+        * \r
+        * @return\r
+        */\r
        public ICdmDataSource getCurrentDataSource() {\r
                if (currentDataSource == null) {\r
-                       throw new IllegalStateException("Current data source not set.");\r
+                       try {\r
+                               currentDataSource = CdmPersistentDataSource.NewInstance(lastUsedDataSourceName);\r
+                       } catch (DataSourceNotFoundException e) {\r
+                               // fallback creates a new default\r
+                               ICdmDataSource h2DataSource = CdmDataSource.NewH2EmbeddedInstance(\r
+                                               DEFAULT_DATASOURCE_NAME, "sa", "");\r
+                               save(h2DataSource.getName(), h2DataSource);\r
+                               setCurrentDataSource(h2DataSource);\r
+                       }\r
                }\r
                return currentDataSource;\r
        }\r
 \r
+\r
+       /**\r
+        * @return the last used DataSource\r
+        */\r
+       public String getLastUsedDataSourceName() {\r
+               return lastUsedDataSourceName;\r
+       }\r
        \r
+       /**\r
+        * \r
+        * @param dataSource\r
+        * @return\r
+        */\r
        public boolean setCurrentDataSource(ICdmDataSource dataSource) {\r
                if (currentDataSource != null) {\r
                        if (!changeDataSource(dataSource)) {\r
@@ -110,6 +120,11 @@ public class CdmDataSourceRepository{
                return true;\r
        }       \r
                \r
+       /**\r
+        * \r
+        * @param dataSource\r
+        * @return\r
+        */\r
        private boolean changeDataSource(final ICdmDataSource dataSource) {\r
 \r
                // TODO Close all open editors before showing progress monitor\r
@@ -247,6 +262,5 @@ public class CdmDataSourceRepository{
 \r
                // Success !\r
                return true;\r
-       }\r
-       \r
+       }       \r
 }
\ No newline at end of file
diff --git a/taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/datasource/ChooseDatasourceDialog.java b/taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/datasource/ChooseDatasourceDialog.java
new file mode 100644 (file)
index 0000000..37627e9
--- /dev/null
@@ -0,0 +1,151 @@
+// $Id$
+/**
+* Copyright (C) 2007 EDIT
+* European Distributed Institute of Taxonomy 
+* http://www.e-taxonomy.eu
+* 
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+
+package eu.etaxonomy.taxeditor.datasource;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+import eu.etaxonomy.cdm.database.ICdmDataSource;
+
+/**
+ * @author n.hoffmann
+ * @created 06.07.2009
+ * @version 1.0
+ */
+public class ChooseDatasourceDialog extends Dialog {
+
+
+       private static final Logger logger = Logger
+                       .getLogger(ChooseDatasourceDialog.class);
+       private Combo combo_dataSources;
+       private int selection;
+       private String title;
+       private String message;
+       private List<ICdmDataSource> dataSources;
+       private Button okButton;
+       
+       /**
+        * @param parentShell
+        */
+       public ChooseDatasourceDialog(Shell parentShell) {
+               super(parentShell);
+               title = "Choose Datasource";
+               message = "Choose a data source to connect to. Cancel will close the editor again.";
+               
+               dataSources = CdmDataSourceRepository.getDefault().getAll();    
+               
+               selection = -1;
+               String lastUsedDataSourceName = CdmDataSourceRepository.getDefault().getLastUsedDataSourceName();
+               for(ICdmDataSource dataSource : dataSources){
+                       selection++;
+                       if(dataSource.getName().equals(lastUsedDataSourceName)){
+                               break;
+                       }
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+        */
+       @Override
+       protected Control createDialogArea(Composite parent) {
+               
+        // create composite
+        Composite composite = (Composite) super.createDialogArea(parent);
+        // create message
+        if (message != null) {
+            Label label = new Label(composite, SWT.WRAP);
+            label.setText(message);
+            GridData data = new GridData(GridData.GRAB_HORIZONTAL
+                    | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
+                    | GridData.VERTICAL_ALIGN_CENTER);
+            data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
+            label.setLayoutData(data);
+            label.setFont(parent.getFont());
+        }
+        
+               combo_dataSources = new Combo(composite, SWT.DROP_DOWN);
+               combo_dataSources.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
+                | GridData.HORIZONTAL_ALIGN_FILL));
+               int i = 0;
+               
+               for (ICdmDataSource dataSource : dataSources){
+                       combo_dataSources.add(dataSource.getName() + " - " + dataSource.getServer() + ", " + dataSource.getDatabase() , i++);
+               }
+               
+               combo_dataSources.addSelectionListener(new SelectionAdapter(){
+
+                       /* (non-Javadoc)
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+                        */
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               selection = combo_dataSources.getSelectionIndex();
+                       }                       
+               });
+               
+               combo_dataSources.select(selection);
+               
+        applyDialogFont(composite);
+        return composite;
+       }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
+     */
+    protected void createButtonsForButtonBar(Composite parent) {
+        // create OK and Cancel buttons by default
+        okButton = createButton(parent, IDialogConstants.OK_ID,
+                IDialogConstants.OK_LABEL, true);
+        createButton(parent, IDialogConstants.CANCEL_ID,
+                IDialogConstants.CANCEL_LABEL, false);
+        //do this here because setting the text will set enablement on the ok
+        // button
+        combo_dataSources.setFocus();
+    }
+       
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+     */
+    protected void configureShell(Shell shell) {
+        super.configureShell(shell);
+        if (title != null) {
+                       shell.setText(title);
+               }
+    }
+    
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+        */
+       @Override
+       protected void okPressed() {
+               super.okPressed();
+               ICdmDataSource chosenDataSource = dataSources.get(selection);           
+               CdmDataSourceRepository.getDefault().setCurrentDataSource(chosenDataSource);
+       }
+}
index 115ace77c0ea8b483aeb4bccad45e9dbba46e412..01bbf5ed6188337a3b9ee595930269e00836b050 100644 (file)
@@ -96,7 +96,7 @@ public class LoginDialog extends Dialog {
                UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); 
                
                try{
-                       CdmStore.authenticate(token);                   
+                       CdmStore.getLoginManager().authenticate(token);                 
                }catch(BadCredentialsException e){
                        logger.error("Bad credentials", e);
                        StoreUtil.warningDialog("Could not authenticate. Reason: Bad Credentials");
diff --git a/taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/TaxeditorLoginModule.java b/taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/model/TaxeditorLoginModule.java
deleted file mode 100644 (file)
index f8c89f6..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-// $Id$
-/**
-* Copyright (C) 2007 EDIT
-* European Distributed Institute of Taxonomy 
-* http://www.e-taxonomy.eu
-* 
-* The contents of this file are subject to the Mozilla Public License Version 1.1
-* See LICENSE.TXT at the top of this package for the full license terms.
-*/
-
-package eu.etaxonomy.taxeditor.model;
-
-import java.util.Map;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-
-import org.apache.log4j.Logger;
-
-/**
- * @author n.hoffmann
- * @created 01.07.2009
- * @version 1.0
- */
-public class TaxeditorLoginModule implements LoginModule {
-       private static final Logger logger = Logger
-                       .getLogger(TaxeditorLoginModule.class);
-
-       /* (non-Javadoc)
-        * @see javax.security.auth.spi.LoginModule#abort()
-        */
-       public boolean abort() throws LoginException {
-               // TODO Auto-generated method stub
-               return false;
-       }
-
-       /* (non-Javadoc)
-        * @see javax.security.auth.spi.LoginModule#commit()
-        */
-       public boolean commit() throws LoginException {
-               // TODO Auto-generated method stub
-               return false;
-       }
-
-       /* (non-Javadoc)
-        * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
-        */
-       public void initialize(Subject subject, CallbackHandler callbackHandler,
-                       Map<String, ?> sharedState, Map<String, ?> options) {
-               // TODO Auto-generated method stub
-
-       }
-
-       /* (non-Javadoc)
-        * @see javax.security.auth.spi.LoginModule#login()
-        */
-       public boolean login() throws LoginException {
-               
-//             Shell shell = TaxeditorStorePlugin.getDefault().getWorkbench()
-//             .getActiveWorkbenchWindow().getShell();
-//
-//             LoginDialog loginDialog = new LoginDialog(shell);
-//             token = loginDialog.open();
-//             
-//             Authentication authentication = CdmStore.getAuthenticationManager().authenticate(token);
-//             SecurityContextHolder.getContext().setAuthentication(authentication);
-//             
-               return false;
-       }
-
-       /* (non-Javadoc)
-        * @see javax.security.auth.spi.LoginModule#logout()
-        */
-       public boolean logout() throws LoginException {
-               // TODO Auto-generated method stub
-               return false;
-       }
-}
index e9abec031477e0d1329f0d26dd1f16acab12351d..77d7d858d5e76cc699ab61abbb26dad42dbd0aa1 100644 (file)
@@ -14,9 +14,8 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.UUID;
 
-import javax.security.auth.spi.LoginModule;
-
 import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.Status;
 import org.springframework.security.Authentication;
 import org.springframework.security.context.SecurityContextHolder;
 import org.springframework.security.providers.ProviderManager;
@@ -46,8 +45,7 @@ import eu.etaxonomy.cdm.model.taxon.Taxon;
 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
 import eu.etaxonomy.cdm.persistence.query.MatchMode;
 import eu.etaxonomy.taxeditor.datasource.CdmDataSourceRepository;
-import eu.etaxonomy.taxeditor.model.TaxeditorLoginModule;
-import eu.etaxonomy.taxeditor.user.AuthenticatedUserBar;
+import eu.etaxonomy.taxeditor.datasource.ChooseDatasourceDialog;
 
 /**
  * This implementation of ICdmDataRepository depends on hibernate sessions to store the data correctly 
@@ -76,7 +74,7 @@ public class CdmStore{
        
        private static DbSchemaValidation dbSchemaValidation;
 
-       private static LoginModule loginModule;
+       private static LoginManager loginManager;
        
        /**
         * 
@@ -94,15 +92,37 @@ public class CdmStore{
        public static CdmStore getDefault(String applicationContextBean){
                if(instance == null){
                        logger.info("Initializing application context ...");
-                       ICdmDataSource cdmDatasource = CdmDataSourceRepository.getDefault().
-                                       getCurrentDataSource();
-                       
-                       instance = new CdmStore(cdmDatasource, getDbSchemaValidation(), applicationContextBean);
                        
-                       logger.info("Application context initialized.");
+                       // Prompt user for datasource if there are more than one
+                       if(CdmDataSourceRepository.getDefault().getAll().size() > 1){
+                               ChooseDatasourceDialog chooseDataSource = new ChooseDatasourceDialog(StoreUtil.getShell());
+                               if(chooseDataSource.open() == Status.OK){
+                                       initialize(applicationContextBean);
+
+                               }else{
+                                       // no datasource chosen.
+                                       logger.warn("No datasource chosen. Exiting now.");
+                                       System.exit(1);
+                               }       
+                       }else{
+                               // Start default cdm database
+                               initialize(applicationContextBean);
+                       }
+               
                }
                return instance;
        }
+       
+       private static CdmStore initialize(String applicationContextBean){      
+               
+               ICdmDataSource cdmDatasource = CdmDataSourceRepository.getDefault().getCurrentDataSource();
+               
+               CdmStore instance = new CdmStore(cdmDatasource, getDbSchemaValidation(), applicationContextBean);
+               
+               logger.info("Application context initialized.");
+               
+               return instance;
+       }
 
        /**
         * @return
@@ -311,38 +331,14 @@ public class CdmStore{
                
                return nomReferenceTypeMap;
        }
-
-       /**
-        * TODO implement LoginModule to handle the whole login stuff
-        * 
-        * @param token
-        */
-       public static void authenticate(UsernamePasswordAuthenticationToken token){
-               Authentication authentication = CdmStore.getAuthenticationManager().authenticate(token);
-               SecurityContextHolder.getContext().setAuthentication(authentication);
-               
-               // TODO register a listener on LoginModule instead of calling a set method here
-//             AuthenticatedUserBar.setAuthenticatedUser(getAuthenticatedUser().getUsername());
-       }
-       
-       public static User getAuthenticatedUser(){
-               Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-               
-               if(authentication != null 
-                               && authentication.getPrincipal() != null 
-                               && authentication.getPrincipal() instanceof User){
-                       return (User)authentication.getPrincipal();
-               }
-               return null;
-       }
        
        /**
         * incomplete! do note use!
         */
-       public static LoginModule getLoginModule(){
-               if(loginModule == null){
-                       loginModule = new TaxeditorLoginModule();
+       public static LoginManager getLoginManager(){
+               if(loginManager == null){
+                       loginManager = new LoginManager();
                }
-               return loginModule;
+               return loginManager;
        }
 }
diff --git a/taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/LoginManager.java b/taxeditor-store/src/main/java/eu/etaxonomy/taxeditor/store/LoginManager.java
new file mode 100644 (file)
index 0000000..beb1adb
--- /dev/null
@@ -0,0 +1,55 @@
+// $Id$
+/**
+* Copyright (C) 2007 EDIT
+* European Distributed Institute of Taxonomy 
+* http://www.e-taxonomy.eu
+* 
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+
+package eu.etaxonomy.taxeditor.store;
+
+import java.util.Observable;
+
+import org.apache.log4j.Logger;
+import org.springframework.security.Authentication;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
+
+import eu.etaxonomy.cdm.model.common.User;
+
+/**
+ * @author n.hoffmann
+ * @created 03.07.2009
+ * @version 1.0
+ */
+public class LoginManager extends Observable{
+       private static final Logger logger = Logger.getLogger(LoginManager.class);
+       
+       /**
+        * @param token
+        */
+       public void authenticate(UsernamePasswordAuthenticationToken token){
+               Authentication authentication = CdmStore.getAuthenticationManager().authenticate(token);
+               SecurityContextHolder.getContext().setAuthentication(authentication);
+               
+               this.setChanged();
+               this.notifyObservers();
+       }
+       
+       /**
+        * 
+        * @return
+        */
+       public User getAuthenticatedUser(){
+               Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+               
+               if(authentication != null 
+                               && authentication.getPrincipal() != null 
+                               && authentication.getPrincipal() instanceof User){
+                       return (User)authentication.getPrincipal();
+               }
+               return null;
+       }
+}
index a09cbd8d97b64782c7b4c7a58338353617db29e2..c57534ae64bee3b1e7b45c45e0bb6838fd2ad3bb 100644 (file)
@@ -46,4 +46,6 @@ public class StoreUtil extends AbstractUtility {
        public static IUndoContext getUndoContext(){
                return IOperationHistory.GLOBAL_UNDO_CONTEXT;
        }
+       
+       
 }
index 5cd128a5c38e2259cd1c2d7578d62dfd8e5654b1..3a7224fa983fbf0ac9c31d0ca7fe48500f23320e 100644 (file)
 
 package eu.etaxonomy.taxeditor.user;
 
-import org.apache.log4j.Logger;
-import org.eclipse.jface.viewers.CellEditor.LayoutData;
+import java.util.Observable;
+import java.util.Observer;
+
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
 
+import eu.etaxonomy.cdm.model.common.User;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+
 /**
+ * Shows the currently logged in user in status bar
+ * 
  * @author n.hoffmann
  * @created 01.07.2009
  * @version 1.0
  */
-public class AuthenticatedUserBar extends WorkbenchWindowControlContribution {
-       private static final Logger logger = Logger
-                       .getLogger(AuthenticatedUserBar.class);
-       
-       private static CLabel label_authenticatedUser;
+public class AuthenticatedUserBar extends WorkbenchWindowControlContribution implements Observer{
 
-       private Composite composite;
+       private Label label_authenticatedUser;
 
+       public AuthenticatedUserBar(){
+               CdmStore.getLoginManager().addObserver(this);
+       }
+       
        /* (non-Javadoc)
         * @see org.eclipse.jface.action.ControlContribution#createControl(org.eclipse.swt.widgets.Composite)
         */
        @Override
        protected Control createControl(Composite parent) {
-               composite = new Composite(parent, SWT.NONE);
-               GridLayout layout = new GridLayout();
-               layout.numColumns = 2;
+               final Composite composite = new Composite(parent, SWT.NONE);
+               final GridLayout layout = new GridLayout();
                composite.setLayout(layout);
                
-               CLabel label = new CLabel(composite, SWT.NULL);
-               label.setText("Authenticated as: ");
-               
-               label_authenticatedUser = new CLabel(composite, SWT.NULL);
-               LayoutData layoutData = new LayoutData();
-//             layoutData.minimumWidth = 30;
-               label_authenticatedUser.setLayoutData(layoutData);
+               label_authenticatedUser = new Label(composite, SWT.NULL);
+
+               update(null, null);
+                       
                return composite;
        }
-       
-       /**
-        * TODO implement a LoginModule and register as a listener there
-        * 
-        * @param username
+
+       /* (non-Javadoc)
+        * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
         */
-       public static void setAuthenticatedUser(String username){
-               label_authenticatedUser.setText(username);
+       public void update(Observable o, Object arg) {
+               User authenticatedUser = CdmStore.getLoginManager().getAuthenticatedUser();
+               // TODO find a method to recompute width for parental toolbar item
+               String text = authenticatedUser == null ? "Not logged in              " : 
+                                                                                                 "Logged in as: " + authenticatedUser.getUsername() + "         ";     
+               label_authenticatedUser.setText(text);
        }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.action.ContributionItem#dispose()
+        */
+       @Override
+       public void dispose() {
+               super.dispose();
+               
+               CdmStore.getLoginManager().deleteObserver(this);
+       }
+       
+       
+
 }
index 0ed46d6a0617f008622c3a26bb1138a73de01993..ed8259fb869c21757d711f4936c2bd1bc2fac3e9 100644 (file)
@@ -33,7 +33,7 @@ public class UserManagerLabelProvider extends LabelProvider {
        public String getText(Object element) {
                User user = (User) element;
                
-               User authenticatedUser = CdmStore.getAuthenticatedUser();
+               User authenticatedUser = CdmStore.getLoginManager().getAuthenticatedUser();
                
                return user.equals(authenticatedUser) ? "* " + user.getUsername() : user.getUsername();
        }
index 5e2e4974e029b82ca65d3f6d6752ef624a5e3db2..7f3cf9f8c138c7626b931a5eb7ba56b177b8741f 100644 (file)
@@ -57,7 +57,7 @@ public class UserWizard extends Wizard {
        @Override
        public boolean performFinish() {
                
-               CdmStore.getUserService().saveOrUpdate(page.getUser());
+               CdmStore.getUserService().save(page.getUser());
                view.getConversationHolder().commit(true);
                
                return view.postOperation(user);
index 367b58c0e35b8828c3b328683fc453a72a945ecb..f432f4658a08f52d7a248027eb621f4251888e9b 100644 (file)
@@ -92,7 +92,7 @@ public class UserWizardPage extends WizardPage implements ModifyListener{
                
                if(newMode){
                        createPasswordFieldsNew(composite);
-               }else if(CdmStore.getAuthenticatedUser().equals(user)){
+               }else if(CdmStore.getLoginManager().getAuthenticatedUser().equals(user)){
                        createPasswordFieldsEdit(composite);
                }