cleanup
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / view / e4 / AbstractCdmEditorPartE4.java
index 7f4b6cb93c44d061b4a87c2a2572cbc74fc48cd4..de6e851c89c971f162340653f453ca9c186a6afe 100644 (file)
@@ -8,38 +8,53 @@
 */
 package eu.etaxonomy.taxeditor.view.e4;
 
+import java.util.Collection;
 import java.util.Set;
 
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Named;
 
+import org.apache.log4j.Logger;
+import org.eclipse.e4.core.contexts.IEclipseContext;
 import org.eclipse.e4.core.di.annotations.Optional;
 import org.eclipse.e4.ui.di.PersistState;
+import org.eclipse.e4.ui.di.UISynchronize;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IEditorPart;
+import org.eclipse.swt.SWTException;
+import org.springframework.security.core.GrantedAuthority;
 
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
+import eu.etaxonomy.cdm.api.service.ITermNodeService;
+import eu.etaxonomy.cdm.api.service.ITermService;
+import eu.etaxonomy.cdm.api.service.IVocabularyService;
 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
 import eu.etaxonomy.cdm.model.common.CdmBase;
-import eu.etaxonomy.cdm.model.description.Distribution;
+import eu.etaxonomy.cdm.model.name.TaxonName;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
-import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
+import eu.etaxonomy.cdm.persistence.dto.TermNodeDto;
+import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
-import eu.etaxonomy.taxeditor.editor.IDistributionEditor;
+import eu.etaxonomy.taxeditor.editor.IBulkEditor;
 import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
-import eu.etaxonomy.taxeditor.model.AbstractUtility;
 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
+import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
+import eu.etaxonomy.taxeditor.security.RequiredPermissions;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
 import eu.etaxonomy.taxeditor.view.e4.details.DetailsViewerE4;
 import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
 import eu.etaxonomy.taxeditor.workbench.part.ISelectionElementEditingPart;
@@ -47,18 +62,19 @@ import eu.etaxonomy.taxeditor.workbench.part.ISelectionElementEditingPart;
 /**
  * @author pplitzner
  * @since Aug 10, 2017
- *
  */
 public abstract class AbstractCdmEditorPartE4
         implements IConversationEnabled, IDirtyMarkable, ISelectionElementEditingPart, IPostOperationEnabled{
 
-    private DelaySelection delaySelection = null;
+       private static final Logger logger = Logger.getLogger(AbstractCdmEditorPartE4.class);
+
+       private DelaySelection delaySelection = null;
     /**
      * This is the monitor for the DelaySelection runnable.
      * If it is <code>true</code> then it is currently delaying a selection.
      */
     private boolean isInDelay;
-
+    private boolean isEnabled = true;
 
     /**
      * This class invokes internal_selectionChanged() in a separate thread.
@@ -97,31 +113,6 @@ public abstract class AbstractCdmEditorPartE4
         public synchronized void setThisPart(MPart thisPart) {
             this.thisPart = thisPart;
         }
-
-    }
-
-    protected abstract void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart);
-
-    @Inject
-    @Optional
-    public void selectionChanged(
-            @Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
-            @Named(IServiceConstants.ACTIVE_PART)MPart activePart,
-            MPart thisPart){
-        Object savablePart = WorkbenchUtility.findSavablePart(this);
-        if(savablePart==null){
-            showEmptyPage();
-        }
-        if(delaySelection==null){
-            delaySelection = new DelaySelection(selection, activePart, thisPart);
-        }
-        delaySelection.setSelection(selection);
-        delaySelection.setActivePart(activePart);
-        delaySelection.setThisPart(thisPart);
-        if(!isInDelay){
-            isInDelay = true;
-            Display.getCurrent().asyncExec(delaySelection);
-        }
     }
 
     protected Viewer viewer;
@@ -130,6 +121,8 @@ public abstract class AbstractCdmEditorPartE4
 
     protected MPart selectionProvidingPart;
 
+    protected Object previousSelection;
+
     protected ISelectionChangedListener selectionChangedListener;
 
     public ISelectionChangedListener getSelectionChangedListener() {
@@ -139,7 +132,64 @@ public abstract class AbstractCdmEditorPartE4
     @Inject
     protected ESelectionService selService;
 
-    /** {@inheritDoc} */
+    @Inject
+    protected IEclipseContext context;
+
+    protected abstract void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart);
+
+    protected boolean showEmptyIfNoActiveEditor(){
+        return true;
+    }
+
+    @Inject
+    public void selectionChanged(
+            @Optional@Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
+            @Optional@Named(IServiceConstants.ACTIVE_PART)MPart activePart,
+            MPart thisPart, UISynchronize sync, EPartService partService){
+        //multiple selections are not supported
+        if(activePart!=null
+                && thisPart!=null
+                && !activePart.equals(thisPart)
+                && selection instanceof IStructuredSelection
+                && ((IStructuredSelection) selection).size()>1){
+            showEmptyPage();
+            return;
+        }
+        // no active editor found
+        if(activePart==thisPart && WorkbenchUtility.getActiveEditorPart(partService)==null && showEmptyIfNoActiveEditor()){
+            showEmptyPage();
+            return;
+        }
+        if (viewer != null && viewer.getControl()!= null && viewer.getInput() != null && !viewer.getControl().isDisposed()){
+           try{
+               viewer.getControl().setEnabled(isEnabled);
+           }catch(SWTException e){
+              logger.debug("Something went wrong for viewer.getControl().setEnabled(true) in " + this.getClass().getSimpleName(), e);
+           }
+        }
+
+        if((previousSelection!=null && selection!=null)
+               && (activePart != null &&  selectionProvidingPart != null && activePart.equals(selectionProvidingPart))
+               && (previousSelection==selection
+                    || previousSelection.equals(selection)
+                    || new StructuredSelection(selection).equals(previousSelection))
+                ) {
+            return;
+        }
+        if(delaySelection==null){
+            delaySelection = new DelaySelection(selection, activePart, thisPart);
+        }else{
+            delaySelection.setSelection(selection);
+            delaySelection.setActivePart(activePart);
+            delaySelection.setThisPart(thisPart);
+        }
+        if(!isInDelay){
+            isInDelay = true;
+            sync.asyncExec(delaySelection);
+            previousSelection = selection;
+        }
+    }
+
     @Override
     public void changed(Object object) {
         if(selectionProvidingPart!=null){
@@ -147,11 +197,8 @@ public abstract class AbstractCdmEditorPartE4
             if(part instanceof IDirtyMarkable){
                 ((IDirtyMarkable) part).changed(object);
             }
-            else {
-                IEditorPart editor = AbstractUtility.getActiveEditor();
-                if (editor != null && editor instanceof IDirtyMarkable) {
-                    ((IDirtyMarkable) editor).changed(object);
-                }
+            if (part instanceof IBulkEditor){
+               ((IBulkEditor)part).setSelection(createSelection(object));
             }
         }
     }
@@ -160,43 +207,106 @@ public abstract class AbstractCdmEditorPartE4
         return viewer;
     }
 
