ref #9861: adapt editor to changes in termnodeDto-featurestateDto
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / section / AbstractCdmDetailElement.java
index 3450dd889c5cfbf4538885b2b98853d3e1b475cf..8c30439a9cd694f3a3da9e92c091f1547a5ad643 100644 (file)
@@ -1,4 +1,3 @@
-// $Id$
 /**
  * Copyright (C) 2007 EDIT
  * European Distributed Institute of Taxonomy
@@ -7,86 +6,96 @@
  * 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.section;
 
 import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Observable;
+import java.util.Observer;
 
 import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
 
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
-import eu.etaxonomy.cdm.model.name.TaxonNameBase;
+import eu.etaxonomy.cdm.common.CdmUtils;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.name.TaxonName;
+import eu.etaxonomy.cdm.model.permission.CRUD;
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
-import eu.etaxonomy.taxeditor.model.AbstractUtility;
-import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.store.LoginManager;
+import eu.etaxonomy.taxeditor.store.StoreUtil;
+import eu.etaxonomy.taxeditor.ui.element.AbstractRelevanceFormElement;
+import eu.etaxonomy.taxeditor.ui.element.CacheRelevance;
+import eu.etaxonomy.taxeditor.ui.element.CacheRelevanceHelper;
 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
+import eu.etaxonomy.taxeditor.ui.element.ICacheRelevantFormElement;
 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
 import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
+import eu.etaxonomy.taxeditor.ui.element.LabelElement;
+import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
+import eu.etaxonomy.taxeditor.ui.element.ToggleableTextElement;
 
 /**
- * <p>
- * Abstract AbstractCdmDetailElement class.
- * </p>
- *
  * @author n.hoffmann
  * @created Feb 26, 2010
- * @version 1.0
  */
