Merge branch 'develop' into unify_derivative_views
authorPatrick Plitzner <p.plitzner@bgbm.org>
Mon, 2 Nov 2015 11:50:52 +0000 (12:50 +0100)
committerPatrick Plitzner <p.plitzner@bgbm.org>
Mon, 2 Nov 2015 13:11:21 +0000 (14:11 +0100)
Conflicts:
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/detail/DetailsViewer.java

44 files changed:
eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/preference/BulkEditorMarkerPreferencePage.java
eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteConfiguration.java
eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/CdmEntitySessionManager.java
eu.etaxonomy.taxeditor.cdmlib/src/main/resources/log4j.xml
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/name/handler/ChangeSynonymToAcceptedTaxonHandler.java
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/name/handler/MoveSynonymToAnotherAcceptedTaxonHandler.java
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/dataimport/transientServices/TransientCdmRepository.java
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/view/dataimport/transientServices/TransientClassificationService.java
eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/handler/ChangeAcceptedTaxonToSynonymHandler.java
eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/handler/RemotingChangeAcceptedTaxonToSynonymHandler.java
eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/handler/RemotingMoveFactualDataHandler.java
eu.etaxonomy.taxeditor.navigation/src/main/java/eu/etaxonomy/taxeditor/navigation/navigator/handler/RemotingMoveTaxonNodeHandler.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/io/ImportManager.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/io/wizard/AbcdImportWizard.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/io/wizard/ClassificationChooserWizardPage.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/model/AbstractUtility.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/model/CdmProgressMonitorAdapter.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/operation/FeedbackGenerator.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/operation/IFeedbackGenerator.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/operation/IPostMoniteredOperationEnabled.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/IPreferenceKeys.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/MobotOpenUrlPreferences.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/TaxonomicEditorGeneralPreferences.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/matching/AbstractMatchingPreferences.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/matching/NonViralNameMatchingPreference.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/matching/ReferenceMatchingPreference.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/matching/TeamOrPersonMatchingPreference.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/store/CdmStore.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/dialog/FeedbackMessageBox.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/dialog/RemotingLoginDialog.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/dialog/ReportTextDialog.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/element/ImageElement.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/media/ImageFileElement.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/media/MediaDetailElement.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/occurrence/association/TaxonAssociationDetailElement.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/util/ProgressMonitorClientManager.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/detail/DetailsViewer.java
eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/BaseRemotingTest.java
eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/HttpInvokerServicesTest.java
eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/RemotingSessionAwareTest.java
eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/TestThread.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/ThreadedTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/service/ProgressMonitorServiceTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/session/CdmEntitySessionAwareTest.java

index 2830dd82d6e82a8325140e7e0450403c191bec7c..b183539a5587d3b6cc34aba365a9836eadf5961c 100644 (file)
 
 package eu.etaxonomy.taxeditor.bulkeditor.preference;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.jface.preference.PreferencePage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 
 import eu.etaxonomy.cdm.model.common.MarkerType;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.store.TermStore;
 
 /**
- * <p>BulkEditorMarkerPreferenceComposite class.</p>
- *
  * @author p.ciardelli
  * @created 17.08.2009
  * @version 1.0
  */
-public class BulkEditorMarkerPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+public class BulkEditorMarkerPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
 
-       private Map<MarkerType, Boolean> markerTypeEditingMap = new HashMap<MarkerType, Boolean>();
 
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
-        */
        @Override
        public void init(IWorkbench workbench) {
                setPreferenceStore(PreferencesUtil.getPreferenceStore());
                if(!CdmStore.isActive()) {
             MessagingUtils.noDataSourceWarningDialog(null);
-               }else{
-                   markerTypeEditingMap = PreferencesUtil.getEditMarkerTypePreferences();
                }
        }
 
-       /* (non-Javadoc)
-        * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
-        */
-       @Override
-       protected Control createContents(Composite parent) {
-               Composite container = new Composite(parent, SWT.NULL);
-               container.setLayout(new GridLayout());
+    @Override
+    protected void createFieldEditors() {
         if(CdmStore.isActive()){
             for (final MarkerType markerType : TermStore.getTerms(MarkerType.class)) {
-                final Button button = new Button(container, SWT.CHECK);
-                button.setText(String.format("Edit '%s' markers", markerType.getLabel()));
-
-                button.addSelectionListener(new SelectionAdapter() {
-                    @Override
-                    public void widgetSelected(SelectionEvent e) {
-                        markerTypeEditingMap.put(markerType, button.getSelection());
-                    }
-                });
-
-                boolean edit = markerTypeEditingMap.get(markerType) == null ? true : markerTypeEditingMap.get(markerType);
-
-                button.setSelection(edit);
+                addField(new BooleanFieldEditor(IPreferenceKeys.EDIT_MARKER_TYPE_PREFIX
+                        + markerType.getClass().getName() + markerType.getLabel(), String.format("Edit '%s' markers",
+                        markerType.getLabel()), getFieldEditorParent()));
             }
         }
-               return container;
-       }
-
-       /* (non-Javadoc)
-        * @see org.eclipse.jface.preference.PreferencePage#performOk()
-        */
-       @Override
-       public boolean performOk() {
-               PreferencesUtil.setEditMarkerTypePreferences(markerTypeEditingMap);
 
-               return super.performOk();
-       }
+    }
 }
index 0de5bc0bdaea31551b0646a1f352a1e4b1e2e16a..760b71c90177843c46c732cadb24396c391b1a30 100644 (file)
@@ -56,6 +56,7 @@ import eu.etaxonomy.cdm.api.service.INameService;
 import eu.etaxonomy.cdm.api.service.IOccurrenceService;\r
 import eu.etaxonomy.cdm.api.service.IPolytomousKeyNodeService;\r
 import eu.etaxonomy.cdm.api.service.IPolytomousKeyService;\r
+import eu.etaxonomy.cdm.api.service.IProgressMonitorService;\r
 import eu.etaxonomy.cdm.api.service.IReferenceService;\r
 import eu.etaxonomy.cdm.api.service.IService;\r
 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;\r
@@ -81,6 +82,7 @@ import eu.etaxonomy.cdm.persistence.hibernate.permission.voter.TaxonBaseVoter;
 import eu.etaxonomy.cdm.persistence.hibernate.permission.voter.TaxonNodeVoter;\r
 import eu.etaxonomy.taxeditor.remoting.source.ICdmRemoteSource;\r
 import eu.etaxonomy.taxeditor.service.CachedCommonServiceImpl;\r
+import eu.etaxonomy.taxeditor.service.CdmAuthenticatedHttpInvokerRequestExecutor;\r
 import eu.etaxonomy.taxeditor.service.CdmServiceRequestExecutor;\r
 import eu.etaxonomy.taxeditor.service.ICachedCommonService;\r
 import eu.etaxonomy.taxeditor.service.TermServiceRequestExecutor;\r
@@ -123,7 +125,7 @@ public class CdmApplicationRemoteConfiguration implements ICdmApplicationConfigu
         this.remoteSource = remoteSource;\r
     }\r
 \r