+    public boolean isEnabled() {
+        return isEnabled;
+    }
+
+    public void setEnabled(boolean isEnabled) {
+        this.isEnabled = isEnabled;
+    }
+
     protected void showViewer(IStructuredSelection selection, MPart activePart, Viewer viewer){
+        if(CdmStore.getCurrentSessionManager().getActiveSession()==null){
+            return;
+        }
         if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()){
             Object element = selection.getFirstElement();
             Object part = createPartObject(activePart);
-            if(selection.getFirstElement()!=null){
-               if (element instanceof Taxon){
-                       Taxon taxon = HibernateProxyHelper.deproxy(element, Taxon.class);
-                       if (taxon.isMisapplication()){
+            if (viewer.getControl().isDisposed()){
+                return;
+            }
+            viewer.getControl().setEnabled(true);
+            if(element != null){
+                if (element instanceof Taxon){
+
+                    Taxon taxon = HibernateProxyHelper.deproxy(element, Taxon.class);
+                    if (part instanceof ITaxonEditor){
+                        TaxonNode node = ((ITaxonEditor) part).getTaxonNode();
+                        if (node != null){
+                            boolean doEnable = CdmStore.currentAuthentiationHasPermission(node,
+                                    RequiredPermissions.TAXON_EDIT);
+                            if (!doEnable){
+                                 //check whether there are explicit TaxonNode rights
+                                 boolean taxonnodePermissionExists = false;
+                                 Collection<? extends GrantedAuthority> authorities = CdmStore.getCurrentAuthentiation().getAuthorities();
+                                 for (GrantedAuthority grantedAuthority: authorities){
+                                     if (grantedAuthority.getAuthority().startsWith("TAXONNODE")){
+                                         taxonnodePermissionExists = true;
+                                     }
+                                 }
+                                 if (!taxonnodePermissionExists){
+                                     doEnable = true;
+                                 }
+                            }
+
+                            //TODO: differ between the views
+                            this.isEnabled = doEnable;
+                        }
+                    }
+                    if (taxon.isMisapplication() || taxon.isProparteSynonym() ){
+
+                        if(part instanceof ITaxonEditor){
+                            Taxon accepted = ((ITaxonEditor) part).getTaxon();
+
+                            Set<TaxonRelationship> rels =  taxon.getTaxonRelations(accepted);
+
+                            if (rels != null && rels.iterator().hasNext() && !taxon.equals(accepted)){
+                                TaxonRelationship rel = rels.iterator().next();
+                                if ((rel.getType().isMisappliedName() || rel.getType().isAnySynonym()) && !rel.getFromTaxon().equals(((ITaxonEditor) part).getTaxon())){
+                                    viewer.setInput(rel);
+                                    selectionProvidingPart = activePart;
+                                    return;
+                                }
+                            }
+                        }
+                    }
+                }
 
-                                if(part instanceof ITaxonEditor){
-                                        Taxon accepted = ((ITaxonEditor) part).getTaxon();
+                //unwrap term DTOs
+                if(element instanceof TermDto){
+                    element = CdmStore.getService(ITermService.class).load(((TermDto) element).getUuid());
+                }
+                else if(element instanceof TermVocabularyDto){
+                    element = CdmStore.getService(IVocabularyService.class).load(((TermVocabularyDto) element).getUuid());
+                }
 
-//                                     Taxon accepted= ((ITaxonEditor)activePart).getTaxon();
-                                       Set<TaxonRelationship> rels =  taxon.getTaxonRelations(accepted);
 
-                                        if (rels.iterator().hasNext()){
-                                                TaxonRelationship rel = rels.iterator().next();
-                                                if (rel.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR()) && !rel.getFromTaxon().equals(((ITaxonEditor) part).getTaxon())){
-                                                        viewer.setInput(rel);
+                selectionProvidingPart = activePart;
+                if (viewer instanceof DetailsViewerE4){
 
-                                                        return;
-                                                }
-                                        }
-                               }
+                    if (selectionProvidingPart.getElementId().equals("eu.etaxonomy.taxeditor.editor.view.checklist.e4.DistributionEditorPart")){
+                        ((DetailsViewerE4)viewer).setDetailsEnabled(false);
+                    }else{
+                        ((DetailsViewerE4)viewer).setDetailsEnabled(isEnabled);
+                    }
+                    ((DetailsViewerE4)viewer).setInput(element, part);
+                   
+                }
 
+                else{
+                    if(element instanceof TermNodeDto){
+                        element = CdmStore.getService(ITermNodeService.class).load(((TermNodeDto) element).getUuid());
+                    }
+                    if (activePart.getObject() instanceof DetailsPartE4 && element instanceof TaxonName){
+                        selectionProvidingPart = ((DetailsPartE4)activePart.getObject()).getSelectionProvidingPart();
+                    }
 
-                       }
+                    viewer.setInput(element);
+                    viewer.getControl().setEnabled(isEnabled);
                 }
-               if (element instanceof Distribution && part instanceof IDistributionEditor){
-                   ((DetailsViewerE4)viewer).setInput(element, part);
-               }else{
-                   viewer.setInput(element);
-               }
-
             }
-            selectionProvidingPart = activePart;
         }
+        
     }
 
     protected Object createPartObject(MPart activePart) {
@@ -209,10 +319,25 @@ public abstract class AbstractCdmEditorPartE4
     }
 
     protected void showEmptyPage() {
-        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()){
+        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed() ){
             viewer.setInput(null);
+            try{
+                   if (!viewer.getControl().isDisposed()){
+                       viewer.getControl().setEnabled(false);
+                   }
+            }catch(SWTException e){
+               if (PreferencesUtil.isShowUpWidgetIsDisposedMessages() && e.getMessage().equals("Widget is disposed")){
+                    MessagingUtils.errorDialog("Widget is disposed",
+                            null,
+                            MessagingUtils.WIDGET_IS_DISPOSED_MESSAGE,
+                            null,
+                            e,
+                            true);
+                }
+            }
         }