-public abstract class AbstractCdmDetailElement<T> extends AbstractCdmFormElement implements ICdmDetailElement<T> {
+public abstract class AbstractCdmDetailElement<T>
+               extends AbstractRelevanceFormElement
+               implements ICdmDetailElement<T>, Observer{
 
        private T entity;
 
-       private boolean irrelevant;
+       protected boolean enabled = true;
+
+       private LabelElement warnForReferencedObjects;
+
+       protected EnumSet<CRUD> requiredCrud = null;
 
-       /**
-        * <p>
-        * Constructor for AbstractCdmDetailElement.
-        * </p>
-        *
-        * @param formFactory
-        *            a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
-        *            object.
-        * @param formElement
-        *            a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
-        *            object.
-        * @param <T>
-        *            a T object.
-        */
        public AbstractCdmDetailElement(CdmFormFactory formFactory,
                        ICdmFormElement formElement) {
                super(formFactory, formElement);
                // register as property change listener
                formFactory.addPropertyChangeListener(this);
+               CdmStore.getLoginManager().addObserver(this);
+
+               getLayoutComposite().getParent().addDisposeListener(
+                       e -> CdmStore.getLoginManager().deleteObserver(AbstractCdmDetailElement.this));
        }
 
        /**
         * Sets the entity and updates controls
-        *
-        * @param entity
-        *            a T object.
         */
-       public void setEntity(T entity) {
-               this.entity = entity;
-               updateContent();
+       @Override
+    public void setEntity(T entity) {
+        this.entity = entity;
+        // the id is always 0 if the entity was not yet saved, so it is new in this case
+        if(getEntity() == null || (getEntity() instanceof CdmBase && StoreUtil.getCdmEntity(getEntity()).getId() == 0)) {
+            // new entity, not yet saved
+            requiredCrud = EnumSet.of(CRUD.CREATE);
+        } else {
+            requiredCrud = EnumSet.of(CRUD.UPDATE);
+        }
+        updateContent();
+       }
+
+       public void setEntityWithoutUpdate(T entity){
+           this.entity = entity;
+        // the id is always 0 if the entity was not yet saved, so it is new in this case
+        if(getEntity() == null || (getEntity() instanceof CdmBase && StoreUtil.getCdmEntity(getEntity()).getId() == 0)) {
+            // new entity, not yet saved
+            requiredCrud = EnumSet.of(CRUD.CREATE);
+        } else {
+            requiredCrud = EnumSet.of(CRUD.UPDATE);
+        }
        }
 
-       /*
-        * (non-Javadoc)
-        *
-        * @see eu.etaxonomy.taxeditor.forms.IEntityElement#getEntity()
-        */
-       /**
-        * <p>
-        * Getter for the field <code>entity</code>.
-        * </p>
-        *
-        * @return a T object.
-        */
        @Override
     public T getEntity() {
                return entity;
@@ -97,18 +106,11 @@ public abstract class AbstractCdmDetailElement<T> extends AbstractCdmFormElement
         */
        protected void updateContent() {
                removeElements();
-               createControls(this, entity, SWT.WRAP);
-               getLayoutComposite().layout();
+               createControls(this, entity, SWT.NONE);
+               updateControlStates();
        }
 
-       /*
-        * (non-Javadoc)
-        *
-        * @see
-        * eu.etaxonomy.taxeditor.forms.ISelectableComposite#setSelected(boolean)
-        */
-       /** {@inheritDoc} */
-       @Override
+    @Override
     public void setSelected(boolean selected) {
                Composite section = getLayoutComposite().getParent();
                section.setBackground(selected ? SELECTED : getPersistentBackground());
@@ -116,15 +118,12 @@ public abstract class AbstractCdmDetailElement<T> extends AbstractCdmFormElement
 
        /**
         * Sets all field to the given enablement state except the objects in
-        * collection except
+        * the collection except parameter.
         *
         * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#setEnabled(boolean)
-        * @param enabled
-        *            a boolean.
-        * @param except
-        *            a {@link java.util.Collection} object.
         */
        public void setEnabled(boolean enabled, Collection<Object> except) {
+           this.enabled = enabled;
                for (ICdmFormElement element : getElements()) {
                        if (element instanceof IEnableableFormElement) {
                                IEnableableFormElement enableableElement = (IEnableableFormElement) element;
@@ -137,62 +136,52 @@ public abstract class AbstractCdmDetailElement<T> extends AbstractCdmFormElement
                }
        }
 
-       /**
-        * <p>
-        * Setter for the field <code>irrelevant</code>.
-        * </p>
-        *
-        * @param irrelevant
-        *            a boolean.
-        * @param except
-        *            a {@link java.util.Collection} object.
-        */
-       public void setIrrelevant(boolean irrelevant, Collection<Object> except) {
-               // logger.warn("Setting " + this.getClass().getSimpleName() +
-               // " to irrelevant state: " + irrelevant);
-               for (ICdmFormElement element : getElements()) {
-                       if (element instanceof IEnableableFormElement) {
-                               IEnableableFormElement relevantElement = (IEnableableFormElement) element;
-                               if (except != null && except.contains(relevantElement)) {
-                                       // do nothing
-                                       // logger.warn("not setting elements irrelevance: " +
-                                       // relevantElement.getClass().getSimpleName() + " in :" +
-                                       // this.getClass().getSimpleName());
-                               } else {
-                                       relevantElement.setIrrelevant(irrelevant);
-                               }
-                       }
-               }
+       @Override
+       public boolean isEnabled() {
+           return enabled;
        }
 
-       /** {@inheritDoc} */
-       @Override
+    @Override
     public void setEnabled(boolean enabled) {
-               setEnabled(enabled, null);
-       }
+        setEnabled(enabled, null);
+    }
+
+    @Override
+    public CacheRelevance cacheRelevance() {
+        return cacheRelevanceHelper.cacheRelevance();
+    }
 
-       /** {@inheritDoc} */
+    @Override
+    public void addDependsOnCache(ToggleableTextElement toggleElement) {
+        cacheRelevanceHelper.addDependsOnCache(toggleElement);
+    }
+
+    protected void registerCacheRelevance(ICacheRelevantFormElement element, ToggleableTextElement... toggleableCaches) {
+        if (element != null && toggleableCaches != null) {
+             for (ToggleableTextElement toggleableCache : toggleableCaches){
+                 if (toggleableCache != null){
+                     element.addDependsOnCache(toggleableCache);
+                 }
+             }
+        }
+//        updateCacheRelevance();
+    }
+
+       /**
+        * Updates the cache relevance state of all internal elements of this
+        * AbstractCdmDetailElement.
+        */
        @Override
-    public void setIrrelevant(boolean irrelevant) {
-               this.irrelevant = irrelevant;
-               setIrrelevant(irrelevant, null);
+    public void updateCacheRelevance(){
+           CacheRelevanceHelper.updateCacheRelevanceForSubelements(getElements());
        }
 
        /**
         * Create all content elements
-        *
-        * @param formElement
-        *            a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
-        *            object.
-        * @param entity
-        *            a T object.
-        * @param style
-        *            a int.
         */
        protected abstract void createControls(ICdmFormElement formElement,
                        T entity, int style);
 
-       /** {@inheritDoc} */
        @Override
        public void propertyChange(PropertyChangeEvent event) {
                if (event == null) {
@@ -205,9 +194,7 @@ public abstract class AbstractCdmDetailElement<T> extends AbstractCdmFormElement
 
                if (eventSource instanceof ICdmFormElement) {
                        ICdmFormElement eventElement = (ICdmFormElement) eventSource;
-                       ICdmFormElement eventElementContainer = eventElement
-                                       .getParentElement();
-
+                       ICdmFormElement eventElementContainer = eventElement.getParentElement();
                        if (eventElementContainer == this) {
                                if (event instanceof CdmPropertyChangeEvent) {
                                        if (((CdmPropertyChangeEvent) event).hasException()) {
@@ -226,66 +213,34 @@ public abstract class AbstractCdmDetailElement<T> extends AbstractCdmFormElement
        }
 
        protected void handleTitleCacheRelevantChange(PropertyChangeEvent event) {
-               boolean isRelevant = getEntity() instanceof TaxonNameBase
+               boolean isRelevant = getEntity() instanceof TaxonName
                                || getEntity() instanceof TaxonBase;
                isRelevant &= this instanceof AbstractIdentifiableEntityDetailElement;
 
                if (isRelevant) {
-                       ((AbstractIdentifiableEntityDetailElement) this)
-                                       .updateToggleableCacheField();
-                       updateParentSection();
+                       ((AbstractIdentifiableEntityDetailElement<?>)this).updateToggleableCacheField();
                }
        }
 
        private void updateParentSection() {
                if (getParentElement() instanceof AbstractCdmDetailSection) {
-                       ((AbstractCdmDetailSection) getParentElement()).updateTitle();
+                       ((AbstractCdmDetailSection<?>) getParentElement()).updateTitle();
                }
+               //NOTE: This slows down the rendering of the details view
+//             StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true);
        }
 
        /**
         * Gets called when the source of the event is a child widget of this
         * widget.
-        *
-        * @param eventSource
-        *            a {@link java.lang.Object} object.
         */
        public abstract void handleEvent(Object eventSource);
 
-       /**
-        * <p>
-        * handleException
-        * </p>
-        *
-        * @param event
-        *            a
-        *            {@link eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent}
-        *            object.
-        */
        public void handleException(CdmPropertyChangeEvent event) {
                // override this in subclasses if you want to deal with the error
-               AbstractUtility.error(event.getSource().getClass(), event.getException());
-       }
-
-       /**
-        * <p>
-        * isIrrelevant
-        * </p>
-        *
-        * @return a boolean.
-        */
-       public boolean isIrrelevant() {
-               return irrelevant;
+               MessagingUtils.error(event.getSource().getClass(), event.getException());
        }
 
-       /**
-        * <p>
-        * getConversationHolder
-        * </p>
-        *
-        * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
-        *         object.
-        */
        @Override
     public ConversationHolder getConversationHolder() {
                if (getParentElement() instanceof IConversationEnabled) {
@@ -296,8 +251,58 @@ public abstract class AbstractCdmDetailElement<T> extends AbstractCdmFormElement
                                "Parent element should be IConversationEnabled");
        }
 
-       /** {@inheritDoc} */
        @Override
     public void update(CdmDataChangeMap changeEvents) {
        }
-}
+
+       @Override
+    public void update(Observable o, Object arg){
+        if(o instanceof LoginManager){
+            updateControlStates();
+        }
+    }
+
+    protected void updateControlStates(){
+        if (getEntity() != null && getEntity() instanceof CdmBase){
+            enabled = enabled && CdmStore.currentAuthentiationHasPermission(StoreUtil.getCdmEntity(getEntity()), requiredCrud);
+        }else{
+            enabled = true;
+        }
+        setEnabled(enabled);
+    }
+
+       public LabelElement getWarnForReferencedObjects() {
+               return warnForReferencedObjects;
+       }
+
+       public void setWarnForReferencedObjects(LabelElement warnForReferencedObjects) {
+               this.warnForReferencedObjects = warnForReferencedObjects;
+       }
+
+       public void setWarnForReferencingObjects(ICdmFormElement formElement, int defaultReferencingObjects){
+           if (getEntity() instanceof CdmBase){
+               CdmBase cdmBase = (CdmBase) getEntity();
+               if (cdmBase.getId() != 0){
+                       long referencingObjectsCount = CdmStore.getCommonService().getReferencingObjectsCount(cdmBase);
+
+                       if (referencingObjectsCount > defaultReferencingObjects){
+                               setWarnForReferencedObjects(formFactory.createLabel(formElement, CdmUtils.Nz("The "+ cdmBase.getUserFriendlyTypeName()+" is referenced by " + referencingObjectsCount+ " objects, if you change it, it is changed for all these objects")));
+                               getWarnForReferencedObjects().setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
+                               getWarnForReferencedObjects().setLayout(LayoutConstants.FILL(2, 3));
+                               getWarnForReferencedObjects().setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
+                               formFactory.createLabel(formElement, "");
+                       }
+               }
+           }
+       }
+
+       public void setWarnForReferencingObjects(ICdmFormElement formElement){
+           setWarnForReferencingObjects(formElement, 1);
+       }
+
+       public void setWarnForReferencingObjectsVisible(boolean isVisible){
+               if (getWarnForReferencedObjects() != null){
+                       getWarnForReferencedObjects().setVisible(isVisible);
+               }
+       }
+}
\ No newline at end of file