-    private Object getService(Class<?> clazz, String serviceSuffix, CdmServiceRequestExecutor executor) {\r
+    private Object getService(Class<?> clazz, String serviceSuffix, CdmAuthenticatedHttpInvokerRequestExecutor executor) {\r
         if(serviceMap.containsKey(clazz)) {\r
             return serviceMap.get(clazz);\r
         }\r
@@ -361,6 +363,11 @@ public class CdmApplicationRemoteConfiguration implements ICdmApplicationConfigu
         return (IPolytomousKeyNodeService) getService(IPolytomousKeyNodeService.class, "/remoting/polytomouskeynode.service", new CdmServiceRequestExecutor());\r
     }\r
 \r
+    @Override\r
+    public IProgressMonitorService getProgressMonitorService() {\r
+        return (IProgressMonitorService) getService(IProgressMonitorService.class, "/remoting/progressmonitor.service", new CdmAuthenticatedHttpInvokerRequestExecutor());\r
+    }\r
+\r
     @Override\r
     public IWorkingSetService getWorkingSetService(){\r
         return (IWorkingSetService) getService(IWorkingSetService.class, "/remoting/workingset.service", new CdmServiceRequestExecutor());\r
index 80bc0caba5cd87406ef1ea017d416c63eaf8142a..5582df7778e457e8d27144591902fa9de0bfe464 100644 (file)
@@ -38,7 +38,9 @@ public class CdmEntitySessionManager implements ICdmEntitySessionManager {
 
     private final List<ICdmEntitySessionManagerObserver> sessionObservers = new ArrayList<ICdmEntitySessionManagerObserver>();
 
-    private ICdmEntitySession activeSession;
+    //private ICdmEntitySession activeSession;
+
+    private final InheritableThreadLocal<ICdmEntitySession> tlActiveSession = new InheritableThreadLocal<ICdmEntitySession>();
 
     private  NullSession nullSession;
 
@@ -76,11 +78,12 @@ public class CdmEntitySessionManager implements ICdmEntitySessionManager {
 
     @Override
     public ICdmEntitySession getActiveSession() {
-        return activeSession;
+        return tlActiveSession.get();
     }
 
+
     private void setActiveSession(ICdmEntitySession activeSession) {
-        this.activeSession = activeSession;
+       this. tlActiveSession.set(activeSession);
         notifyObservers();
     }
 
@@ -123,18 +126,18 @@ public class CdmEntitySessionManager implements ICdmEntitySessionManager {
      */
     @Override
     public <T extends Object> T load(T obj, boolean update) {
-        if(activeSession == null) {
+        if(tlActiveSession.get() == null) {
             return obj;
         } else {
-            return activeSession.load(obj, update);
+            return tlActiveSession.get().load(obj, update);
         }
     }
 
 
     @Override
     public <T extends CdmBase> void update() {
-        if(activeSession != null) {
-            activeSession.update();
+        if(tlActiveSession.get() != null) {
+            tlActiveSession.get().update();
         }
     }
 
@@ -143,10 +146,10 @@ public class CdmEntitySessionManager implements ICdmEntitySessionManager {
      */
     @Override
     public <T extends CdmBase> T load(T cdmBase, boolean update) {
-        if(activeSession == null) {
+        if(tlActiveSession.get() == null) {
             return cdmBase;
         }
-        return activeSession.load(cdmBase, update);
+        return tlActiveSession.get().load(cdmBase, update);
     }
 
 
@@ -155,10 +158,10 @@ public class CdmEntitySessionManager implements ICdmEntitySessionManager {
      */
     @Override
     public UpdateResult load(UpdateResult updateResult, boolean update) {
-        if(activeSession == null) {
+        if(tlActiveSession.get() == null) {
             return updateResult;
         }
-        return activeSession.load(updateResult, update);
+        return tlActiveSession.get().load(updateResult, update);
     }
 
 
@@ -167,10 +170,10 @@ public class CdmEntitySessionManager implements ICdmEntitySessionManager {
      */
     @Override
     public MergeResult load(MergeResult mergeResult, boolean update) {
-        if(activeSession == null) {
+        if(tlActiveSession.get() == null) {
             return mergeResult;
         }
-        return activeSession.load(mergeResult, update);
+        return tlActiveSession.get().load(mergeResult, update);
     }
 
 
@@ -179,10 +182,10 @@ public class CdmEntitySessionManager implements ICdmEntitySessionManager {
      */
     @Override
     public <T extends CdmBase> Collection<T> load(Collection<T> cdmBaseList, boolean update) {
-        if(activeSession == null) {
+        if(tlActiveSession.get() == null) {
             return cdmBaseList;
         }
-        return activeSession.load(cdmBaseList, update);
+        return tlActiveSession.get().load(cdmBaseList, update);
     }
 
 
@@ -195,7 +198,7 @@ public class CdmEntitySessionManager implements ICdmEntitySessionManager {
             logger.info("No Session connected to owner, nothing to do");
             return;
         }
-        if(session == activeSession) {
+        if(session == tlActiveSession.get()) {
             setActiveSession(null);
         }
         ownerSessionMap.remove(owner);
index 2c8a9f827c6f10f470e3c8bbb145505bef44b6a9..14b670b470338cb0cd25f31dfeb55ce1bfbf4d0a 100644 (file)
 <!--     name="eu.etaxonomy.taxeditor.service.CdmServiceRequestExecutor"> -->
 <!--     <level value="info" /> -->
 <!--   </logger> -->
+<!--   <logger -->
+<!--     name="eu.etaxonomy.taxeditor.session.DefaultNewEntityListener"> -->
+<!--     <level value="info" /> -->
+<!--   </logger> -->
+<!--     <logger -->
+<!--     name="eu.etaxonomy.taxeditor.util.ProgressMonitorClientManager"> -->
+<!--     <level value="info" /> -->
+<!--   </logger> -->
 </log4j:configuration>
\ No newline at end of file
index d0eca25f8ee5798022727bc76924e64fba0b9a35..c6a9a0cd843ad506a4354b548984f49fc1f9b0be 100644 (file)
@@ -10,6 +10,7 @@
 
 package eu.etaxonomy.taxeditor.editor.name.handler;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 import java.util.UUID;
@@ -87,7 +88,8 @@ public class ChangeSynonymToAcceptedTaxonHandler extends AbstractHandler impleme
 
                TaxonNode parentNode = (TaxonNode) HibernateProxyHelper.deproxy(((TaxonEditorInput) input).getTaxonNode().getParent());
 
-               List<UUID> excludeTaxa = null;
+               List<UUID> excludeTaxa = new ArrayList<UUID>();
+               excludeTaxa.add(taxon.getUuid());
 
                TaxonNode newParentNode = TaxonNodeSelectionDialog.select(HandlerUtil.getActiveShell(event), editor.getConversationHolder(), "Select parent", excludeTaxa, null, ((TaxonEditorInput) input).getTaxonNode().getClassification());
 
index b2c7b64532116f49938fa32c2d68de829fee13ce..bb5fb10aceb55dc921bf38d1c598a8bd1517afcc 100644 (file)
@@ -1,5 +1,9 @@
 package eu.etaxonomy.taxeditor.editor.name.handler;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
 import org.apache.log4j.Logger;
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
@@ -18,6 +22,7 @@ import eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor;
 import eu.etaxonomy.taxeditor.editor.TaxonEditorInput;
 import eu.etaxonomy.taxeditor.editor.name.operation.MoveSynonymToAnotherAcceptedTaxonOperation;
 import eu.etaxonomy.taxeditor.model.AbstractUtility;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
 import eu.etaxonomy.taxeditor.ui.dialog.selection.TaxonNodeSelectionDialog;
 
@@ -31,6 +36,10 @@ public class MoveSynonymToAnotherAcceptedTaxonHandler extends AbstractHandler im
                editor =  (MultiPageTaxonEditor) HandlerUtil.getActiveEditor(event);
                Shell shell = HandlerUtil.getActiveShell(event);
                IEditorInput input = editor.getEditorInput();
+               // Get synonym from selection before possible save dialog
+               // because the selection will be null if save dialog is shown
+               StructuredSelection selection = (StructuredSelection) HandlerUtil.getCurrentSelection(event);
+
                if (!EditorUtil.forceUserSave(editor, shell)) {
                        return null;
                }
@@ -40,19 +49,22 @@ public class MoveSynonymToAnotherAcceptedTaxonHandler extends AbstractHandler im
                        return null;
                }
 
-               // Get synonym from selection
-               StructuredSelection selection = (StructuredSelection) HandlerUtil.getCurrentSelection(event);
-               if (!(selection.getFirstElement() instanceof Synonym)) {
+               if (selection==null || !(selection.getFirstElement() instanceof Synonym)) {
+                   MessagingUtils.warningDialog("No selection", this, "No synonym selected");
                        logger.error("Selection does not contain a Synonym");
                        return null;
                }
 
                Synonym synonym = (Synonym) selection.getFirstElement();
-               TaxonNode newParentNode = TaxonNodeSelectionDialog.select(HandlerUtil.getActiveShell(event), editor.getConversationHolder(), "Select new accepted taxon", null, null, ((TaxonEditorInput)input).getTaxonNode().getClassification());
-               if(newParentNode!=null){
-                   Taxon oldParent = ((TaxonEditorInput)input).getTaxon();
+               Taxon oldParent = ((TaxonEditorInput)input).getTaxon();
+               List<UUID> excludeTaxa = new ArrayList<UUID>();
+               excludeTaxa.add(oldParent.getUuid());
+
+                               
+               TaxonNode newParentNode = TaxonNodeSelectionDialog.select(HandlerUtil.getActiveShell(event), editor.getConversationHolder(), "Select new accepted taxon", excludeTaxa, null, ((TaxonEditorInput)input).getTaxonNode().getClassification());
 
-                   MoveSynonymToAnotherAcceptedTaxonOperation operation = new MoveSynonymToAnotherAcceptedTaxonOperation("Change accepted Taxon of Synonym", EditorUtil.getUndoContext(),
+               if(newParentNode!=null){
+                  MoveSynonymToAnotherAcceptedTaxonOperation operation = new MoveSynonymToAnotherAcceptedTaxonOperation("Change accepted Taxon of Synonym", EditorUtil.getUndoContext(),
                            oldParent.getUuid(), synonym.getUuid(), newParentNode.getTaxon(), editor);
 
                    AbstractUtility.executeOperation(operation);
index aebdee8f95469a89c17da851e339333ae2b726eb..2a2caea5630cd36d0d2ffac97d506983a98f99fd 100644 (file)
@@ -37,6 +37,7 @@ import eu.etaxonomy.cdm.api.service.INameService;
 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
 import eu.etaxonomy.cdm.api.service.IPolytomousKeyNodeService;
 import eu.etaxonomy.cdm.api.service.IPolytomousKeyService;
+import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
 import eu.etaxonomy.cdm.api.service.IReferenceService;
 import eu.etaxonomy.cdm.api.service.IService;
 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
@@ -418,4 +419,12 @@ public class TransientCdmRepository implements ICdmApplicationConfiguration {
     public IAnnotationService getAnnotationService() {
         return defaultApplicationConfiguration.getAnnotationService();
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IProgressMonitorService getProgressMonitorService() {
+        return defaultApplicationConfiguration.getProgressMonitorService();
+    }
 }
index 624e98dc2adbe272bb4e89830764668f25889afa..5f642230a03e94c64bc1730c01cee3246cde67f6 100644 (file)
@@ -975,14 +975,13 @@ public class TransientClassificationService implements IClassificationService {
         return defaultService.loadWithUpdate(arg0);
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(UUID arg0,
-            List<UUID> arg1) {
-        return defaultService.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(arg0, arg1);
-    }
+
+       @Override
+       public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(
+                       UUID classificationUuid, List<UUID> excludeTaxa) {
+               
+               return defaultService.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(classificationUuid, excludeTaxa);
+       }
 
 
 }
index f79c91facdce45f3236ed2b7dcac8c44e80b4125..a60bd2e321a302423561dbccd02174752214d513 100644 (file)
@@ -108,7 +108,7 @@ public class ChangeAcceptedTaxonToSynonymHandler extends DeleteHandler
                                }*/
 
                                List<UUID> excludeTaxa = new ArrayList<UUID>();
-                               excludeTaxa.add(oldAcceptedTaxonNode.getUuid());
+                               excludeTaxa.add(((TaxonNode)oldAcceptedTaxonNode).getTaxon().getUuid());
                                TaxonNode newAcceptedTaxonNode = TaxonNodeSelectionDialog.select(HandlerUtil.getActiveShell(event),
                                                taxonNavigator.getConversationHolder(),
                                                "Choose the accepted taxon",
index a42c6dfb066a615ef639bff23fb4bb3c24b4de75..c4f6df32c9b70e35c86839f607bfbf87c21a834e 100644 (file)
@@ -97,7 +97,7 @@ public class RemotingChangeAcceptedTaxonToSynonymHandler extends RemotingCdmHand
     @Override
     public AbstractOperation prepareOperation(ExecutionEvent event) {
         List<UUID> excludeTaxa = new ArrayList<UUID>();
-        excludeTaxa.add(oldTaxonNode.getUuid());
+        excludeTaxa.add(((TaxonNode)oldTaxonNode).getTaxon().getUuid());
         TaxonNode newAcceptedTaxonNode = TaxonNodeSelectionDialog.select(HandlerUtil.getActiveShell(event),
                 new ConversationHolderMock(),
                 "Choose the accepted taxon",
index f0fa3d9216b6a79f22588f711f2aa27d7317c7e6..1d6b008e903e98bcc367872528fc5b4aa84df2f1 100644 (file)
@@ -96,7 +96,7 @@ public class RemotingMoveFactualDataHandler extends RemotingCdmHandler {
                 "Choose the accepted taxon",
                 excludeTaxa,
                 null,
-                null);
+                sourceTaxonNode.getClassification());
 
         if(targetTaxonNode == null) {
             return new Status(IStatus.CANCEL,
index 288211858c672f3abcccc0e1114cedf64e7fc0e2..3458faa9f8df8c1cccc9a94dfc6c92e0900dc076 100644 (file)
@@ -85,12 +85,12 @@ public class RemotingMoveTaxonNodeHandler extends RemotingCdmHandler {
         TaxonNode parentTaxonNode;
 
         List<UUID> excludeTaxa = new ArrayList<UUID>();
-        excludeTaxa.add(oldTaxonNode.getUuid());
+        excludeTaxa.add(oldTaxonNode.getTaxon().getUuid());
 
         boolean moveToNewParent = true;
 
         if (PreferencesUtil.getSortNodesNaturally()){
-            if(!MessageDialog.openQuestion(activeShell, "Target node", "The choosen target node should be the parent?")){
+            if(!MessageDialog.openQuestion(activeShell, "Target node", "Should the choosen target node be the parent of this taxon node?")){
                 moveToNewParent = false;
             }
             parentTaxonNode = TaxonNodeSelectionDialog.select(activeShell,
@@ -98,14 +98,14 @@ public class RemotingMoveTaxonNodeHandler extends RemotingCdmHandler {
                     "Choose the taxon above the moved taxon.",
                     excludeTaxa,
                     null,
-                    null);
+                    oldTaxonNode.getClassification());
         } else {
             parentTaxonNode = TaxonNodeSelectionDialog.select(activeShell,
                     new ConversationHolderMock(),
                     "Choose new parent",
                     excludeTaxa,
                     null,
-                    null);
+                    oldTaxonNode.getClassification());
         }
 
 
index 89249cddc02f43a90f6d1dad5e9a9a85e6075259..abdad0532f4d722ea341fd18461b976eb3a0e612 100644 (file)
@@ -15,6 +15,7 @@ import java.io.InputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.UUID;
 
 import org.apache.commons.io.IOUtils;
 import org.eclipse.core.runtime.Assert;
@@ -26,6 +27,7 @@ import org.eclipse.swt.widgets.Display;
 
 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
 import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
+import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
 import eu.etaxonomy.cdm.io.common.CdmDefaultImport;
 import eu.etaxonomy.cdm.io.common.IImportConfigurator;
 import eu.etaxonomy.cdm.io.common.IImportConfigurator.SOURCE_TYPE;
@@ -37,8 +39,10 @@ import eu.etaxonomy.cdm.io.service.IIOService;
 import eu.etaxonomy.cdm.io.specimen.abcd206.in.Abcd206ImportConfigurator;
 import eu.etaxonomy.cdm.io.specimen.excel.in.SpecimenCdmExcelImportConfigurator;
 import eu.etaxonomy.cdm.io.tcsxml.in.TcsXmlImportConfigurator;
+import eu.etaxonomy.taxeditor.model.AbstractUtility;
 import eu.etaxonomy.taxeditor.model.CdmProgressMonitorAdapter;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
 
@@ -51,7 +55,7 @@ import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
  * @created Sep 11, 2009
  * @version 1.0
  */
-public class ImportManager extends AbstractIOManager<IImportConfigurator> {
+public class ImportManager extends AbstractIOManager<IImportConfigurator> implements IPostMoniteredOperationEnabled {
 
        /**
         * @param applicationConfiguration
@@ -195,6 +199,53 @@ public class ImportManager extends AbstractIOManager<IImportConfigurator> {
 
         return job;
 
+    }
+
+    public void runMoniteredOperation(IImportConfigurator configurator, InputStream is, SOURCE_TYPE type) {
+
+        try {
+            runMoniteredOperation(configurator, IOUtils.toByteArray(is), type);
+        } catch (Exception e) {
+            MessagingUtils.errorDialog("Error importing input stream",
+                    this,
+                    e.getMessage(),
+                    TaxeditorStorePlugin.PLUGIN_ID,
+                    e,
+                    true);
+        }
+
+    }
+
+    public void runMoniteredOperation(IImportConfigurator configurator, File importFile, SOURCE_TYPE type) {
+        Path path = Paths.get(importFile.toURI());
+        try {
+            runMoniteredOperation(configurator, Files.readAllBytes(path), type);
+        } catch (Exception e) {
+            MessagingUtils.errorDialog("Error importing input stream",
+                    this,
+                    e.getMessage(),
+                    TaxeditorStorePlugin.PLUGIN_ID,
+                    e,
+                    true);
+        }
+
+    }
+
+    public void runMoniteredOperation(final IImportConfigurator configurator, final byte[] data, final SOURCE_TYPE type) {
+        IIOService ioService = CdmApplicationState.getIOService();
+        final UUID uuid = ioService.monitImportData(configurator, data, type);
+        Display.getDefault().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+                AbstractUtility.executeMoniteredOperation("Import: " + configurator.getClass().getSimpleName(),
+                        uuid,
+                        1000,
+                        false,
+                        ImportManager.this,
+                        null);
+            }
+        });
+
     }
 
        private IImportConfigurator getConfigurator(TYPE type) {
@@ -301,5 +352,20 @@ public class ImportManager extends AbstractIOManager<IImportConfigurator> {
                return (SpecimenCdmExcelImportConfigurator) getConfigurator(TYPE.SpecimenCdmExcel);
        }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void postOperation(IRemotingProgressMonitor monitor) {
+        Display.getDefault().asyncExec(new Runnable() {
+
+            @Override
+            public void run() {
+                CdmStore.getContextManager().notifyContextRefresh();
+            }
+        });
+
+    }
+
 
 }
index 70bc683baa8c356fbc7002fd54a1bfc9eb37a631..4dc3d410c49d192a04ffa994179649c11a00029d 100644 (file)
@@ -16,7 +16,6 @@ import java.io.FileNotFoundException;
 import java.net.URI;
 
 import org.apache.log4j.Logger;
-import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.ui.IWorkbench;
 
@@ -66,8 +65,9 @@ public class AbcdImportWizard extends AbstractImportWizard<Abcd206ImportConfigur
            configurator.setReportUri(classificationChooserWizardPage.getReportUri());
 
            if(CdmStore.getCurrentSessionManager().isRemoting()) {
-               Job job = CdmStore.getImportManager().createIOServiceJob(configurator, new File(source), SOURCE_TYPE.INPUTSTREAM);
-               CdmStore.getImportManager().run(job);
+               //Job job = CdmStore.getImportManager().createIOServiceJob(configurator, new File(source), SOURCE_TYPE.INPUTSTREAM);
+               //CdmStore.getImportManager().run(job);
+               CdmStore.getImportManager().runMoniteredOperation(configurator, new File(source), SOURCE_TYPE.INPUTSTREAM);
            } else {
                try {
                    configurator.setSource(new FileInputStream(new File(source)));
index da353112490a5cfc8acd5051a5ac75e3cb8437b7..01e47b4a81e2403dc9539031c945f8787e235e59 100644 (file)
@@ -29,6 +29,7 @@ import org.eclipse.swt.widgets.Text;
 import org.eclipse.wb.swt.ResourceManager;
 
 import eu.etaxonomy.cdm.model.taxon.Classification;
+import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.ui.dialog.selection.SelectionDialogFactory;
 
 /**
@@ -105,38 +106,39 @@ public class ClassificationChooserWizardPage extends WizardPage implements Liste
                btnClear.setImage(ResourceManager.getPluginImage("eu.etaxonomy.taxeditor.store", "icons/trash.gif"));
                btnClear.addListener(SWT.Selection, this);
 
-               //report
-               Label labelReportFile = new Label(composite, SWT.NONE);
-        labelReportFile.setText("Report File");
+               if(!CdmStore.getCurrentSessionManager().isRemoting()) {
+                   //report
+                   Label labelReportFile = new Label(composite, SWT.NONE);
+                   labelReportFile.setText("Report File");
 
-        fileDialogReport = new FileDialog(parent.getShell());
+                   fileDialogReport = new FileDialog(parent.getShell());
 
-        fileDialogReport.setFilterExtensions(new String[]{"*.*"});
+                   fileDialogReport.setFilterExtensions(new String[]{"*.*"});
 
-        textFileReport = new Text(composite, SWT.BORDER);
-        textFileReport.setEditable(false);
-        textFileReport.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+                   textFileReport = new Text(composite, SWT.BORDER);
+                   textFileReport.setEditable(false);
+                   textFileReport.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
 
 
-        Button buttonReport = new Button(composite, SWT.PUSH);
-        buttonReport.setText("Browse...");
+                   Button buttonReport = new Button(composite, SWT.PUSH);
+                   buttonReport.setText("Browse...");
 
-        buttonReport.addSelectionListener(new SelectionAdapter(){
+                   buttonReport.addSelectionListener(new SelectionAdapter(){
 
-            /* (non-Javadoc)
-             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-             */
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                String path = fileDialogReport.open();
-                if(path!=null){
-                    textFileReport.setText(path);
-                    setPageComplete(true);
-                }
-            }
-
-        });
+                       /* (non-Javadoc)
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+                        */
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                           String path = fileDialogReport.open();
+                           if(path!=null){
+                               textFileReport.setText(path);
+                               setPageComplete(true);
+                           }
+                       }
 
+                   });
+               }
                setControl(composite);
        }
 
@@ -165,6 +167,9 @@ public class ClassificationChooserWizardPage extends WizardPage implements Liste
     }
 
     public URI getReportUri(){
+        if(textFileReport == null) {
+            return null;
+        }
         String text = textFileReport.getText();
         if(text==null || text.isEmpty()){
             return null;
index 560fd61f04b8dc701883df406c8c9934b2940eb4..e700d2e3563aab8333e265b65131eb35c793d774 100644 (file)
@@ -16,7 +16,10 @@ import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.TreeSet;
+import java.util.UUID;
 
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.commands.NotEnabledException;
 import org.eclipse.core.commands.NotHandledException;
@@ -31,6 +34,7 @@ import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.action.IStatusLineManager;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.resource.ColorRegistry;
@@ -51,16 +55,24 @@ import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
 import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.progress.IProgressConstants;
 import org.eclipse.ui.progress.IProgressService;
 import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
 import org.eclipse.ui.themes.ITheme;
 import org.eclipse.ui.themes.IThemeManager;
 
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
+import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
 import eu.etaxonomy.cdm.model.common.IEnumTerm;
 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
+import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
+import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
 import eu.etaxonomy.taxeditor.operation.RemotingCdmHandler;
+import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
+import eu.etaxonomy.taxeditor.ui.dialog.ReportTextDialog;
 import eu.etaxonomy.taxeditor.view.AbstractCdmDataViewer;
 import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
 import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
@@ -76,587 +88,678 @@ import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
  */
 public abstract class AbstractUtility {
 
+    private static final Logger logger = Logger.getLogger(AbstractUtility.class);
+
     /** Constant <code>statusLineManager</code> */
     protected static IStatusLineManager statusLineManager;
 
 
-       /**
-        * <p>
-        * closeAll
-        * </p>
-        *
-        * @return a boolean.
-        */
-       public static boolean closeAll() {
-               return getActivePage().closeAllEditors(true);
-       }
-
-       /**
-        * Close the given editor.
-        *
-        * @param editor
-        *            The <tt>MultipageTaxonEditor</tt> to close.
-        * @return <tt>true</tt> on success
-        */
-       public static boolean close(EditorPart editor) {
-               return getActivePage().closeEditor(editor, true);
-       }
-
-       /**
-        * <p>
-        * getShell
-        * </p>
-        *
-        * @return a {@link org.eclipse.swt.widgets.Shell} object.
-        */
-       public static Shell getShell() {
-
-               return TaxeditorStorePlugin.getDefault().getWorkbench()
-                               .getActiveWorkbenchWindow().getShell();
-       }
-
-       /**
-        * <p>
-        * getActivePage
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.IWorkbenchPage} object.
-        */
-       public static IWorkbenchPage getActivePage() {
-
-               return TaxeditorStorePlugin.getDefault().getWorkbench()
-                               .getActiveWorkbenchWindow().getActivePage();
-       }
-
-       /**
-        * <p>
-        * getActivePart
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.IWorkbenchPart} object.
-        */
-       public static IWorkbenchPart getActivePart() {
-               return getActivePage() != null ? getActivePage().getActivePart() : null;
-       }
-
-       public static IWorkbench getWorkbench() {
-               return TaxeditorStorePlugin.getDefault().getWorkbench();
-       }
-
-       /**
-        * <p>
-        * getWorkbenchWindow
-        * </p>
-        *
-        * @return a {@link org.eclipse.jface.window.ApplicationWindow} object.
-        */
-       public static ApplicationWindow getWorkbenchWindow() {
-               if (getWorkbench().getWorkbenchWindowCount() > 1) {
-                       throw new IllegalStateException("More than one workbench window");
-               }
-               return (ApplicationWindow) getWorkbench().getWorkbenchWindows()[0];
-       }
-
-       /**
-        * <p>
-        * showView
-        * </p>
-        *
-        * @param id
-        *            a {@link java.lang.String} object.
-        * @return a {@link org.eclipse.ui.IViewPart} object.
-        */
-       public static IViewPart showView(String id) {
-               try {
-                       return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
-                                       .getActivePage()
-                                       .showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
-               } catch (PartInitException e) {
-                       MessagingUtils.messageDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
-                       return null;
-               }
-       }
-
-       /**
-        * <p>
-        * hideView
-        * </p>
-        *
-        * @param view
-        *            a {@link org.eclipse.ui.IViewPart} object.
-        */
-       public static void hideView(IViewPart view) {
-               PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
-                               .hideView(view);
-       }
-
-       /**
-        * <p>
-        * getView
-        * </p>
-        *
-        * @param id
-        *            a {@link java.lang.String} object.
-        * @param restore
-        *            a boolean.
-        * @return a {@link org.eclipse.ui.IViewPart} object.
-        */
-       public static IViewPart getView(String id, boolean restore) {
-               IViewReference[] references = PlatformUI.getWorkbench()
-                               .getActiveWorkbenchWindow().getActivePage().getViewReferences();
-               for (IViewReference reference : references) {
-                       if (reference.getId().equals(id)) {
-                               return reference.getView(restore);
-                       }
-               }
-               return null;
-       }
-
-       /**
-        * <p>
-        * getService
-        * </p>
-        *
-        * @param api
-        *            a {@link java.lang.Class} object.
-        * @return a {@link java.lang.Object} object.
-        */
-       public static Object getService(Class api) {
-               return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
-       }
-
-       /**
-        * <p>
-        * getCurrentTheme
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.themes.ITheme} object.
-        */
-       public static ITheme getCurrentTheme() {
-               IThemeManager themeManager = TaxeditorStorePlugin.getDefault()
-                               .getWorkbench().getThemeManager();
-               return themeManager.getCurrentTheme();
-       }
-
-       /**
-        * Fonts registered to the plugin may be obtained with the Eclipse themeing
-        * functionality. Thus fonts are chooseable by the user via
-        * Preferences->General->Appearance->Colors and Fonts
-        *
-        * @return the FontRegistry for the current theme
-        */
-       public static FontRegistry getFontRegistry() {
-               return getCurrentTheme().getFontRegistry();
-       }
-
-       /**
-        * <p>
-        * getFont
-        * </p>
-        *
-        * @param symbolicName
-        *            a {@link java.lang.String} object.
-        * @return a {@link org.eclipse.swt.graphics.Font} object.
-        */
-       public static Font getFont(String symbolicName) {
-               return getFontRegistry().get(symbolicName);
-       }
-
-       /**
-        * Color registered to the plugin may be obtained with the Eclipse themeing
-        * functionality. Thus colors are editable by the user via
-        * Preferences->General->Appearance->Colors and Fonts
-        *
-        * @return the ColorRegistry for the current theme
-        */
-       public static ColorRegistry getColorRegistry() {
-               return getCurrentTheme().getColorRegistry();
-       }
-
-       /**
-        * <p>
-        * getColor
-        * </p>
-        *
-        * @param symbolicName
-        *            a {@link java.lang.String} object.
-        * @return a {@link org.eclipse.swt.graphics.Color} object.
-        */
-       public static Color getColor(String symbolicName) {
-               return getColorRegistry().get(symbolicName);
-       }
-
-       /**
-        * <p>
-        * executeOperation
-        * </p>
-        *
-        * @param operation
-        *            a
-        *            {@link eu.etaxonomy.taxeditor.operation.AbstractPostTaxonOperation}
-        *            object.
-        * @return a {@link org.eclipse.core.runtime.IStatus} object.
-        */
-       public static IStatus executeOperation(final AbstractPostOperation operation) {
-               if (getOperationHistory() == null) {
-                       throw new IllegalArgumentException(
-                                       "There is no operation history for this context");
-               }
-
-               final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
-                               .getUIInfoAdapter(getShell());
-
-               IRunnableWithProgress runnable = new IRunnableWithProgress() {
-
-                       @Override
+    /**
+     * <p>
+     * closeAll
+     * </p>
+     *
+     * @return a boolean.
+     */
+    public static boolean closeAll() {
+        return getActivePage().closeAllEditors(true);
+    }
+
+    /**
+     * Close the given editor.
+     *
+     * @param editor
+     *            The <tt>MultipageTaxonEditor</tt> to close.
+     * @return <tt>true</tt> on success
+     */
+    public static boolean close(EditorPart editor) {
+        return getActivePage().closeEditor(editor, true);
+    }
+
+    /**
+     * <p>
+     * getShell
+     * </p>
+     *
+     * @return a {@link org.eclipse.swt.widgets.Shell} object.
+     */
+    public static Shell getShell() {
+
+        return TaxeditorStorePlugin.getDefault().getWorkbench()
+                .getActiveWorkbenchWindow().getShell();
+    }
+
+    /**
+     * <p>
+     * getActivePage
+     * </p>
+     *
+     * @return a {@link org.eclipse.ui.IWorkbenchPage} object.
+     */
+    public static IWorkbenchPage getActivePage() {
+
+        return TaxeditorStorePlugin.getDefault().getWorkbench()
+                .getActiveWorkbenchWindow().getActivePage();
+    }
+
+    /**
+     * <p>
+     * getActivePart
+     * </p>
+     *
+     * @return a {@link org.eclipse.ui.IWorkbenchPart} object.
+     */
+    public static IWorkbenchPart getActivePart() {
+        return getActivePage() != null ? getActivePage().getActivePart() : null;
+    }
+
+    public static IWorkbench getWorkbench() {
+        return TaxeditorStorePlugin.getDefault().getWorkbench();
+    }
+
+    /**
+     * <p>
+     * getWorkbenchWindow
+     * </p>
+     *
+     * @return a {@link org.eclipse.jface.window.ApplicationWindow} object.
+     */
+    public static ApplicationWindow getWorkbenchWindow() {
+        if (getWorkbench().getWorkbenchWindowCount() > 1) {
+            throw new IllegalStateException("More than one workbench window");
+        }
+        return (ApplicationWindow) getWorkbench().getWorkbenchWindows()[0];
+    }
+
+    /**
+     * <p>
+     * showView
+     * </p>
+     *
+     * @param id
+     *            a {@link java.lang.String} object.
+     * @return a {@link org.eclipse.ui.IViewPart} object.
+     */
+    public static IViewPart showView(String id) {
+        try {
+            return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+                    .getActivePage()
+                    .showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
+        } catch (PartInitException e) {
+            MessagingUtils.messageDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
+            return null;
+        }
+    }
+
+    /**
+     * <p>
+     * hideView
+     * </p>
+     *
+     * @param view
+     *            a {@link org.eclipse.ui.IViewPart} object.
+     */
+    public static void hideView(IViewPart view) {
+        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
+        .hideView(view);
+    }
+
+    /**
+     * <p>
+     * getView
+     * </p>
+     *
+     * @param id
+     *            a {@link java.lang.String} object.
+     * @param restore
+     *            a boolean.
+     * @return a {@link org.eclipse.ui.IViewPart} object.
+     */
+    public static IViewPart getView(String id, boolean restore) {
+        IViewReference[] references = PlatformUI.getWorkbench()
+                .getActiveWorkbenchWindow().getActivePage().getViewReferences();
+        for (IViewReference reference : references) {
+            if (reference.getId().equals(id)) {
+                return reference.getView(restore);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * <p>
+     * getService
+     * </p>
+     *
+     * @param api
+     *            a {@link java.lang.Class} object.
+     * @return a {@link java.lang.Object} object.
+     */
+    public static Object getService(Class api) {
+        return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
+    }
+
+    /**
+     * <p>
+     * getCurrentTheme
+     * </p>
+     *
+     * @return a {@link org.eclipse.ui.themes.ITheme} object.
+     */
+    public static ITheme getCurrentTheme() {
+        IThemeManager themeManager = TaxeditorStorePlugin.getDefault()
+                .getWorkbench().getThemeManager();
+        return themeManager.getCurrentTheme();
+    }
+
+    /**
+     * Fonts registered to the plugin may be obtained with the Eclipse themeing
+     * functionality. Thus fonts are chooseable by the user via
+     * Preferences->General->Appearance->Colors and Fonts
+     *
+     * @return the FontRegistry for the current theme
+     */
+    public static FontRegistry getFontRegistry() {
+        return getCurrentTheme().getFontRegistry();
+    }
+
+    /**
+     * <p>
+     * getFont
+     * </p>
+     *
+     * @param symbolicName
+     *            a {@link java.lang.String} object.
+     * @return a {@link org.eclipse.swt.graphics.Font} object.
+     */
+    public static Font getFont(String symbolicName) {
+        return getFontRegistry().get(symbolicName);
+    }
+
+    /**
+     * Color registered to the plugin may be obtained with the Eclipse themeing
+     * functionality. Thus colors are editable by the user via
+     * Preferences->General->Appearance->Colors and Fonts
+     *
+     * @return the ColorRegistry for the current theme
+     */
+    public static ColorRegistry getColorRegistry() {
+        return getCurrentTheme().getColorRegistry();
+    }
+
+    /**
+     * <p>
+     * getColor
+     * </p>
+     *
+     * @param symbolicName
+     *            a {@link java.lang.String} object.
+     * @return a {@link org.eclipse.swt.graphics.Color} object.
+     */
+    public static Color getColor(String symbolicName) {
+        return getColorRegistry().get(symbolicName);
+    }
+
+    /**
+     * <p>
+     * executeOperation
+     * </p>
+     *
+     * @param operation
+     *            a
+     *            {@link eu.etaxonomy.taxeditor.operation.AbstractPostTaxonOperation}
+     *            object.
+     * @return a {@link org.eclipse.core.runtime.IStatus} object.
+     */
+    public static IStatus executeOperation(final AbstractPostOperation operation) {
+        if (getOperationHistory() == null) {
+            throw new IllegalArgumentException(
+                    "There is no operation history for this context");
+        }
+
+        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
+                .getUIInfoAdapter(getShell());
+
+        IRunnableWithProgress runnable = new IRunnableWithProgress() {
+
+            @Override
             public void run(IProgressMonitor monitor)
-                                       throws InvocationTargetException, InterruptedException {
-                               String operationlabel = operation.getLabel();
+                    throws InvocationTargetException, InterruptedException {
+                String operationlabel = operation.getLabel();
                 monitor.beginTask(operationlabel, 100);
-                               IStatus status = Status.CANCEL_STATUS;
-                               try {
-                                       operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
-                                       status = getOperationHistory().execute(operation, monitor,
-                                                       uiInfoAdapter);
-                               } catch (ExecutionException e) {
-
-                                       MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
-
-                               } finally {
-                                       monitor.done();
-                               }
-
-                               String statusString = status.equals(Status.OK_STATUS) ? "completed"
-                                               : "cancelled";
-                               setStatusLine(operationlabel + " " + statusString + ".");
-
-                       }
-               };
-
-               try {
-                       runInUI(runnable, null);
-               } catch (Exception e) {
-                       MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
-               }
-
-               IPostOperationEnabled postOperationEnabled = operation
-                               .getPostOperationEnabled();
-               if (postOperationEnabled != null) {
-                       postOperationEnabled.onComplete();
-               }
-               return Status.OK_STATUS;
-       }
-
-          public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler) {
-               if (getOperationHistory() == null) {
-                   throw new IllegalArgumentException(
-                           "There is no operation history for this context");
-               }
-
-               final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
-                       .getUIInfoAdapter(getShell());
-
-               IRunnableWithProgress runnable = new IRunnableWithProgress() {
-
-                   @Override
-                   public void run(IProgressMonitor monitor)
-                           throws InvocationTargetException, InterruptedException {
-                       String operationlabel = operation.getLabel();
-                       monitor.beginTask(operationlabel, 100);
-                       IStatus status = Status.CANCEL_STATUS;
-                       try {
-                           operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
-                           status = getOperationHistory().execute(operation, monitor,
-                                   uiInfoAdapter);
-                           if(handler != null) {
-                               handler.postOperation(status);
-                           }
-                       } catch (ExecutionException e) {
-                           MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
-                       } finally {
-                           monitor.done();
-                       }
-
-                       String statusString = status.equals(Status.OK_STATUS) ? "completed"
-                               : "cancelled";
-                       setStatusLine(operationlabel + " " + statusString + ".");
-
-                   }
-               };
-
-               try {
-                   runInUI(runnable, null);
-               } catch (Exception e) {
-                   MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
-               }
-
-               return Status.OK_STATUS;
-           }
-       /**
-        * <p>
-        * getOperationHistory
-        * </p>
-        *
-        * @return a {@link org.eclipse.core.commands.operations.IOperationHistory}
-        *         object.
-        */
-       public static IOperationHistory getOperationHistory() {
-               return getWorkbench().getOperationSupport().getOperationHistory();
-       }
-
-       /**
-        * <p>
-        * setStatusLine
-        * </p>
-        *
-        * @param message
-        *            a {@link java.lang.String} object.
-        */
-       public static void setStatusLine(final String message) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       @Override
+                IStatus status = Status.CANCEL_STATUS;
+                try {
+                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
+                    status = getOperationHistory().execute(operation, monitor,
+                            uiInfoAdapter);
+                } catch (ExecutionException e) {
+
+                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
+
+                } finally {
+                    monitor.done();
+                }
+
+                String statusString = status.equals(Status.OK_STATUS) ? "completed"
+                        : "cancelled";
+                setStatusLine(operationlabel + " " + statusString + ".");
+
+            }
+        };
+
+        try {
+            runInUI(runnable, null);
+        } catch (Exception e) {
+            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
+        }
+
+        IPostOperationEnabled postOperationEnabled = operation
+                .getPostOperationEnabled();
+        if (postOperationEnabled != null) {
+            postOperationEnabled.onComplete();
+        }
+        return Status.OK_STATUS;
+    }
+
+    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler) {
+        if (getOperationHistory() == null) {
+            throw new IllegalArgumentException(
+                    "There is no operation history for this context");
+        }
+
+        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
+                .getUIInfoAdapter(getShell());
+
+        IRunnableWithProgress runnable = new IRunnableWithProgress() {
+
+            @Override
+            public void run(IProgressMonitor monitor)
+                    throws InvocationTargetException, InterruptedException {
+                String operationlabel = operation.getLabel();
+                monitor.beginTask(operationlabel, 100);
+                IStatus status = Status.CANCEL_STATUS;
+                try {
+                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
+                    status = getOperationHistory().execute(operation, monitor,
+                            uiInfoAdapter);
+                    if(handler != null) {
+                        handler.postOperation(status);
+                    }
+                } catch (ExecutionException e) {
+                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
+                } finally {
+                    monitor.done();
+                }
+
+                String statusString = status.equals(Status.OK_STATUS) ? "completed"
+                        : "cancelled";
+                setStatusLine(operationlabel + " " + statusString + ".");
+
+            }
+        };
+
+        try {
+            runInUI(runnable, null);
+        } catch (Exception e) {
+            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
+        }
+
+        return Status.OK_STATUS;
+    }
+
+    /**
+     * Executes a remoting monitored operation
+     *
+     * @param label for the operation
+     * @param uuid of the remoting monitor already started on the server
+     * @param pollInterval in milliseconds
+     * @param cancelable flag which determines whether the operation can be cancelled
+     * @param postOp callback for running post operation logic
+     * @return
+     */
+    public static IStatus executeMoniteredOperation(final String label,
+            final UUID uuid,
+            final int pollInterval,
+            final boolean cancelable,
+            final IPostMoniteredOperationEnabled postOp,
+            final IFeedbackGenerator feedbackGenerator) {
+
+        try {
+            // get the remoting monitor the first time to make sure that the
+            // operation is valid
+            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
+            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
+            if(firstRemotingMonitor == null) {
+                throw new IllegalStateException("Remoting progress monitor is null");
+            }
+
+            Job job = new Job(label) {
+
+
+                @Override
+                public IStatus run(IProgressMonitor monitor) {
+                    // run the monitor until the operation is finished
+                    IRemotingProgressMonitor remotingMonitor;
+                    try {
+                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
+                                uuid,
+                                pollInterval,
+                                postOp,
+                                feedbackGenerator,
+                                monitor);
+                    } catch (Exception ex) {
+                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
+                    }
+                    final StringBuilder reportSb = new StringBuilder();
+                    // collect reports
+                    for(String report : remotingMonitor.getReports()) {
+                        reportSb.append(report);
+                    }
+                    if(!StringUtils.isBlank(reportSb.toString())) {
+                        Display.getDefault().asyncExec(new Runnable() {
+                            @Override
+                            public void run() {
+                                // display reports with possibility to save
+                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+                                dialog.setTitle(label + " Report");
+                                dialog.setReportText(reportSb.toString());
+                                dialog.open();
+                            }
+                        });
+                    }
+                    return Status.OK_STATUS;
+                }
+
+                @Override
+                protected void canceling() {
+                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
+                }
+            };
+
+            // configure the job
+            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
+            job.setUser(true);
+            // schedule job
+            job.schedule();
+
+        } catch (Exception e) {
+            MessagingUtils.errorDialog("Error executing operation",
+                    AbstractUtility.class,
+                    "An error occured while executing " + label,
+                    TaxeditorStorePlugin.PLUGIN_ID,
+                    e,
+                    true);
+        }
+
+        return Status.OK_STATUS;
+    }
+
+
+    /**
+     * <p>
+     * getOperationHistory
+     * </p>
+     *
+     * @return a {@link org.eclipse.core.commands.operations.IOperationHistory}
+     *         object.
+     */
+    public static IOperationHistory getOperationHistory() {
+        return getWorkbench().getOperationSupport().getOperationHistory();
+    }
+
+    /**
+     * <p>
+     * setStatusLine
+     * </p>
+     *
+     * @param message
+     *            a {@link java.lang.String} object.
+     */
+    public static void setStatusLine(final String message) {
+        Display.getDefault().asyncExec(new Runnable() {
+
+            @Override
             public void run() {
-                               statusLineManager.setMessage(message);
-                       }
-
-               });
-
-       }
-
-       /**
-        * <p>
-        * getMonitor
-        * </p>
-        *
-        * @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
-        */
-       public static IProgressMonitor getMonitor() {
-               statusLineManager.setCancelEnabled(false);
-               return statusLineManager.getProgressMonitor();
-       }
-
-       /**
-        * Starts either the given {@link IProgressMonitor} if it's not
-        * <code>null</code> or a new {@link NullProgressMonitor}.
-        *
-        * @param progressMonitor
-        *            The {@link IProgressMonitor} or <code>null</code> if no
-        *            progress should be reported.
-        * @param taskName
-        *            The name of the main task.
-        * @param steps
-        *            The number of steps this task is subdivided into.
-        * @return The {@link IProgressMonitor}.
-        */
-       public static IProgressMonitor startMainMonitor(
-                       IProgressMonitor progressMonitor, String taskName, int steps) {
-               IProgressMonitor newMonitor = progressMonitor;
-               if (newMonitor == null) {
-                       newMonitor = new NullProgressMonitor();
-               }
-               newMonitor.beginTask(taskName == null ? "" : taskName, steps);
-               newMonitor.subTask(" ");
-               return newMonitor;
-       }
-
-       /**
-        * Creates a {@link SubProgressMonitor} if the given
-        * {@link IProgressMonitor} is not <code>null</code> and not a
-        * {@link NullProgressMonitor}.
-        *
-        * @param progressMonitor
-        *            The parent {@link IProgressMonitor} of the
-        *            {@link SubProgressMonitor} to be created.
-        * @param ticks
-        *            The number of steps this subtask is subdivided into. Must be a
-        *            positive number and must not be
-        *            {@link IProgressMonitor#UNKNOWN}.
-        * @return The {@link IProgressMonitor}.
-        */
-       public static IProgressMonitor getSubProgressMonitor(
-                       IProgressMonitor progressMonitor, int ticks) {
-               if (progressMonitor == null) {
-                       return new NullProgressMonitor();
-               }
-               if (progressMonitor instanceof NullProgressMonitor) {
-                       return progressMonitor;
-               }
-
-               return new SubProgressMonitor(progressMonitor, ticks);
-       }
-
-       /**
-        * Checks whether the user canceled this operation. If not canceled, the
-        * given number of steps are declared as done.
-        *
-        * @param newMonitor
-        *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
-        * @param steps
-        *            a int.
-        */
-       public static void workedChecked(IProgressMonitor newMonitor, int steps) {
-               // In case the progress monitor was canceled throw an exception.
-               if (newMonitor.isCanceled()) {
-                       throw new OperationCanceledException();
-               }
-               // Otherwise declare this step as done.
-               newMonitor.worked(steps);
-       }
-
-       /**
-        * Present a progress dialog to the user. This dialog will block the UI
-        *
-        * @param runnable
-        *            an implementation of {@link IRunnableWithProgress}
-        * @throws java.lang.InterruptedException
-        *             if any.
-        * @throws java.lang.reflect.InvocationTargetException
-        *             if any.
-        */
-       public static void busyCursorWhile(IRunnableWithProgress runnable)
-                       throws InvocationTargetException, InterruptedException {
-               getProgressService().busyCursorWhile(runnable);
-       }
-
-       /**
-        * <p>
-        * runInUI
-        * </p>
-        *
-        * @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
-        * @param runnable
-        *            a {@link org.eclipse.jface.operation.IRunnableWithProgress}
-        *            object.
-        * @param rule
-        *            a {@link org.eclipse.core.runtime.jobs.ISchedulingRule}
-        *            object.
-        * @throws java.lang.reflect.InvocationTargetException
-        *             if any.
-        * @throws java.lang.InterruptedException
-        *             if any.
-        */
-       public static void runInUI(IRunnableWithProgress runnable,
-                       ISchedulingRule rule) throws InvocationTargetException,
-                       InterruptedException {
-               getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
-       }
-
-       /**
-        * <p>
-        * run
-        * </p>
-        *
-        * @param fork
-        *            a boolean.
-        * @param cancelable
-        *            a boolean.
-        * @param runnable
-        *            a {@link org.eclipse.jface.operation.IRunnableWithProgress}
-        *            object.
-        * @throws java.lang.reflect.InvocationTargetException
-        *             if any.
-        * @throws java.lang.InterruptedException
-        *             if any.
-        */
-       public static void run(boolean fork, boolean cancelable,
-                       IRunnableWithProgress runnable) throws InvocationTargetException,
-                       InterruptedException {
-               getProgressService().run(fork, cancelable, runnable);
-       }
-
-       /**
-        * <p>
-        * getProgressService
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.progress.IProgressService} object.
-        */
-       public static IProgressService getProgressService() {
-               IWorkbench workbench = PlatformUI.getWorkbench();
-               return workbench.getProgressService();
-       }
-
-       /**
-        * <p>
-        * getProgressService2
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService}
-        *         object.
-        */
-       public static IWorkbenchSiteProgressService getProgressService2() {
-               return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
-       }
-
-       /**
-        * <p>
-        * getPluginId
-        * </p>
-        *
-        * @return a {@link java.lang.String} object.
-        */
-       public static String getPluginId() {
-               return "eu.taxeditor";
-       }
-
-       /**
-        * <p>
-        * getActiveEditor
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.IEditorPart} object.
-        */
-       public static IEditorPart getActiveEditor() {
-               return getActivePage() != null ? getActivePage().getActiveEditor()
-                               : null;
-       }
-
-       /**
-        * <p>
-        * getDetailsView
-        * </p>
-        *
-        * @return a {@link eu.etaxonomy.taxeditor.view.detail.DetailsViewPart}
-        *         object.
-        */
-       public static DetailsViewPart getDetailsView() {
-               return (DetailsViewPart) getView(DetailsViewPart.ID, false);
-       }
-
-       /**
-        * <p>
-        * refreshDetailsViewer
-        * </p>
-        */
-       public static void refreshDetailsViewer() {
-               if (getDetailsView() != null) {
-                       ((AbstractCdmDataViewer) getDetailsView().getViewer()).refresh();
-               }
-       }
-
-       /**
-        * <p>
-        * reflowDetailsViewer
-        * </p>
-        */
-       public static void reflowDetailsViewer() {
-               if (getDetailsView() != null) {
-                       ((AbstractCdmDataViewer) getDetailsView().getViewer()).reflow();
-               }
-       }
-
-       public static SupplementalDataViewPart getSupplementalDataView() {
-               return (SupplementalDataViewPart) getView(SupplementalDataViewPart.ID,
-                               false);
-       }
-
-       public static void reflowSupplementalViewer() {
-               if (getSupplementalDataView() != null) {
-                       ((AbstractCdmDataViewer) getSupplementalDataView().getViewer())
-                                       .reflow();
-               }
-       }
+                statusLineManager.setMessage(message);
+            }
+
+        });
+
+    }
+
+    /**
+     * <p>
+     * getMonitor
+     * </p>
+     *
+     * @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
+     */
+    public static IProgressMonitor getMonitor() {
+        statusLineManager.setCancelEnabled(false);
+        return statusLineManager.getProgressMonitor();
+    }
+
+    /**
+     * Starts either the given {@link IProgressMonitor} if it's not
+     * <code>null</code> or a new {@link NullProgressMonitor}.
+     *
+     * @param progressMonitor
+     *            The {@link IProgressMonitor} or <code>null</code> if no
+     *            progress should be reported.
+     * @param taskName
+     *            The name of the main task.
+     * @param steps
+     *            The number of steps this task is subdivided into.
+     * @return The {@link IProgressMonitor}.
+     */
+    public static IProgressMonitor startMainMonitor(
+            IProgressMonitor progressMonitor, String taskName, int steps) {
+        IProgressMonitor newMonitor = progressMonitor;
+        if (newMonitor == null) {
+            newMonitor = new NullProgressMonitor();
+        }
+        newMonitor.beginTask(taskName == null ? "" : taskName, steps);
+        newMonitor.subTask(" ");
+        return newMonitor;
+    }
+
+    /**
+     * Creates a {@link SubProgressMonitor} if the given
+     * {@link IProgressMonitor} is not <code>null</code> and not a
+     * {@link NullProgressMonitor}.
+     *
+     * @param progressMonitor
+     *            The parent {@link IProgressMonitor} of the
+     *            {@link SubProgressMonitor} to be created.
+     * @param ticks
+     *            The number of steps this subtask is subdivided into. Must be a
+     *            positive number and must not be
+     *            {@link IProgressMonitor#UNKNOWN}.
+     * @return The {@link IProgressMonitor}.
+     */
+    public static IProgressMonitor getSubProgressMonitor(
+            IProgressMonitor progressMonitor, int ticks) {
+        if (progressMonitor == null) {
+            return new NullProgressMonitor();
+        }
+        if (progressMonitor instanceof NullProgressMonitor) {
+            return progressMonitor;
+        }
+
+        return new SubProgressMonitor(progressMonitor, ticks);
+    }
+
+    /**
+     * Checks whether the user canceled this operation. If not canceled, the
+     * given number of steps are declared as done.
+     *
+     * @param newMonitor
+     *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
+     * @param steps
+     *            a int.
+     */
+    public static void workedChecked(IProgressMonitor newMonitor, int steps) {
+        // In case the progress monitor was canceled throw an exception.
+        if (newMonitor.isCanceled()) {
+            throw new OperationCanceledException();
+        }
+        // Otherwise declare this step as done.
+        newMonitor.worked(steps);
+    }
+
+    /**
+     * Present a progress dialog to the user. This dialog will block the UI
+     *
+     * @param runnable
+     *            an implementation of {@link IRunnableWithProgress}
+     * @throws java.lang.InterruptedException
+     *             if any.
+     * @throws java.lang.reflect.InvocationTargetException
+     *             if any.
+     */
+    public static void busyCursorWhile(IRunnableWithProgress runnable)
+            throws InvocationTargetException, InterruptedException {
+        getProgressService().busyCursorWhile(runnable);
+    }
+
+    /**
+     * <p>
+     * runInUI
+     * </p>
+     *
+     * @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
+     * @param runnable
+     *            a {@link org.eclipse.jface.operation.IRunnableWithProgress}
+     *            object.
+     * @param rule
+     *            a {@link org.eclipse.core.runtime.jobs.ISchedulingRule}
+     *            object.
+     * @throws java.lang.reflect.InvocationTargetException
+     *             if any.
+     * @throws java.lang.InterruptedException
+     *             if any.
+     */
+    public static void runInUI(IRunnableWithProgress runnable,
+            ISchedulingRule rule) throws InvocationTargetException,
+            InterruptedException {
+        getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
+    }
+
+    /**
+     * <p>
+     * run
+     * </p>
+     *
+     * @param fork
+     *            a boolean.
+     * @param cancelable
+     *            a boolean.
+     * @param runnable
+     *            a {@link org.eclipse.jface.operation.IRunnableWithProgress}
+     *            object.
+     * @throws java.lang.reflect.InvocationTargetException
+     *             if any.
+     * @throws java.lang.InterruptedException
+     *             if any.
+     */
+    public static void run(boolean fork, boolean cancelable,
+            IRunnableWithProgress runnable) throws InvocationTargetException,
+            InterruptedException {
+        getProgressService().run(fork, cancelable, runnable);
+    }
+
+    /**
+     * <p>
+     * getProgressService
+     * </p>
+     *
+     * @return a {@link org.eclipse.ui.progress.IProgressService} object.
+     */
+    public static IProgressService getProgressService() {
+        IWorkbench workbench = PlatformUI.getWorkbench();
+        return workbench.getProgressService();
+    }
+
+    /**
+     * <p>
+     * getProgressService2
+     * </p>
+     *
+     * @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService}
+     *         object.
+     */
+    public static IWorkbenchSiteProgressService getProgressService2() {
+        return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
+    }
+
+    /**
+     * <p>
+     * getPluginId
+     * </p>
+     *
+     * @return a {@link java.lang.String} object.
+     */
+    public static String getPluginId() {
+        return "eu.taxeditor";
+    }
+
+    /**
+     * <p>
+     * getActiveEditor
+     * </p>
+     *
+     * @return a {@link org.eclipse.ui.IEditorPart} object.
+     */
+    public static IEditorPart getActiveEditor() {
+        return getActivePage() != null ? getActivePage().getActiveEditor()
+                : null;
+    }
+
+    /**
+     * <p>
+     * getDetailsView
+     * </p>
+     *
+     * @return a {@link eu.etaxonomy.taxeditor.view.detail.DetailsViewPart}
+     *         object.
+     */
+    public static DetailsViewPart getDetailsView() {
+        return (DetailsViewPart) getView(DetailsViewPart.ID, false);
+    }
+
+    /**
+     * <p>
+     * refreshDetailsViewer
+     * </p>
+     */
+    public static void refreshDetailsViewer() {
+        if (getDetailsView() != null) {
+            ((AbstractCdmDataViewer) getDetailsView().getViewer()).refresh();
+        }
+    }
+
+    /**
+     * <p>
+     * reflowDetailsViewer
+     * </p>
+     */
+    public static void reflowDetailsViewer() {
+        if (getDetailsView() != null) {
+            ((AbstractCdmDataViewer) getDetailsView().getViewer()).reflow();
+        }
+    }
+
+    public static SupplementalDataViewPart getSupplementalDataView() {
+        return (SupplementalDataViewPart) getView(SupplementalDataViewPart.ID,
+                false);
+    }
+
+    public static void reflowSupplementalViewer() {
+        if (getSupplementalDataView() != null) {
+            ((AbstractCdmDataViewer) getSupplementalDataView().getViewer())
+            .reflow();
+        }
+    }
 
 
     /**
index f9e994006d61a6d298335a404928169a2eaa9d8a..70a7130dbcadccd960bf964632c5bd1bea5ae0a4 100644 (file)
@@ -1,8 +1,10 @@
 /**
- * 
+ *
  */
 package eu.etaxonomy.taxeditor.model;
 
+import java.io.Serializable;
+
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
 
@@ -16,17 +18,17 @@ import eu.etaxonomy.taxeditor.store.StoreUtil;
  * @version 1.0
  */
 public class CdmProgressMonitorAdapter implements eu.etaxonomy.cdm.common.monitor.IProgressMonitor {
-       
+
        private IProgressMonitor progressMonitor;
 
        private CdmProgressMonitorAdapter (IProgressMonitor monitor){
                if(monitor == null){
                        monitor = new NullProgressMonitor();
                }
-               
+
                this.progressMonitor = monitor;
        }
-       
+
        /**
         * <p>CreateMonitor</p>
         *
@@ -36,7 +38,7 @@ public class CdmProgressMonitorAdapter implements eu.etaxonomy.cdm.common.monito
        public static CdmProgressMonitorAdapter CreateMonitor (IProgressMonitor monitor){
                return new CdmProgressMonitorAdapter(monitor);
        }
-       
+
        /**
         * <p>CreateSubMonitor</p>
         *
@@ -48,7 +50,7 @@ public class CdmProgressMonitorAdapter implements eu.etaxonomy.cdm.common.monito
                IProgressMonitor subMonitor = StoreUtil.getSubProgressMonitor(monitor, ticks);
                return new CdmProgressMonitorAdapter(subMonitor);
        }
-       
+
        /** {@inheritDoc} */
        @Override
        public void beginTask(String name, int totalWork) {
@@ -107,4 +109,79 @@ public class CdmProgressMonitorAdapter implements eu.etaxonomy.cdm.common.monito
        public void internalWorked(double arg0) {
                progressMonitor.internalWorked(arg0);
        }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Serializable getFeedback() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean getIsWaitingForFeedback() {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setFeedback(Serializable arg0) {
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void waitForFeedback() {
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getOwner() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean hasFeedbackWaitTimedOut() {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void interrupt() {
+
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setOwner(String arg0) {
+
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void waitForFeedback(long arg0) {
+
+    }
+
 }
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/operation/FeedbackGenerator.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/operation/FeedbackGenerator.java
new file mode 100644 (file)
index 0000000..5b084f5
--- /dev/null
@@ -0,0 +1,49 @@
+// $Id$
+/**
+* Copyright (C) 2015 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.operation;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+import org.eclipse.swt.widgets.Display;
+
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+
+/**
+ * Default implementation of the {@link IFeedbackGenerator} interface.
+ *
+ * @author cmathew
+ * @date 29 Oct 2015
+ *
+ */
+public abstract class FeedbackGenerator implements IFeedbackGenerator {
+
+
+    /**
+     * Generates feedback for a waiting remoting progress monitor
+     *
+     * @return feedback object
+     */
+    public abstract Serializable generateFeedback();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setFeedbackForMonitor(final UUID uuid) {
+        Display.getDefault().syncExec(new Runnable() {
+            @Override
+            public void run() {
+                CdmApplicationState.getCurrentAppConfig().getProgressMonitorService().setFeedback(uuid, generateFeedback());
+            }
+        });
+    }
+
+}
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/operation/IFeedbackGenerator.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/operation/IFeedbackGenerator.java
new file mode 100644 (file)
index 0000000..36a6af1
--- /dev/null
@@ -0,0 +1,32 @@
+// $Id$
+/**
+* Copyright (C) 2015 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.operation;
+
+import java.util.UUID;
+
+/**
+ * Generates feeback for waiting remoting progress monitors.
+ * The default implementation of this interface is {@link FeedbackGenerator}
+ *
+ * @author cmathew
+ * @date 28 Oct 2015
+ *
+ */
+public interface IFeedbackGenerator {
+
+    /**
+     * Generates and sets feedback for a waiting remoting progress
+     * monitor corresponding to the given uuid.
+     *
+     * @param uuid of target waiting remoting progress monitor
+     */
+    public void setFeedbackForMonitor(UUID uuid);
+
+}
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/operation/IPostMoniteredOperationEnabled.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/operation/IPostMoniteredOperationEnabled.java
new file mode 100644 (file)
index 0000000..1c15d42
--- /dev/null
@@ -0,0 +1,24 @@
+// $Id$
+/**
+* Copyright (C) 2015 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.operation;
+
+import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
+
+/**
+ * @author cmathew
+ * @date 22 Oct 2015
+ *
+ */
+public interface IPostMoniteredOperationEnabled {
+
+
+    public void postOperation(IRemotingProgressMonitor monitor);
+
+}
index faa81f5be68f328953feac82d3f435ce82b5b3bc..ec73e3044249d9213fe8f10bcbe8411632524d53 100644 (file)
@@ -127,6 +127,8 @@ public interface IPreferenceKeys {
 
        public static final String SEARCH_OPEN_RESULTS_IN_SEPARATE_WINDOWS = "eu.etaxonomy.taxeditor.navigation.search.openResultInSeparateWindows";
 
+       public static final String DISABLE_SERVICES_API_TIMESTAMP_CHECK = "eu.etaxonomy.taxeditor.cdmlib.remoting.disableServicesApiTimestampCheck";
+
        public static final String ADD_TYPES_TO_ALL_NAMES = "eu.etaxonomy.taxeditor.store.addTypeToAllNames";
 
     public static final String DETERMINATION_ONLY_FOR_FIELD_UNITS = "eu.etaxonomy.taxeditor.specimen.determinationOnlyOnFieldUnitLevel";
index 8679d677e2085a5b284a3badd90519dfa28ab269..0e953be686a7ec469e07958c8b830186ec5c8ea6 100644 (file)
@@ -1,25 +1,18 @@
 // $Id$
 /**
  * Copyright (C) 2007 EDIT
- * European Distributed Institute of Taxonomy 
+ * 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.preference;
 
-import org.eclipse.jface.preference.PreferencePage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CLabel;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Text;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.IntegerFieldEditor;
+import org.eclipse.jface.preference.StringFieldEditor;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 
@@ -28,120 +21,28 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
  * @created Feb 4, 2011
  * @version 1.0
  */
-public class MobotOpenUrlPreferences extends PreferencePage implements
+public class MobotOpenUrlPreferences extends FieldEditorPreferencePage implements
                IWorkbenchPreferencePage {
 
-       private String openUrlServiceAccessPoint;
-       private String openUrlImageMaxWidth;
-       private String openUrlImageMaxHeight;
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see
-        * org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
-        */
-       @Override
-       public void init(IWorkbench workbench) {
-               setPreferenceStore(PreferencesUtil.getPreferenceStore());
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see
-        * org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse
-        * .swt.widgets.Composite)
-        */
-       @Override
-       protected Control createContents(Composite parent) {
-               Composite container = new Composite(parent, SWT.NULL);
-               final GridLayout gridLayout = new GridLayout();
-               container.setLayout(gridLayout);
-
-               creatOpenUrlServiceAccessPoint(container);
-
-               createOpenUrlImageSize(container);
-
-               return container;
-       }
-
-       /**
-        * @param container
-        */
-       private void createOpenUrlImageSize(Composite container) {
-               openUrlImageMaxWidth = getPreferenceStore().getString(
-                               IPreferenceKeys.OPENURL_IMAGE_MAX_WIDTH);
-               openUrlImageMaxHeight = getPreferenceStore().getString(
-                               IPreferenceKeys.OPENURL_IMAGE_MAX_HEIGHT);
-
-               Composite composite = new Composite(container, SWT.NULL);
-               final GridLayout gridLayout = new GridLayout(2, false);
-               composite.setLayout(gridLayout);
-
-               final CLabel labelWidth = new CLabel(composite, SWT.NULL);
-               labelWidth.setText("Image Maximum Width: ");
-
-               final Text textWidth = new Text(composite, SWT.BORDER);
-               textWidth.setText(openUrlImageMaxWidth);
-               textWidth.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-
-               textWidth.addModifyListener(new ModifyListener() {
-
-                       public void modifyText(ModifyEvent e) {
-                               openUrlImageMaxWidth = textWidth.getText();
-                       }
-               });
-
-               final CLabel labelHeight = new CLabel(composite, SWT.NULL);
-               labelHeight.setText("Image Maximum Height: ");
-
-               final Text textHeight = new Text(composite, SWT.BORDER);
-               textHeight.setText(openUrlImageMaxHeight);
-               textHeight.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-
-               textHeight.addModifyListener(new ModifyListener() {
-
-                       public void modifyText(ModifyEvent e) {
-                               openUrlImageMaxHeight = textHeight.getText();
-                       }
-               });
-       }
-
-       private void creatOpenUrlServiceAccessPoint(Composite composite) {
-               openUrlServiceAccessPoint = getPreferenceStore().getString(
-                               IPreferenceKeys.OPENURL_ACCESS_POINT);
-
-               final CLabel label = new CLabel(composite, SWT.NULL);
-               label.setText("Mobot Open Url Service Access Point:");
-
-               final Text text = new Text(composite, SWT.BORDER);
-               text.setText(openUrlServiceAccessPoint);
-               text.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-
-               text.addModifyListener(new ModifyListener() {
-
-                       public void modifyText(ModifyEvent e) {
-                               openUrlServiceAccessPoint = text.getText();
-                       }
-               });
-       }
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see org.eclipse.jface.preference.PreferencePage#performOk()
-        */
-       @Override
-       public boolean performOk() {
-               getPreferenceStore().setValue(IPreferenceKeys.OPENURL_ACCESS_POINT,
-                               openUrlServiceAccessPoint);
-               getPreferenceStore().setValue(IPreferenceKeys.OPENURL_IMAGE_MAX_WIDTH,
-                               openUrlImageMaxWidth);
-               getPreferenceStore().setValue(IPreferenceKeys.OPENURL_IMAGE_MAX_HEIGHT,
-                               openUrlImageMaxHeight);
-
-               return super.performOk();
-       }
 
+    @Override
+    protected void createFieldEditors() {
+        addField(new StringFieldEditor(
+                IPreferenceKeys.OPENURL_ACCESS_POINT,
+                "Mobot Open Url Service Access Point:", getFieldEditorParent()));
+        addField(new IntegerFieldEditor(
+                IPreferenceKeys.OPENURL_IMAGE_MAX_WIDTH,
+                "Image Maximum Width:",
+                getFieldEditorParent()));
+        addField(new IntegerFieldEditor(
+                IPreferenceKeys.OPENURL_IMAGE_MAX_HEIGHT,
+                "Image Maximum Height:",
+                getFieldEditorParent()));
+
+    }
+
+    @Override
+    public void init(IWorkbench workbench) {
+        setPreferenceStore(PreferencesUtil.getPreferenceStore());
+    }
 }
index cae829782409e61fa6bb5b1322e280d6342512a8..9ec409300f05a58bd20e7606ee0eda7a3fe769f5 100644 (file)
@@ -60,6 +60,9 @@ public class TaxonomicEditorGeneralPreferences extends
                addField(new BooleanFieldEditor(IPreferenceKeys.SEARCH_OPEN_RESULTS_IN_SEPARATE_WINDOWS,
                        "Open search results in separate windows",
                        getFieldEditorParent()));
+             addField(new BooleanFieldEditor(IPreferenceKeys.DISABLE_SERVICES_API_TIMESTAMP_CHECK,
+                       "Disable services api timestamp check",
+                       getFieldEditorParent()));
        }
 
        /*
index 6d2ddb9bc92792faa37e28d4b6bfc938a0a071ed..be84b00cfff03c850b7222227c69cf3bd5c2fad4 100644 (file)
@@ -17,15 +17,10 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.eclipse.jface.preference.PreferencePage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CLabel;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.jface.preference.ComboFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
 import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
@@ -37,13 +32,11 @@ import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 
 /**
- * <p>Abstract AbstractMatchingPreferences class.</p>
- *
  * @author n.hoffmann
  * @created Jan 22, 2010
  * @version 1.0
  */
-public abstract class AbstractMatchingPreferences<T extends IdentifiableEntity> extends PreferencePage implements
+public abstract class AbstractMatchingPreferences<T extends IdentifiableEntity> extends FieldEditorPreferencePage implements
                IWorkbenchPreferencePage {
 
        /**
@@ -60,96 +53,30 @@ public abstract class AbstractMatchingPreferences<T extends IdentifiableEntity>
 
        protected Map<String, Combo> matchModeCombos = new HashMap<String, Combo>();
 
-       /* (non-Javadoc)
-        * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+    @Override
+    public void init(IWorkbench workbench) {
+        setPreferenceStore(PreferencesUtil.getPreferenceStore());
+    }
+
+       /**
+        * {@inheritDoc}
         */
-       /** {@inheritDoc} */
        @Override
-       protected Control createContents(Composite parent) {
-               final Composite composite = new Composite(parent, SWT.NULL);
-               GridLayout gridLayout = new GridLayout();
-               gridLayout.numColumns = 2;
-               composite.setLayout(gridLayout);
-
-               if(!CdmStore.isActive()) {
+       protected void createFieldEditors() {
+           if(!CdmStore.isActive()) {
             MessagingUtils.noDataSourceWarningDialog(null);
         }else{
             for(String fieldName : getFieldNames()){
-                createFieldWidget(composite, fieldName);
+                String[][] comboValues = new String[getMatchModeList().size()][2];
+                for (int i=0;i<getMatchModeList().size();i++) {
+                    comboValues[i][0] = getMatchModeList().get(i).name();
+                    comboValues[i][1] = getMatchModeList().get(i).name();
+                }
+                addField(new ComboFieldEditor(this.getClass().getCanonicalName()+fieldName,
+                        fieldName, comboValues,
+                        getFieldEditorParent()));
             }
         }
-
-               return composite;
-       }
-
-       /**
-        * Creates a widget for a field consisting of the label and a combo
-        *
-        * @see {@link #createMatchModeCombo(Composite, String, MatchMode)}
-        * @param composite
-        * @param fieldName
-        */
-       private void createFieldWidget(Composite parent, String fieldName) {
-           CLabel label = new CLabel(parent, SWT.NONE);
-           label.setText(fieldName);
-           MatchMode matchMode = matchStrategy.getMatchMode(fieldName);
-
-           createMatchModeCombo(parent, fieldName, matchMode);
-       }
-
-       /**
-        * Creates a combo for a field with the currently selected match mode for that field preselected
-        *
-        * @param parent
-        * @param matchMode
-        */
-       private void createMatchModeCombo(Composite parent, String fieldName, MatchMode selectedMatchMode) {
-               Combo matchModeCombo = new Combo(parent, SWT.NULL);
-
-               for (MatchMode matchMode : getMatchModeList()) {
-                       matchModeCombo.add(matchMode.name());
-               }
-
-               int index = getMatchModeList().indexOf(selectedMatchMode);
-
-               matchModeCombo.select(index);
-
-               matchModeCombo.addSelectionListener(new MatchModeComboSelectionListener(matchModeCombo, fieldName));
-
-               matchModeCombos.put(fieldName, matchModeCombo);
-       }
-
-       /**
-        * This listener updates the cache strategy when a value was changed in one of the combos
-        *
-        * @author n.hoffmann
-        * @created Jan 28, 2010
-        * @version 1.0
-        */
-       private class MatchModeComboSelectionListener extends SelectionAdapter{
-
-               private final Combo matchModeCombo;
-               private final String fieldName;
-
-               MatchModeComboSelectionListener(Combo matchModeCombo, String fieldName){
-                       this.matchModeCombo = matchModeCombo;
-                       this.fieldName = fieldName;
-               }
-
-               /* (non-Javadoc)
-                * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-                */
-               @Override
-               public void widgetSelected(SelectionEvent event) {
-                       super.widgetSelected(event);
-                       MatchMode matchMode = getMatchModeList().get(matchModeCombo.getSelectionIndex());
-                       try {
-                               matchStrategy.setMatchMode(fieldName, matchMode);
-                       } catch (MatchException e) {
-                               MessagingUtils.error(this.getClass(), e);
-                               throw new RuntimeException(e);
-                       }
-               }
        }
 
        /**
@@ -202,40 +129,6 @@ public abstract class AbstractMatchingPreferences<T extends IdentifiableEntity>
            return fields;
        }
 
-       /* (non-Javadoc)
-        * @see org.eclipse.jface.preference.PreferencePage#performApply()
-        */
-       /** {@inheritDoc} */
-       @Override
-       protected void performApply() {
-           PreferencesUtil.setMatchStrategy(matchStrategy);
-               super.performApply();
-       }
-
-       /* (non-Javadoc)
-        * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
-        */
-       /** {@inheritDoc} */
-       @Override
-       protected void performDefaults() {
-               try {
-                       // set match strategy to default
-                       matchStrategy = getDefaultMatchStrategy();
-
-                       // set combos to their default values
-                       for(String fieldName : matchModeCombos.keySet()){
-                               Combo combo = matchModeCombos.get(fieldName);
-                               MatchMode matchMode = matchStrategy.getMatchMode(fieldName);
-                               combo.select(matchModeList.indexOf(matchMode));
-                       }
-
-               } catch (MatchException e) {
-                       MessagingUtils.error(this.getClass(), e);
-                       throw new RuntimeException(e);
-               }
-               super.performDefaults();
-       }
-
        /**
         * Returns the default match strategy for the respective class
         *
index 339232c7aacf8f14bab108f5f394c505bf0b472f..b048e2d13a6906fce33e878c225ac691a4392c37 100644 (file)
@@ -27,12 +27,10 @@ import eu.etaxonomy.taxeditor.model.MessagingUtils;
  */
 public class NonViralNameMatchingPreference extends AbstractMatchingPreferences<NonViralName>{
 
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
-        */
        /** {@inheritDoc} */
        @Override
     public void init(IWorkbench workbench) {
+           super.init(workbench);
                clazz = NonViralName.class;
 
                try {
@@ -43,9 +41,6 @@ public class NonViralNameMatchingPreference extends AbstractMatchingPreferences<
                }
        }
 
-       /* (non-Javadoc)
-        * @see eu.etaxonomy.taxeditor.preference.matching.AbstractMatchingPreferences#getDefaultMatchStrategy()
-        */
        /** {@inheritDoc} */
        @Override
        protected IMatchStrategy getDefaultMatchStrategy() throws MatchException {
index 9a578c0c4a929a2dee67474f21f5689e1afd795d..f28e61fc68cf2a315a0ff11e31345335f294ddc0 100644 (file)
@@ -19,20 +19,16 @@ import eu.etaxonomy.cdm.strategy.match.MatchStrategyConfigurator;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
 
 /**
- * <p>ReferenceMatchingPreference class.</p>
- *
  * @author n.hoffmann
  * @created Jan 22, 2010
  * @version 1.0
  */
 public class ReferenceMatchingPreference extends AbstractMatchingPreferences<Reference> {
 
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
-        */
        /** {@inheritDoc} */
        @Override
     public void init(IWorkbench workbench) {
+           super.init(workbench);
                clazz = Reference.class;
 
                try {
@@ -43,9 +39,6 @@ public class ReferenceMatchingPreference extends AbstractMatchingPreferences<Ref
                }
        }
 
-       /* (non-Javadoc)
-        * @see eu.etaxonomy.taxeditor.preference.matching.AbstractMatchingPreferences#getDefaultMatchStrategy()
-        */
        /** {@inheritDoc} */
        @Override
        protected IMatchStrategy getDefaultMatchStrategy() throws MatchException {
index fac1a2b109ec0a634cccc5d2ae4a76c0218fc0f4..a9774b346f7b2d12af6c69388e19118fbc301c03 100644 (file)
@@ -19,8 +19,6 @@ import eu.etaxonomy.cdm.strategy.match.MatchStrategyConfigurator;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
 
 /**
- * <p>TeamOrPersonMatchingPreference class.</p>
- *
  * @author n.hoffmann
  * @created Jan 22, 2010
  * @version 1.0
@@ -28,13 +26,10 @@ import eu.etaxonomy.taxeditor.model.MessagingUtils;
 public class TeamOrPersonMatchingPreference extends
                AbstractMatchingPreferences<TeamOrPersonBase> {
 
-       /* (non-Javadoc)
-        * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
-        */
        /** {@inheritDoc} */
        @Override
     public void init(IWorkbench workbench) {
-
+           super.init(workbench);
                clazz = TeamOrPersonBase.class;
 
                try {
@@ -45,9 +40,6 @@ public class TeamOrPersonMatchingPreference extends
                }
        }
 
-       /* (non-Javadoc)
-        * @see eu.etaxonomy.taxeditor.preference.matching.AbstractMatchingPreferences#getDefaultMatchStrategy()
-        */
        /** {@inheritDoc} */
        @Override
        protected IMatchStrategy getDefaultMatchStrategy() throws MatchException {
index 8d96d335990f46e0da8826e6be52b0a63e9667af..c4d231be2f82347b1c118371dbcc9c90a7e66b20 100644 (file)
@@ -48,6 +48,7 @@ import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager;
 import eu.etaxonomy.taxeditor.session.mock.MockCdmEntitySessionManager;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
 import eu.etaxonomy.taxeditor.ui.dialog.RemotingLoginDialog;
+import eu.etaxonomy.taxeditor.util.ProgressMonitorClientManager;
 import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
 
 /**
@@ -85,6 +86,8 @@ public class CdmStore {
 
     private static UseObjectStore useObjectInitializer = new UseObjectStore();
 
+    private static ProgressMonitorClientManager progressMonitorClientManager = new ProgressMonitorClientManager();
+
     private static CdmStoreConnector job;
 
     private Language language;
@@ -523,6 +526,10 @@ public class CdmStore {
         return editorManager;
     }
 
+    public static ProgressMonitorClientManager getProgressMonitorClientManager() {
+        return progressMonitorClientManager;
+    }
+
     /*
      * IMPORT/EXPORT FACTORIES
      */
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/dialog/FeedbackMessageBox.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/dialog/FeedbackMessageBox.java
new file mode 100644 (file)
index 0000000..50b1568
--- /dev/null
@@ -0,0 +1,52 @@
+// $Id$
+/**
+* Copyright (C) 2015 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.ui.dialog;
+
+import java.io.Serializable;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+
+import eu.etaxonomy.taxeditor.operation.FeedbackGenerator;
+
+/**
+ * Feedback Generator corresponding to a {@link MessageBox}
+ *
+ * @author cmathew
+ * @date 29 Oct 2015
+ *
+ */
+public class FeedbackMessageBox extends FeedbackGenerator {
+
+    private Shell shell;
+    /**
+     * @param parent
+     */
+    public FeedbackMessageBox(Shell parent) {
+        this.shell = parent;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Serializable generateFeedback() {
+
+     // create a dialog with ok and cancel buttons and a question icon
+        MessageBox dialog =
+          new MessageBox(shell, SWT.ICON_QUESTION | SWT.OK| SWT.CANCEL);
+        dialog.setText("Monitor Feedback");
+        dialog.setMessage("Do you really want to continue?");
+
+        // open dialog and await user selection
+        return dialog.open();
+    }
+}
index bddb7a0f34ae25778b6189847a83ce8fa862b74d..4d088a4f3b912fef618696a214697691922df449 100644 (file)
@@ -50,6 +50,8 @@ import org.osgi.service.prefs.Preferences;
 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
 import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
+import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
 import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
 import eu.etaxonomy.taxeditor.remoting.source.CdmRemoteSource;
 import eu.etaxonomy.taxeditor.remoting.source.CdmServerInfo;
@@ -645,8 +647,12 @@ public class RemotingLoginDialog extends Dialog {
                 if(available) {
                     txtServerCDMVersion.setText(selectedCsii.getCdmRemoteSource(selectedCdmInstance, getPort()).getDbSchemaVersion());
                     int compareDbSchemaVersion = selectedCsii.compareDbSchemaVersion(selectedCdmInstance, getPort());
-                    int compareCdmlibServicesVersion = selectedCsii.compareCdmlibServicesVersion();
-
+                    int compareCdmlibServicesVersion = 0;
+                    boolean disableServicesApiTimestampCheck =
+                            PreferencesUtil.getPreferenceStore().getBoolean((IPreferenceKeys.DISABLE_SERVICES_API_TIMESTAMP_CHECK));
+                    if(!disableServicesApiTimestampCheck) {
+                        compareCdmlibServicesVersion = selectedCsii.compareCdmlibServicesVersion();
+                    }
                     if(compareDbSchemaVersion > 0 || compareCdmlibServicesVersion > 0) {
                         status =  STATUS_NOT_COMPATIBLE;
                         available = false;
@@ -660,10 +666,7 @@ public class RemotingLoginDialog extends Dialog {
                         available = true;
                         message = "";
                     }
-
-
                 }
-
             } catch (Exception e) {
                 txtCdmInstanceStatus.setToolTipText(e.getMessage());
             } finally {
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/dialog/ReportTextDialog.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/dialog/ReportTextDialog.java
new file mode 100644 (file)
index 0000000..d1cefe6
--- /dev/null
@@ -0,0 +1,134 @@
+// $Id$
+/**
+ * Copyright (C) 2015 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.ui.dialog;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author cmathew
+ * @date 22 Oct 2015
+ *
+ */
+public class ReportTextDialog extends Dialog {
+
+    private String reportText = "";
+    private String title = "";
+    /**
+     * Create the dialog.
+     * @param parentShell
+     */
+    public ReportTextDialog(Shell parentShell) {
+        super(parentShell);
+    }
+
+    /**
+     * Create contents of the dialog.
+     * @param parent
+     */
+    @Override
+    protected Control createDialogArea(final Composite parent) {
+        Composite container = (Composite) super.createDialogArea(parent);
+        GridLayout gridLayout = (GridLayout) container.getLayout();
+        gridLayout.numColumns = 2;
+
+        StyledText styledText = new StyledText(container, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.BORDER);
+        styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        styledText.setText(reportText);
+
+        Button btnSave = new Button(container, SWT.NONE);
+        btnSave.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                FileDialog fileDialog = new FileDialog(parent.getShell(), SWT.SAVE);
+                // Set filter on .txt files
+                fileDialog.setFilterExtensions(new String[] { "*.txt" });
+                // Put in a readable name for the filter
+                fileDialog.setFilterNames(new String[] { "Textfiles(*.txt)" });
+                String fileName = fileDialog.open();
+                System.out.println("File Name : " + fileName);
+                if(fileName != null) {
+                    File file = new File(fileName);
+                    if (file.exists()) {
+                        MessageBox mb = new MessageBox(fileDialog.getParent(), SWT.ICON_WARNING
+                                | SWT.YES | SWT.NO);
+                        mb.setMessage(fileName + " already exists. Do you want to replace it?");
+                        boolean override = mb.open() == SWT.YES;
+                        if(!override) {
+                            return;
+                        }
+                    }
+                    try {
+                        FileWriter fileWriter = new FileWriter(fileName, false);
+                        fileWriter.write(getReportText());
+                        fileWriter.close();
+                    } catch (IOException ioe) {
+                        throw new IllegalStateException(ioe);
+                    }
+                }
+            }
+        });
+        btnSave.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
+        btnSave.setText("save");
+
+        return container;
+    }
+
+    /**
+     * Create contents of the button bar.
+     * @param parent
+     */
+    @Override
+    protected void createButtonsForButtonBar(Composite parent) {
+        createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+    }
+
+    @Override
+    protected void configureShell(Shell shell) {
+        super.configureShell(shell);
+        shell.setText(title);
+     }
+    /**
+     * Return the initial size of the dialog.
+     */
+    @Override
+    protected Point getInitialSize() {
+        return new Point(669, 501);
+    }
+
+    public void setReportText(String text) {
+        this.reportText = text;
+    }
+
+    public String getReportText() {
+        return reportText;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+}
index 090413bb9fe20aea585212bfe59d5cfc7b5bce54..c041c7a236f72e651d1fa530b4921cde33c7375e 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$
 /**
 * Copyright (C) 2007 EDIT
-* European Distributed Institute of Taxonomy 
+* 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.
 */
@@ -32,11 +32,10 @@ import org.eclipse.swt.widgets.Event;
 import org.eclipse.ui.forms.widgets.TableWrapData;
 
 import eu.etaxonomy.cdm.common.UriUtils;
+import eu.etaxonomy.taxeditor.model.AbstractUtility;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
 
 /**
- * <p>ImageElement class.</p>
- *
  * @author n.hoffmann
  * @created Sep 24, 2010
  * @version 1.0
@@ -45,59 +44,41 @@ public class ImageElement extends AbstractCdmFormElement implements PaintListene
 
        private URI imageUri;
        private Image image;
-       
+
        private Composite container;
 
-       /**
-        * <p>Constructor for ImageElement.</p>
-        *
-        * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory} object.
-        * @param parentElement a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
-        * @param imageUri a {@link java.net.URI} object.
-        * @param style a int.
-        */
+       private final Runnable postRunnable = new Runnable(){
+        @Override
+        public void run() {
+            AbstractUtility.reflowDetailsViewer();
+            AbstractUtility.reflowSupplementalViewer();
+        }
+    };
+
        protected ImageElement(CdmFormFactory formFactory, ICdmFormElement parentElement, URI imageUri, int style) {
                super(formFactory, parentElement);
-                               
+
                container = new Composite(getLayoutComposite(), style);
                container.setLayoutData(LayoutConstants.FILL(2, 1));
-               
+
                container.addPaintListener(this);
        }
 
-       /**
-        * <p>Setter for the field <code>imageUri</code>.</p>
-        *
-        * @param uri a {@link java.net.URI} object.
-        * @throws HttpException 
-        * @throws IOException 
-        */
        public void initImageUri(URI uri) throws IOException, HttpException {
                this.imageUri = uri;
                InputStream imageStream = UriUtils.getInputStream(imageUri);
                image = new Image(Display.getCurrent(), imageStream);
        }
-       
-       
-       /**
-        * <p>Getter for the field <code>imageUri</code>.</p>
-        *
-        * @return the imageUri
-        */
+
+
        public URI getImageUri() {
                return imageUri;
        }
-       
+
        public void loadImage(){
-               loadImage(null);
-       }
-       
-       
-       
-       public void loadImage(final Runnable postRunnable){
                if(getImageUri() != null){
                        Job job = new Job("Loading image") {
-                               
+
                                @Override
                                protected IStatus run(IProgressMonitor monitor) {
                                        IRunnableWithProgress runnable = getLoadImageRunnable(postRunnable);
@@ -106,19 +87,17 @@ public class ImageElement extends AbstractCdmFormElement implements PaintListene
                                        } catch (Exception e) {
                                                MessagingUtils.messageDialog("Could not load image", getClass(), e.getMessage()  + ": " +  getImageUri(), e);
                                        }
-                                       
+
                                        return Status.OK_STATUS;
                                }
                        };
                        job.schedule();
                }
        }
-       
 
-
-       public void unloadImage(final Runnable postRunnable) {
+       public void unloadImage() {
                Job job = new Job("Unloading image") {
-                       
+
                        @Override
                        protected IStatus run(IProgressMonitor monitor) {
                                IRunnableWithProgress runnable = getLoadImageRunnable(postRunnable);
@@ -127,29 +106,29 @@ public class ImageElement extends AbstractCdmFormElement implements PaintListene
                                } catch (Exception e) {
                                        MessagingUtils.messageDialog("Could not unload image", getClass(), e.getMessage()  + ": " +  getImageUri(), e);
                                }
-                               
+
                                return Status.OK_STATUS;
                        }
                };
                job.schedule();
-               
+
        }
-       
+
        public IRunnableWithProgress getLoadImageRunnable(final Runnable postRunnable){
-                       
-               final Display display = getLayoutComposite().getDisplay(); 
-               
+
+               final Display display = getLayoutComposite().getDisplay();
+
                IRunnableWithProgress runnable = new IRunnableWithProgress(){
-                       
+
                        @Override
                        public void run(IProgressMonitor monitor) {
                                monitor.beginTask("Loading: " + getImageUri(), IProgressMonitor.UNKNOWN);
-                                                               
+
                                // redraw the image container
                                display.asyncExec(new Runnable(){
                                        @Override
                                        public void run() {
-                                               if(! getLayoutComposite().isDisposed()){
+                                               if(! getLayoutComposite().isDisposed() && container!=null){
                                                        Event untypedEvent = new Event();
                                                        untypedEvent.widget = container;
                                                        PaintEvent event = new PaintEvent(untypedEvent);
@@ -159,37 +138,45 @@ public class ImageElement extends AbstractCdmFormElement implements PaintListene
                                                }
                                        }
                                });
-                               
+
                                // execute the external runnable
                                if(postRunnable != null){
                                        display.asyncExec(postRunnable);
                                }
-                               monitor.done();         
+                               monitor.done();
                        }
 
                };
-               
+
                return runnable;
        }
-       
+
        private Rectangle calculateImageBounds(Image image, Control control){
                Rectangle imageBounds = image.getBounds();
                Rectangle containerBounds = control.getBounds();
-               
+
                Integer imgWidth = imageBounds.width;
                Integer imgHeight = imageBounds.height;
-               
+
                Float ratio = imgHeight.floatValue()/imgWidth.floatValue();
                Integer width = containerBounds.width;
                Integer height = ((Float) (width * ratio)).intValue();
-               
+
                return new Rectangle(containerBounds.x, containerBounds.y, width, height);
        }
 
+       public void dispose(){
+           if(image!=null){
+               image.dispose();
+               image = null;
+           }
+           imageUri = null;
+           if(container!=null){
+               container.dispose();
+               container = null;
+           }
+       }
 
-       /* (non-Javadoc)
-        * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
-        */
        /** {@inheritDoc} */
        @Override
        public void paintControl(PaintEvent e) {
index 7a5618b27e2fa1d5f9f73012d710bc414a6a4a48..f260d1b8ee4e19f4e4140595c70e63267b09161d 100644 (file)
@@ -19,7 +19,6 @@ import org.eclipse.swt.events.SelectionListener;
 
 import eu.etaxonomy.cdm.common.media.ImageInfo;
 import eu.etaxonomy.cdm.model.media.ImageFile;
-import eu.etaxonomy.taxeditor.model.AbstractUtility;
 import eu.etaxonomy.taxeditor.ui.element.AbstractFormSection;
 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
@@ -40,16 +39,6 @@ public class ImageFileElement extends MediaRepresentationPartElement<ImageFile>
        private KeyValueViewerElement element_keyValue;
        private ImageElement element_image;
 
-
-       private final Runnable postRunnable = new Runnable(){
-               @Override
-        public void run() {
-                       AbstractUtility.reflowDetailsViewer();
-                       AbstractUtility.reflowSupplementalViewer();
-               }
-       };
-
-
        public ImageFileElement(CdmFormFactory cdmFormFactory,
                        AbstractFormSection section, ImageFile element,
                        SelectionListener removeListener, int style) {
@@ -85,7 +74,7 @@ public class ImageFileElement extends MediaRepresentationPartElement<ImageFile>
        private void loadImage(URI uri, boolean updateDimensions) throws IOException, HttpException{
                element_image.initImageUri(uri);
 
-               element_image.loadImage(postRunnable );
+               element_image.loadImage();
 
 
                if(uri == null){
@@ -139,16 +128,10 @@ public class ImageFileElement extends MediaRepresentationPartElement<ImageFile>
        }
 
        protected void handleException(Exception e) {
-               element_image.unloadImage(postRunnable);
+               element_image.unloadImage();
                text_height.setNumber(0);
                text_width.setNumber(0);
 
-               element_image.loadImage(new Runnable(){
-                       @Override
-            public void run() {
-                               AbstractUtility.reflowDetailsViewer();
-                               AbstractUtility.reflowSupplementalViewer();
-                       }
-               });
+               element_image.loadImage();
        }
 }
index 750fc27cef907a0342620fea4c5718d49c8ea6f3..a2a6de62061cf58a6979d624fa55a0e59315df85 100644 (file)
@@ -9,10 +9,16 @@
 */
 package eu.etaxonomy.taxeditor.ui.section.media;
 
+import java.io.IOException;
 import java.net.URI;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.http.HttpException;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Label;
+
+import eu.etaxonomy.cdm.common.media.ImageInfo;
 import eu.etaxonomy.cdm.model.media.Media;
 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
 import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
@@ -22,6 +28,7 @@ import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
+import eu.etaxonomy.taxeditor.ui.element.ImageElement;
 import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
 import eu.etaxonomy.taxeditor.ui.element.UriWithLabelElement;
 import eu.etaxonomy.taxeditor.ui.section.AbstractCdmDetailElement;
@@ -45,6 +52,8 @@ public class MediaDetailElement extends AbstractCdmDetailElement<Media>{
      * Used to store the URI even if it is invalid and thus cannot be stored in CDM
      */
     private String uriBuffer;
+    private ImageElement element_image;
+    private Label lblNoImage;
 
     public MediaDetailElement(CdmFormFactory formFactory, ICdmFormElement formElement) {
         super(formFactory, formElement);
@@ -75,6 +84,19 @@ public class MediaDetailElement extends AbstractCdmDetailElement<Media>{
             if(uri==null){
                 uriBuffer=textUri.getText();
             }
+            else{
+
+                ImageInfo imageInfo;
+                try {
+                    imageInfo = ImageInfo.NewInstance(uri, 10000);
+                    singleMediaRepresentationPart.getMediaRepresentation().setMimeType(imageInfo.getMimeType());
+                    singleMediaRepresentationPart.getMediaRepresentation().setSuffix(imageInfo.getSuffix());
+                    element_image = formFactory.createImageElement(parentFormElement, uri, style);
+                    loadImage(singleMediaRepresentationPart.getUri());
+                } catch (Exception e) {
+                    handleException();
+                }
+            }
         }
     }
 
@@ -99,6 +121,10 @@ public class MediaDetailElement extends AbstractCdmDetailElement<Media>{
             if(textUri!=null){
                 removeElementsAndControls(textUri);
             }
+            if(element_image!=null){
+                element_image.dispose();
+                element_image = null;
+            }
             section_mediaRepresentation = formFactory.createMediaRepresentationSection(getConversationHolder(), parentFormElement, style);
             section_mediaRepresentation.setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
             section_mediaRepresentation.setEntity(getEntity());
@@ -120,6 +146,13 @@ public class MediaDetailElement extends AbstractCdmDetailElement<Media>{
                 textUri.parseText();
             }
             textUri.getLayoutComposite().layout();
+
+            element_image = formFactory.createImageElement(parentFormElement, null, style);
+            try {
+                loadImage(singleMediaRepresentationPart.getUri());
+            } catch (Exception e) {
+                handleException();
+            }
         }
     }
 
@@ -143,6 +176,27 @@ public class MediaDetailElement extends AbstractCdmDetailElement<Media>{
         isAdvancedMediaView =  false;
     }
 
+    private void loadImage(URI uri) throws IOException, HttpException{
+        element_image.initImageUri(uri);
+        element_image.loadImage();
+        if(uri == null){
+            return;
+        }
+        lblNoImage.dispose();
+        lblNoImage = null;
+    }
+
+    private void handleException() {
+        element_image.unloadImage();
+        element_image.loadImage();
+        element_image.dispose();
+        if(lblNoImage==null){
+            lblNoImage = formFactory.createLabel(getLayoutComposite(), "No Image found");
+            lblNoImage.setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
+            lblNoImage.setAlignment(SWT.CENTER);
+        }
+    }
+
     public boolean isAdvancedMediaView() {
         return isAdvancedMediaView;
     }
index 890942c61e989f509cabce7e616a7077c3d34224..4ff63d538b054474d860e11497154cc29f6843fa 100644 (file)
@@ -69,23 +69,21 @@ public class TaxonAssociationDetailElement extends AbstractCdmDetailElement<Deri
 
         //TODO add context menu for deleting associations
 
-        Label associationsLabel = formFactory.createLabel(getLayoutComposite(), "Individuals Associations");
-        associationsLabel.setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
-
-        associationsViewer = new TableViewer(getLayoutComposite(), SWT.FULL_SELECTION);
-        associationsViewer.getTable().setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
-        associationsViewer.setContentProvider(new ArrayContentProvider());
         Collection<TaxonBase<?>> associatedTaxa = CdmStore.getService(IOccurrenceService.class).listAssociatedTaxa(entity.innerDerivedUnit(), null, null, null, null);
-        associationsViewer.setInput(associatedTaxa);
-        associationsViewer.addDoubleClickListener(this);
+        Collection<SpecimenTypeDesignation> typeDesignations = CdmStore.getService(IOccurrenceService.class).listTypeDesignations(entity.innerDerivedUnit(), null, null, null, null);
 
-        Label typeLabel = formFactory.createLabel(getLayoutComposite(), "Type Designations");
-        typeLabel.setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
+        if(!associatedTaxa.isEmpty()){
+            associationsViewer = new TableViewer(getLayoutComposite(), SWT.FULL_SELECTION);
+            associationsViewer.getTable().setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
+            associationsViewer.setContentProvider(new ArrayContentProvider());
+            associationsViewer.setInput(associatedTaxa);
+            associationsViewer.addDoubleClickListener(this);
+        }
+        else{
+            Label label = formFactory.createLabel(getLayoutComposite(), "No associations");
+            label.setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
+        }
 
-        typeDesignationViewer = new TableViewer(getLayoutComposite(), SWT.FULL_SELECTION);
-        typeDesignationViewer.getTable().setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
-        typeDesignationViewer.setContentProvider(new ArrayContentProvider());
-        Collection<SpecimenTypeDesignation> typeDesignations = CdmStore.getService(IOccurrenceService.class).listTypeDesignations(entity.innerDerivedUnit(), null, null, null, null);
         //TODO implement service method for this which is just used in the label provider
         Collection<TaxonBase<?>> typedTaxa = new HashSet<TaxonBase<?>>();
         for (SpecimenTypeDesignation specimenTypeDesignation : typeDesignations) {
@@ -98,8 +96,16 @@ public class TaxonAssociationDetailElement extends AbstractCdmDetailElement<Deri
                 }
             }
         }
-        typeDesignationViewer.setInput(typedTaxa);
-        typeDesignationViewer.addDoubleClickListener(this);
+        if(!typedTaxa.isEmpty()){
+            Label typeLabel = formFactory.createLabel(getLayoutComposite(), "Type Designations");
+            typeLabel.setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
+
+            typeDesignationViewer = new TableViewer(getLayoutComposite(), SWT.FULL_SELECTION);
+            typeDesignationViewer.getTable().setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
+            typeDesignationViewer.setContentProvider(new ArrayContentProvider());
+            typeDesignationViewer.setInput(typedTaxa);
+            typeDesignationViewer.addDoubleClickListener(this);
+        }
     }
 
     /** {@inheritDoc} */
@@ -108,9 +114,6 @@ public class TaxonAssociationDetailElement extends AbstractCdmDetailElement<Deri
         //empty
     }
 
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
-     */
     @Override
     public void doubleClick(DoubleClickEvent event) {
         if(event.getSelection() instanceof IStructuredSelection){
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/util/ProgressMonitorClientManager.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/util/ProgressMonitorClientManager.java
new file mode 100644 (file)
index 0000000..5e7e97a
--- /dev/null
@@ -0,0 +1,151 @@
+// $Id$
+/**
+ * Copyright (C) 2015 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.util;
+
+import java.text.DecimalFormat;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
+import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
+import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
+import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
+
+/**
+ * Manages client side progress monitors
+ *
+ * @author cmathew
+ * @date 23 Oct 2015
+ *
+ */
+
+public class ProgressMonitorClientManager {
+    private static final Logger logger = Logger.getLogger(ProgressMonitorClientManager.class);
+
+    /**
+     * Polls the progress monitor service for the progress status of a monitor
+     * corresponding to the given uuid.
+     *
+     * @param label for the operation
+     * @param uuid of the remoting monitor already started on the server
+     * @param pollInterval in milliseconds
+     * @param cancelable flag which determines whether the operation can be cancelled
+     * @param postOp callback for running post operation logic
+     * @param feedbackGenerator feedback generator corresponding to the
+     *        'wait on feedback' request made on the remoting monitor
+     * @param monitor to be updated
+     * @return a final progress monitor after the operation is completed
+     * @throws InterruptedException
+     */
+    public IRemotingProgressMonitor pollMonitor(final String label,
+            final UUID uuid,
+            final int pollInterval,
+            final IPostMoniteredOperationEnabled postOp,
+            IFeedbackGenerator feedbackGenerator,
+            IProgressMonitor monitor) throws InterruptedException {
+        return pollMonitor(label, uuid, pollInterval, postOp, Arrays.asList(feedbackGenerator), monitor);
+    }
+    /**
+     * Polls the progress monitor service for the progress status of a monitor
+     * corresponding to the given uuid.
+     *
+     *
+     * @param label for the operation
+     * @param uuid of the remoting monitor already started on the server
+     * @param pollInterval in milliseconds
+     * @param cancelable flag which determines whether the operation can be cancelled
+     * @param postOp callback for running post operation logic
+     * @param feedbackGenerators list of feedback generators corresponding to the
+     *        size and exact order of the 'wait on feedback' requests made on the
+     *        remoting monitor
+     * @param monitor to be updated
+     * @return a final progress monitor after the operation is completed
+     * @throws InterruptedException
+     */
+    public IRemotingProgressMonitor pollMonitor(final String label,
+            final UUID uuid,
+            final int pollInterval,
+            final IPostMoniteredOperationEnabled postOp,
+            List<IFeedbackGenerator> feedbackGenerators,
+            IProgressMonitor monitor) throws InterruptedException {
+        IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
+        IRemotingProgressMonitor remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
+        try {
+            final int START_DELAY=10;
+            // wait about 10 seconds for the remoting monitor to be initialised
+            // (i.e. for the begin task method to be called ON THE REMOTING MONITOR)
+            for(int i=0;i<START_DELAY;i++) {
+                Thread.sleep(1000);
+                logger.info("Waiting for monitered work to start ..");
+                remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
+                if(remotingMonitor.getTotalWork() > 0) {
+                    break;
+                }
+            }
+            // if the total work is still not been set then we assume that the
+            // operation has zero work units
+            if(remotingMonitor.getTotalWork() == 0) {
+                throw new InterruptedException("Monitor has zero work units");
+            }
+            // start the client monitor
+            monitor.beginTask(label, remotingMonitor.getTotalWork());
+            logger.info("Work to be done: " + remotingMonitor.getTotalWork());
+            int editorTotalWorkDone = 0;
+            int serverTotalWorkDone = 0;
+            // loop until the operation is done
+            int feedbackCount = 0;
+            while(!(remotingMonitor.isCanceled() || remotingMonitor.isFailed() || remotingMonitor.isDone())) {
+                // wait for pollInterval, then
+                // .... retrieve remoting monitor, then
+                //      .... set client monitor info
+                Thread.sleep(pollInterval);
+                remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
+                // check if remoting monitor is waiting for feedback
+                if(remotingMonitor.getIsWaitingForFeedback()) {
+                    if(feedbackGenerators != null) {
+                        // if we have run out of feedback generators while
+                        // the remoting monitor is waiting on feedback
+                        // then throw exception
+                        if(feedbackCount + 1 > feedbackGenerators.size()) {
+                            throw new IllegalStateException("Remoting monitor waiting on feedback that does not exist");
+                        }
+                        feedbackGenerators.get(feedbackCount).setFeedbackForMonitor(uuid);
+                        feedbackCount++;
+                    }
+                }
+                serverTotalWorkDone = (int) remotingMonitor.getWorkDone();
+                logger.info("Work done from start: " + serverTotalWorkDone);
+                String percentage = new DecimalFormat("#.##").format(remotingMonitor.getPercentage());
+                // set dialog text
+                monitor.setTaskName(label + " " + percentage + "% done ");
+                monitor.subTask(remotingMonitor.getSubTask());
+                int worked = serverTotalWorkDone - editorTotalWorkDone;
+                if(worked > 0) {
+                    logger.info("Work done since last check: " + worked);
+                    monitor.worked(worked);
+                }
+                editorTotalWorkDone = serverTotalWorkDone;
+            }
+            if(remotingMonitor.getResult() instanceof Exception) {
+                throw new IllegalStateException((Exception)remotingMonitor.getResult());
+            }
+            return remotingMonitor;
+        } finally {
+            if(postOp != null && remotingMonitor.isDone()) {
+                postOp.postOperation(remotingMonitor);
+            }
+        }
+    }
+}
index 5908ab91e92db921f6b6fcf5991d089c43ae1182..8618277b452902f3adb4b24a438903e79817a655 100644 (file)
@@ -578,26 +578,27 @@ public class DetailsViewer extends AbstractCdmDataViewer {
             FieldUnitDetailSection fieldUnitDetailSection = formFactory.createFieldUnitDetailSection(getConversationHolder(), parent, this, ExpandableComposite.TWISTIE);
             addPart(fieldUnitDetailSection);
         }
+        else{
 
+            if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_TAXON_ASSOCIATIONS)){
+                formFactory.createHorizontalSeparator(parent, SWT.BORDER);
+                TaxonAssociationDetailSection taxonAssociationDetailSection = formFactory.createTaxonAssociationDetailSection(getConversationHolder(), parent, this, ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED);
+                addPart(taxonAssociationDetailSection);
+            }
+            formFactory.createHorizontalSeparator(parent, SWT.BORDER);
+            IdentifierDetailSection identifierDetailSection = formFactory.createIdentifierDetailSection(getConversationHolder(), parent, ExpandableComposite.TWISTIE);
+            addPart(identifierDetailSection);
+        }
         if(!PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.DETERMINATION_ONLY_FOR_FIELD_UNITS)){
             formFactory.createHorizontalSeparator(parent, SWT.BORDER);
             DeterminationDetailSection determinationDetailSection = formFactory.createDeterminationDetailSection(getConversationHolder(), parent, this, ExpandableComposite.TWISTIE);
             addPart(determinationDetailSection);
         }
-        if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_TAXON_ASSOCIATIONS)){
-            formFactory.createHorizontalSeparator(parent, SWT.BORDER);
-            TaxonAssociationDetailSection taxonAssociationDetailSection = formFactory.createTaxonAssociationDetailSection(getConversationHolder(), parent, this, ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED);
-            addPart(taxonAssociationDetailSection);
-        }
 
         formFactory.createHorizontalSeparator(parent, SWT.BORDER);
         DerivedUnitTypeDesignationSection derivedUnitTypeDesignationSection = formFactory.createDerivedUnitTypeDesignationSection(getConversationHolder(), parent, this, ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED);
         addPart(derivedUnitTypeDesignationSection);
 
-        formFactory.createHorizontalSeparator(parent, SWT.BORDER);
-        IdentifierDetailSection identifierDetailSection = formFactory.createIdentifierDetailSection(getConversationHolder(), parent, ExpandableComposite.TWISTIE);
-        addPart(identifierDetailSection);
-
     }
 
     private void createFieldUnitSection(RootElement parent) {
index 694d80e57e2f7830ea1834dd4dbaa11fde34ac65..8a0e1859127e0d36acca4fa39462c6d44eb359ba 100644 (file)
@@ -30,7 +30,6 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.context.SecurityContextImpl;
-import org.unitils.UnitilsJUnit4;
 import org.unitils.database.DatabaseUnitils;
 import org.unitils.database.annotations.Transactional;
 import org.unitils.database.util.TransactionMode;
@@ -61,7 +60,7 @@ import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager;
  */
 @Transactional(TransactionMode.DISABLED)
 @SpringApplicationContext("file:./target/classes/eu/etaxonomy/cdm/testRemotingApplicationContext.xml")
-public abstract class BaseRemotingTest extends UnitilsJUnit4 {
+public abstract class BaseRemotingTest extends ThreadedTest {
     private static final Logger logger = Logger.getLogger(BaseRemotingTest.class);
 
 
@@ -84,6 +83,7 @@ public abstract class BaseRemotingTest extends UnitilsJUnit4 {
     private static String user = DEFAULT_USER;
     private static String password = DEFAULT_PASSWORD;
 
+
     protected static CDMServer cdmServer;
 
     @BeforeClass
@@ -136,8 +136,7 @@ public abstract class BaseRemotingTest extends UnitilsJUnit4 {
            // Assert.fail("Server failed to start. Reason : " + e.getMessage());
         }
 
-        logger.info("Emptying all caches (except model cache) ");
-        //emptyAllCachesExceptModelCache();
+
     }
 
     public static void emptyAllCachesExceptModelCache() {
@@ -172,6 +171,12 @@ public abstract class BaseRemotingTest extends UnitilsJUnit4 {
 
         CdmApplicationState.setCurrentDataChangeService(new CdmDataChangeService());
 
+        authenticate(username, password);
+
+    }
+
+    protected static void authenticate(String username, String password) {
+
         //FIXME:Remoting the authentication code should be replaced by a method call which actually
         // does the authentication in the editor code so that the 'real' authentication can be tested
         SecurityContextHolder.clearContext();
@@ -183,8 +188,8 @@ public abstract class BaseRemotingTest extends UnitilsJUnit4 {
 
         SecurityContextHolder.setContext(sc);
         CdmApplicationState.setCurrentSecurityContext(SecurityContextHolder.getContext());
-    }
 
+    }
 
 
     protected static CdmApplicationRemoteController getRemoteApplicationController() {
@@ -211,7 +216,7 @@ public abstract class BaseRemotingTest extends UnitilsJUnit4 {
     }
 
     protected static CdmEntitySession getActiveSession() {
-        return (CdmEntitySession) getFieldValueViaReflection(cdmEntitySessionManager, "activeSession");
+        return ((InheritableThreadLocal<CdmEntitySession>) getFieldValueViaReflection(cdmEntitySessionManager, "tlActiveSession")).get();
     }
 
     protected static CdmTransientEntityCacher getCacher(ICdmEntitySessionEnabled sessionOwner) {
@@ -238,6 +243,9 @@ public abstract class BaseRemotingTest extends UnitilsJUnit4 {
     }
 
 
+    protected static void authenticateDefaultUser() {
+        authenticate(user, password);
+    }
 
 
 }
index 2ef07d2aa874041b1d8883821401acd849038009..1949ce3b8941483bf2e75d23505a28bf8abe17ee 100644 (file)
@@ -12,8 +12,12 @@ package eu.etaxonomy.taxeditor.httpinvoker;
 import org.apache.log4j.Logger;
 import org.junit.After;
 import org.junit.Before;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+import eu.etaxonomy.cdm.api.service.IUserService;
+import eu.etaxonomy.cdm.model.common.User;
 import eu.etaxonomy.taxeditor.remoting.cache.CdmTransientEntityCacher;
 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
 import eu.etaxonomy.taxeditor.session.MockSessionOwner;
@@ -30,6 +34,11 @@ public abstract class RemotingSessionAwareTest extends BaseRemotingTest {
     protected CdmTransientEntityCacher cacher;
     protected MockSessionOwner sessionOwner;
 
+    private static String extraUsername = "Someone";
+    private static String extraPassword = "Password";
+
+
+    private IUserService userService = getRemoteApplicationController().getUserService();
 
     @Before
     public void initializeSession() {
@@ -40,6 +49,17 @@ public abstract class RemotingSessionAwareTest extends BaseRemotingTest {
         CdmApplicationState.getCurrentDataChangeService().register(sessionOwner);
         sessionOwner.setCdmEntitySession(cdmEntitySession);
         cacher = getCacher(sessionOwner);
+
+        UserDetails extraUser = null;
+
+        try {
+            extraUser = userService.loadUserByUsername(extraUsername);
+        } catch (UsernameNotFoundException unfe) {
+            User user = User.NewInstance(extraUsername, extraPassword);
+            userService.createUser(user);
+        }
+
+
     }
 
     @After
@@ -48,4 +68,10 @@ public abstract class RemotingSessionAwareTest extends BaseRemotingTest {
         CdmApplicationState.getCurrentDataChangeService().unregister(sessionOwner);
         logger.info("disposed of mock session owner : " + sessionOwner);
     }
+
+
+    protected static void authenticateExtraUser() {
+        authenticate(extraUsername, extraPassword);
+    }
+
 }
diff --git a/eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/TestThread.java b/eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/TestThread.java
new file mode 100644 (file)
index 0000000..b70f802
--- /dev/null
@@ -0,0 +1,60 @@
+// $Id$
+/**
+ * Copyright (C) 2015 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.httpinvoker;
+
+/**
+ * @author cmathew
+ * @date 16 Oct 2015
+ *
+ */
+public abstract class TestThread extends Thread {
+    Throwable throwable;
+    boolean isBlocked = false;
+
+    public TestThread() {
+
+    }
+
+    public TestThread(boolean blocking) {
+        isBlocked = blocking;
+    }
+    /**
+     * @return the throwable
+     */
+    public Throwable getThrowable() {
+        return throwable;
+    }
+
+    /**
+     * @param throwable the throwable to set
+     */
+    public void setThrowable(Throwable throwable) {
+        this.throwable = throwable;
+    }
+
+    public void unblock() {
+        isBlocked = false;
+    }
+
+    @Override
+    public final void run() {
+        try {
+            while(isBlocked) {};
+            doRun();
+        } catch(Exception ex) {
+            throwable = ex;
+        } catch(AssertionError ae) {
+            throwable = ae;
+        }
+    }
+
+    public abstract void doRun() throws Exception, AssertionError;
+
+}
diff --git a/eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/ThreadedTest.java b/eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/ThreadedTest.java
new file mode 100644 (file)
index 0000000..bea9a62
--- /dev/null
@@ -0,0 +1,50 @@
+// $Id$
+/**
+* Copyright (C) 2015 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.httpinvoker;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.After;
+import org.unitils.UnitilsJUnit4;
+
+/**
+ * @author cmathew
+ * @date 16 Oct 2015
+ *
+ */
+public abstract class ThreadedTest extends UnitilsJUnit4 {
+
+    private Set<TestThread> threadPool = new HashSet<TestThread>();
+
+    protected void invokeThread(TestThread thread) {
+        threadPool.add(thread);
+        thread.start();
+    }
+
+    @After
+    public void cleanup() throws Throwable {
+        try {
+            for(TestThread thread : threadPool) {
+                if(thread.isAlive()) {
+                    thread.join();
+                }
+            }
+
+            for(TestThread thread : threadPool) {
+                if(thread.getThrowable() != null) {
+                    throw thread.getThrowable();
+                }
+            }
+        } finally {
+            threadPool.clear();
+        }
+    }
+}
diff --git a/eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/service/ProgressMonitorServiceTest.java b/eu.etaxonomy.taxeditor.test/src/test/java/eu/etaxonomy/taxeditor/service/ProgressMonitorServiceTest.java
new file mode 100644 (file)
index 0000000..76df490
--- /dev/null
@@ -0,0 +1,329 @@
+// $Id$
+/**
+ * Copyright (C) 2015 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.service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
+import eu.etaxonomy.cdm.api.service.ITestService;
+import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
+import eu.etaxonomy.cdm.common.monitor.RemotingProgressMonitor;
+import eu.etaxonomy.taxeditor.httpinvoker.RemotingSessionAwareTest;
+import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
+import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+
+/**
+ * @author cmathew
+ * @date 22 Oct 2015
+ *
+ */
+public class ProgressMonitorServiceTest extends RemotingSessionAwareTest {
+
+    private static final Logger logger = Logger.getLogger(ProgressMonitorServiceTest.class);
+
+    ITestService testService =  getRemoteApplicationController().getTestService();
+
+    IProgressMonitorService progressMonitorService = getRemoteApplicationController().getProgressMonitorService();
+
+
+
+    @After
+    public void revertAuthentication() {
+        authenticateDefaultUser();
+    }
+
+    @Test
+    public void testMonitLongRunningMethod() throws InterruptedException {
+        UUID uuid = testService.monitLongRunningMethod(null, null, 0);
+        int pollInterval = 1000;
+        RemotingProgressMonitor expectedMonitor = new RemotingProgressMonitor();
+        expectedMonitor.setResult("Success");
+        expectedMonitor.addReport("Report");
+        expectedMonitor.done();
+        CdmStore.getProgressMonitorClientManager().pollMonitor("Testing Progress Monitor",
+                uuid,
+                pollInterval,
+                new MockPostMoniteredOperationEnabled(expectedMonitor, uuid),
+                (IFeedbackGenerator)null,
+                new NullProgressMonitor());
+    }
+
+    @Test
+    public void testMonitLongRunningMethodByChangingUser() throws InterruptedException {
+
+        IllegalStateException ise = new IllegalStateException("IllegalStateException");
+        UUID uuid = testService.monitLongRunningMethod(ise, null, 0);
+        authenticateExtraUser();
+        IRemotingProgressMonitor monitor = progressMonitorService.getRemotingMonitor(uuid);
+        Assert.assertNull(monitor);
+
+    }
+
+    @Test
+    public void testMonitLongRunningMethodWithException() throws InterruptedException {
+        IllegalStateException ise = new IllegalStateException("IllegalStateException");
+        UUID uuid = testService.monitLongRunningMethod(ise, null, 0);
+        int pollInterval = 1000;
+        RemotingProgressMonitor expectedMonitor = new RemotingProgressMonitor();
+        expectedMonitor.setResult(ise);
+        expectedMonitor.setIsFailed(true);
+        expectedMonitor.done();
+        try {
+            CdmStore.getProgressMonitorClientManager().pollMonitor("Testing Progress Monitor",
+                    uuid,
+                    pollInterval,
+                    new MockPostMoniteredOperationEnabled(expectedMonitor, uuid),
+                    (IFeedbackGenerator)null,
+                    new NullProgressMonitor());
+            Assert.fail("Exception due to inconsistent number of feedback generators not thrown");
+        } catch(IllegalStateException e) {
+
+        }
+    }
+
+    @Test
+    public void testMonitLongRunningMethodWithInterrupt() {
+        IllegalStateException ise = new IllegalStateException("Interrupted Exception");
+        final UUID uuid = testService.monitLongRunningMethod(ise, null, 0);
+        final int pollInterval = 1000;
+        final RemotingProgressMonitor expectedMonitor = new RemotingProgressMonitor();
+        expectedMonitor.setResult(ise);
+        expectedMonitor.setCanceled(true);
+        expectedMonitor.setIsFailed(true);
+        expectedMonitor.done();
+
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    CdmStore.getProgressMonitorClientManager().pollMonitor("Testing Progress Monitor",
+                            uuid,
+                            pollInterval,
+                            null,
+                            (IFeedbackGenerator)null,
+                            new NullProgressMonitor());
+                    Assert.fail("InterruptedException wrapped in an IllegalStateException should be thrown");
+                } catch (InterruptedException e) {
+
+                } catch (IllegalStateException e) {
+
+                }
+            }
+        };
+        thread.start();
+        while(!progressMonitorService.isMonitorThreadRunning(uuid)) {}
+
+        progressMonitorService.interrupt(uuid);
+
+        while(progressMonitorService.isMonitorThreadRunning(uuid)) {}
+
+        IRemotingProgressMonitor remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
+        new MockPostMoniteredOperationEnabled(expectedMonitor, uuid).postOperation(remotingMonitor);
+
+    }
+
+    @Test
+    public void testMonitLongRunningMethodWithCancellation() throws InterruptedException {
+
+        final UUID uuid = testService.monitLongRunningMethod(null, null, 0);
+        final int pollInterval = 1000;
+        final RemotingProgressMonitor expectedMonitor = new RemotingProgressMonitor();
+        expectedMonitor.setResult("Cancelled");
+        expectedMonitor.setCanceled(true);
+        expectedMonitor.done();
+
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    CdmStore.getProgressMonitorClientManager().pollMonitor("Testing Progress Monitor",
+                            uuid,
+                            pollInterval,
+                            null,
+                            (IFeedbackGenerator)null,
+                            new NullProgressMonitor());
+                } catch (InterruptedException e) {
+
+                }
+            }
+
+        };
+        thread.start();
+        while(!progressMonitorService.isMonitorThreadRunning(uuid)) {}
+        progressMonitorService.cancel(uuid);
+        while(progressMonitorService.isMonitorThreadRunning(uuid)) {}
+        IRemotingProgressMonitor remotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
+        new MockPostMoniteredOperationEnabled(expectedMonitor, uuid).postOperation(remotingMonitor);
+
+    }
+
+    @Test
+    public void testMonitLongRunningMethodWithWaitForFeedback() throws InterruptedException {
+
+        List<String> feedbacks = Arrays.asList("feedback1", "feedback2");
+        List<IFeedbackGenerator> feebackGenerators = new ArrayList<IFeedbackGenerator>();
+        final RemotingProgressMonitor expectedMonitor = new RemotingProgressMonitor();
+        expectedMonitor.setResult("Success");
+        for(String feedback : feedbacks) {
+            feebackGenerators.add(new MockFeedbackGenerator(feedback, 0));
+            expectedMonitor.addReport(feedback);
+        }
+        expectedMonitor.addReport("Report");
+        expectedMonitor.done();
+
+        final UUID uuid = testService.monitLongRunningMethod(null, feedbacks, 0);
+        final int pollInterval = 1000;
+
+        CdmStore.getProgressMonitorClientManager().pollMonitor("Testing Progress Monitor",
+                uuid,
+                pollInterval,
+                new MockPostMoniteredOperationEnabled(expectedMonitor, uuid),
+                feebackGenerators,
+                new NullProgressMonitor());
+
+    }
+
+    @Test
+    public void testMonitLongRunningMethodWithInconsistentWaitForFeedback() throws InterruptedException {
+
+        List<String> feedbacks = Arrays.asList("feedback1", "feedback2");
+        List<IFeedbackGenerator> feebackGenerators = new ArrayList<IFeedbackGenerator>();
+        final RemotingProgressMonitor expectedMonitor = new RemotingProgressMonitor();
+        expectedMonitor.setResult("Success");
+        for(String feedback : feedbacks) {
+            feebackGenerators.add(new MockFeedbackGenerator(feedback, 0));
+            expectedMonitor.addReport(feedback);
+        }
+        expectedMonitor.addReport("Report");
+        expectedMonitor.done();
+
+        final UUID uuid = testService.monitLongRunningMethod(null, feedbacks, 0);
+        final int pollInterval = 1000;
+
+        feebackGenerators.remove(1);
+
+        final UUID newUuid = testService.monitLongRunningMethod(null, feedbacks, 0);
+
+        try {
+            CdmStore.getProgressMonitorClientManager().pollMonitor("Testing Progress Monitor",
+                    newUuid,
+                    pollInterval,
+                    new MockPostMoniteredOperationEnabled(expectedMonitor, newUuid),
+                    feebackGenerators,
+                    new NullProgressMonitor());
+            Assert.fail("Exception due to inconsistent number of feedback generators not thrown");
+        } catch(IllegalStateException ise) {
+
+        }
+    }
+
+    @Test
+    public void testMonitLongRunningMethodWithWaitForFeedbackTimeout() throws InterruptedException {
+
+        List<String> feedbacks = Arrays.asList("feedback1");
+        List<IFeedbackGenerator> feebackGenerators = new ArrayList<IFeedbackGenerator>();
+        final RemotingProgressMonitor expectedMonitor = new RemotingProgressMonitor();
+        expectedMonitor.setResult(new IllegalStateException(new InterruptedException()));
+        for(String feedback : feedbacks) {
+            feebackGenerators.add(new MockFeedbackGenerator(feedback, 1000 * 15));
+
+        }
+        expectedMonitor.setCanceled(true);
+        expectedMonitor.setIsFailed(true);
+        expectedMonitor.done();
+
+        expectedMonitor.done();
+
+        final UUID uuid = testService.monitLongRunningMethod(null, feedbacks, 1000 * 5);
+        final int pollInterval = 1000;
+
+
+        try {
+            CdmStore.getProgressMonitorClientManager().pollMonitor("Testing Progress Monitor",
+                    uuid,
+                    pollInterval,
+                    new MockPostMoniteredOperationEnabled(expectedMonitor, uuid),
+                    feebackGenerators,
+                    new NullProgressMonitor());
+            Assert.fail("Exception due to inconsistent number of feedback generators not thrown");
+        } catch(IllegalStateException ise) {
+
+        }
+    }
+
+
+    class MockPostMoniteredOperationEnabled implements IPostMoniteredOperationEnabled {
+
+        private RemotingProgressMonitor expectedMonitor;
+        private UUID monitorUuid;
+
+        public MockPostMoniteredOperationEnabled(RemotingProgressMonitor expectedMonitor, UUID monitorUuid) {
+            this.expectedMonitor = expectedMonitor;
+            this.monitorUuid = monitorUuid;
+        }
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void postOperation(IRemotingProgressMonitor monitor) {
+            if(expectedMonitor.getResult() instanceof Exception) {
+                Exception expectedException = (Exception) expectedMonitor.getResult();
+                Exception exception = (Exception) monitor.getResult();
+                Assert.assertEquals(expectedException.getClass(), expectedException.getClass());
+                Assert.assertEquals(expectedException.getMessage(), expectedException.getMessage());
+            } else {
+                Assert.assertEquals(expectedMonitor.getResult(), monitor.getResult());
+            }
+            Assert.assertEquals(expectedMonitor.getReports(), monitor.getReports());
+            Assert.assertEquals(expectedMonitor.isCanceled(), monitor.isCanceled());
+            Assert.assertEquals(expectedMonitor.isFailed(), monitor.isFailed());
+            Assert.assertEquals(expectedMonitor.isDone(), monitor.isDone());
+            Assert.assertTrue(!progressMonitorService.isMonitorThreadRunning(monitorUuid));
+        }
+    }
+
+    class MockFeedbackGenerator implements IFeedbackGenerator {
+
+        private String feedback;
+        private long waitTime;
+
+        public MockFeedbackGenerator(String feedback, long waitTime) {
+            this.feedback = feedback;
+            this.waitTime = waitTime;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void setFeedbackForMonitor(UUID uuid) {
+            if(waitTime > 0) {
+                try {
+                    Thread.sleep(waitTime);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+            CdmApplicationState.getCurrentAppConfig().getProgressMonitorService().setFeedback(uuid, feedback);
+        }
+
+    }
+}
index ed9579b1dbeb9e1a9bcf2c284472889b5ffef97c..88d5b24a7ea923de303c44d38584c343a6458506 100644 (file)
@@ -20,7 +20,6 @@ import org.apache.log4j.Logger;
 import org.hibernate.collection.spi.PersistentCollection;
 import org.junit.Assert;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.unitils.dbunit.annotation.DataSet;
 
@@ -49,6 +48,7 @@ import eu.etaxonomy.cdm.model.description.PolytomousKeyNode;
 import eu.etaxonomy.cdm.model.media.Rights;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
 import eu.etaxonomy.taxeditor.httpinvoker.RemotingSessionAwareTest;
+import eu.etaxonomy.taxeditor.httpinvoker.TestThread;
 
 /**
  * @author cmathew
@@ -478,29 +478,42 @@ public class CdmEntitySessionAwareTest extends RemotingSessionAwareTest {
         }
     }
 
-    @Ignore // activate after fixing #5138
+
     @Test
     public void updatePerson() {
+        // Test for #5138
         Person person = (Person) CdmApplicationState.getCurrentAppConfig().getAgentService().load(personUuid);
-        // Note : at this point the contact field in Person (AgentBase) is initialized even though no
-        //        data related to the Contact class exists in the database.
         person.setFirstname("Me");
         CdmApplicationState.getCurrentAppConfig().getAgentService().merge(person);
-
     }
 
-    @Ignore // activate after fixing #5138
+
     @Test
     public void createPerson() {
-
+        // Test for #5138
         Person person = Person.NewInstance();
-        //person.setTitleCache("New Person", true);
         person = (Person) CdmApplicationState.getCurrentAppConfig().getAgentService().merge(person);
-        //Note : at this point the contact field in Person (AgentBase) is set to null which is
-        //       different behaviour as compared to a load call on an existing Person entity.
-        //       The fact that the contact is null will lead to the all-delete-orphan error.
         person = (Person) CdmApplicationState.getCurrentAppConfig().getAgentService().load(person.getUuid());
         person.setFirstname("Some");
         CdmApplicationState.getCurrentAppConfig().getAgentService().merge(person);
     }
+
+    @Test
+    public void testThreadLocalActiveSession() throws InterruptedException {
+        MockSessionOwner<CdmBase> so1 = new MockSessionOwner<CdmBase>();
+        final ICdmEntitySession activeSession = getCdmEntitySessionManager().newSession(so1, true);
+        TestThread thread = new TestThread(true) {
+            @Override
+            public void doRun() throws InterruptedException {
+                ICdmEntitySession threadLocalActiveSession = getCdmEntitySessionManager().getActiveSession();
+                Assert.assertEquals(threadLocalActiveSession, activeSession);
+            }
+        };
+        invokeThread(thread);
+        MockSessionOwner<CdmBase> so2 = new MockSessionOwner<CdmBase>();
+        ICdmEntitySession newActiveSession = getCdmEntitySessionManager().newSession(so2, true);
+        Assert.assertFalse(activeSession.equals(newActiveSession));
+        thread.unblock();
+
+    }
 }