-        selectionProvidingPart = null;
+
+        reset();
         if(thisPart!=null){
             thisPart.setLabel(getViewName());
         }
@@ -232,9 +357,6 @@ public abstract class AbstractCdmEditorPartE4
         return structuredSelection;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public ConversationHolder getConversationHolder() {
         if(selectionProvidingPart != null && selectionProvidingPart instanceof IConversationEnabled) {
@@ -243,29 +365,24 @@ public abstract class AbstractCdmEditorPartE4
         return null;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public boolean postOperation(CdmBase objectAffectedByOperation) {
+    public boolean postOperation(Object objectAffectedByOperation) {
         changed(objectAffectedByOperation);
+//        Object part = selectionProvidingPart.getObject();
+//        if (part instanceof IBulkEditor){
+//             ((IBulkEditor)part).setSelection(createSelection(objectAffectedByOperation));
+//        }
         return true;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean onComplete() {
         viewer.refresh();
         return true;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public Object getSelectionProvidingPart() {
+    public MPart getSelectionProvidingPart() {
         return selectionProvidingPart;
     }
 
@@ -273,21 +390,22 @@ public abstract class AbstractCdmEditorPartE4
     private void dispose() {
     }
 
+    private void reset(){
+        previousSelection = null;
+        selectionProvidingPart = null;
+        delaySelection = null;
+        context.deactivate();
+    }
+
     @PersistState
     private void persistState(){
 
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void update(CdmDataChangeMap arg0) {
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void forceDirty() {
     }