fixing #4808
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / view / descriptive / DescriptiveContentProvider.java
index fce0faf8e592fc5ec687eb383a97af673547b092..33626cb75ca5c6ad6a7f206bbd56ee81f3271ac6 100644 (file)
@@ -1,9 +1,11 @@
 /**
- * 
+ *
  */
 package eu.etaxonomy.taxeditor.editor.view.descriptive;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -11,21 +13,18 @@ import java.util.Set;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 
-import eu.etaxonomy.cdm.api.service.ITermService;
 import eu.etaxonomy.cdm.model.common.Marker;
-import eu.etaxonomy.cdm.model.common.MarkerType;
 import eu.etaxonomy.cdm.model.description.DescriptionBase;
+import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
 import eu.etaxonomy.cdm.model.description.Feature;
 import eu.etaxonomy.cdm.model.description.FeatureTree;
-import eu.etaxonomy.cdm.model.description.TaxonDescription;
-import eu.etaxonomy.cdm.model.taxon.Taxon;
-import eu.etaxonomy.taxeditor.editor.TaxonEditorInput;
-import eu.etaxonomy.taxeditor.editor.UsageTermCollection;
+import eu.etaxonomy.cdm.model.description.IDescribable;
+import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
 import eu.etaxonomy.taxeditor.model.FeatureNodeContainer;
 import eu.etaxonomy.taxeditor.model.FeatureNodeContainerTree;
 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
-import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.store.TermStore;
+import eu.etaxonomy.taxeditor.store.UsageTermCollection;
 
 /**
  * <p>DescriptiveContentProvider class.</p>
@@ -35,49 +34,87 @@ import eu.etaxonomy.taxeditor.store.TermStore;
  * @version $Id: $
  */
 public class DescriptiveContentProvider implements ITreeContentProvider {
-       
+
        protected static final Object[] NO_CHILDREN = new Object[0];
-       protected Map<TaxonDescription, FeatureNodeContainerTree> featureNodeContainerCache;
-       
+       protected Map<DescriptionBase<?>, FeatureNodeContainerTree> featureNodeContainerCache;
+       private boolean showOnlyIndividualAssociations;
+       private static FeatureTree defaultFeatureTree = null;
+
+       public DescriptiveContentProvider(Map<DescriptionBase<?>, FeatureNodeContainerTree> featureNodeContainerCache) {
+           this(featureNodeContainerCache, false);
+       }
        /**
         * <p>Constructor for DescriptiveContentProvider.</p>
         *
         * @param featureNodeContainerCache a {@link java.util.Map} object.
         */
-       public DescriptiveContentProvider(Map<TaxonDescription, FeatureNodeContainerTree> featureNodeContainerCache) {
+       public DescriptiveContentProvider(Map<DescriptionBase<?>, FeatureNodeContainerTree> featureNodeContainerCache, boolean showOnlyIndividualAssociations) {
                this.featureNodeContainerCache = featureNodeContainerCache;
+               this.showOnlyIndividualAssociations = showOnlyIndividualAssociations;
        }
-       
+
        /* (non-Javadoc)
         * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
         */
        /** {@inheritDoc} */
-       public Object[] getChildren(Object parentElement) {
-               if (parentElement instanceof TaxonEditorInput) {
-                       return getDescriptions((TaxonEditorInput) parentElement).toArray(); 
+       @Override
+    public Object[] getChildren(Object parentElement) {
+               if (parentElement instanceof IDescribable<?>) {
+                       return getDescriptions((IDescribable<?>) parentElement).toArray();
                }
-               else if (parentElement instanceof TaxonDescription) {
-                       if ( ! ((TaxonDescription) parentElement).isImageGallery()) {
-                               TaxonDescription description = (TaxonDescription) parentElement;
-                               
+               else if (parentElement instanceof DescriptionBase<?>) {
+                       if ( ! ((DescriptionBase<?>) parentElement).isImageGallery()) {
+                           DescriptionBase<?> description = (DescriptionBase<?>) parentElement;
+
                                FeatureNodeContainerTree containerTree = getContainerTreeForDesription(description);
-                               
-                               return containerTree.getRoot().getChildren().toArray();
+                               List<FeatureNodeContainer> children = containerTree.getRoot().getChildren();
+                               //filter out containers with no children
+                               List<FeatureNodeContainer> childrenWithChildren = new ArrayList<FeatureNodeContainer>();
+                               for (FeatureNodeContainer featureNodeContainer : children) {
+                                   if(getChildren(featureNodeContainer).length>0){
+                                       childrenWithChildren.add(featureNodeContainer);
+                                   }
+                }
+                               return childrenWithChildren.toArray();
                        }
                }
                else if (parentElement instanceof FeatureNodeContainer){
                        FeatureNodeContainer container = (FeatureNodeContainer) parentElement;
                        if(container.isLeaf()){
-                               return container.getDescriptionElements().toArray();
+                               List<DescriptionElementBase> descriptionElements = container.getDescriptionElements();
+                               List<IndividualsAssociation> individualAssociations = new ArrayList<IndividualsAssociation>();
+                               for (DescriptionElementBase descriptionElement : descriptionElements) {
+                                   if(descriptionElement instanceof IndividualsAssociation){
+                                       individualAssociations.add((IndividualsAssociation) descriptionElement);
+                                   }
+                               }
+                               //sort individual associations by title cache of associated specimens
+                               Collections.sort(individualAssociations, new Comparator<IndividualsAssociation>() {
+
+                    @Override
+                    public int compare(IndividualsAssociation o1, IndividualsAssociation o2) {
+                        if(o1==null || o1.getAssociatedSpecimenOrObservation()==null){
+                            return -1;
+                        }
+                        if(o2==null || o2.getAssociatedSpecimenOrObservation()==null){
+                            return 1;
+                        }
+                        return o1.getAssociatedSpecimenOrObservation().compareTo(o2.getAssociatedSpecimenOrObservation());
+                    }
+                });
+                               if(showOnlyIndividualAssociations){
+                                   descriptionElements = new ArrayList<DescriptionElementBase>(individualAssociations);
+                               }
+                return descriptionElements.toArray();
                        }else{
                                return container.getChildren().toArray();
                        }
                }
-               
+
                return NO_CHILDREN;
        }
-       
-       private FeatureNodeContainerTree getContainerTreeForDesription(TaxonDescription description){
+
+       private FeatureNodeContainerTree getContainerTreeForDesription(DescriptionBase<?> description){
                if(! featureNodeContainerCache.containsKey(description)){
                        FeatureNodeContainerTree containerTree = new FeatureNodeContainerTree(description, getFeatureTree(description));
                        featureNodeContainerCache.put(description, containerTree);
@@ -88,102 +125,98 @@ public class DescriptiveContentProvider implements ITreeContentProvider {
        /** {@inheritDoc} */
        @Override
        public boolean hasChildren(Object element) {
-               if (element instanceof TaxonDescription){
-                       TaxonDescription description = (TaxonDescription) element;
+               if (element instanceof DescriptionBase<?>){
+                   DescriptionBase<?> description = (DescriptionBase<?>) element;
                        FeatureNodeContainerTree containerTree = featureNodeContainerCache.get(description);
                        if(containerTree != null && containerTree.getRoot() != null){
                                return containerTree.getRoot().getChildren().size() != 0;
                        }
-               } 
+               }
                return getChildren(element).length != 0;
        }
-       
+
        /**
         * Retrieves the feature tree associated with the given description
-        * 
-        * TODO as of now this is always the same thing because feature trees may not be associated 
+        *
+        * TODO as of now this is always the same thing because feature trees may not be associated
         * to descriptions yet.
-        * 
+        *
         * @param description
         * @return
         */
        private FeatureTree getFeatureTree(DescriptionBase description){
-               FeatureTree featureTree = null;
-               
+
+           if(defaultFeatureTree == null) {
+               defaultFeatureTree = FeatureTree.NewInstance(TermStore.getTerms(Feature.class));
+           }
+           FeatureTree featureTree;
                // TODO change this to the feature tree associated with this taxon description
-               if (description.hasStructuredData()){                                   
+               if (description.hasStructuredData()){
                        featureTree = PreferencesUtil.getDefaultFeatureTreeForStructuredDescription();
                }else{
                        featureTree = PreferencesUtil.getDefaultFeatureTreeForTextualDescription();
                }
-               
+
                // create a transient tree with all features if none was selected
                if(featureTree == null){
-                       featureTree = FeatureTree.NewInstance(TermStore.getTerms(Feature.class));
+                       featureTree = defaultFeatureTree;
                }
-               
+
                return featureTree;
        }
 
-       /**
-        * Get all descriptions associated with the given TaxonEditorInput
-        * 
-        * @param parentElement
-        * @return
-        */
-       protected List<DescriptionBase> getDescriptions(TaxonEditorInput parentElement) {
-               Taxon taxon = parentElement.getTaxon();
-               List<DescriptionBase> descriptions = new ArrayList<DescriptionBase>();
-               for(DescriptionBase description : taxon.getDescriptions()){
+    /**
+     * Get all descriptions associated with the given object
+     * @param parentElement
+     * @return
+     */
+    protected List<DescriptionBase<?>> getDescriptions(IDescribable<?> parentElement) {
+        Set<? extends DescriptionBase<?>> elementDescriptions = parentElement.getDescriptions();
+        List<DescriptionBase<?>> resultDescriptions = new ArrayList<DescriptionBase<?>>();
+        for(DescriptionBase<?> description : elementDescriptions){
                        if(! description.isImageGallery()){
-                               MarkerType useMarkertype = (MarkerType) CdmStore.getService(ITermService.class).find(UsageTermCollection.uuidUseMarkerType);
                                Set<Marker> descriptionMarkers = description.getMarkers();
                                if(descriptionMarkers != null && !descriptionMarkers.isEmpty()) {
                                        for (Marker marker: descriptionMarkers) {
-                                               if(!(marker.getMarkerType().equals(useMarkertype))) {
-                                                       descriptions.add(description);
+                                               if(marker.getMarkerType() != null && !(marker.getMarkerType().getUuid().equals(UsageTermCollection.uuidUseMarkerType))) {
+                                                       resultDescriptions.add(description);
                                                }
                                        }
                                }
                                else {
-                                       descriptions.add(description);
+                                       resultDescriptions.add(description);
                                }
                        }
-                       
-               }                       
-               return descriptions;
-       }
+               }
+        return resultDescriptions;
+    }
 
-       /* (non-Javadoc)
-        * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
-        */
        /** {@inheritDoc} */
-       public Object getParent(Object element) {
+       @Override
+    public Object getParent(Object element) {
                return null;
        }
 
-       /* (non-Javadoc)
-        * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
-        */
        /** {@inheritDoc} */
-       public Object[] getElements(Object inputElement) {
+       @Override
+    public Object[] getElements(Object inputElement) {
                return getChildren(inputElement);
        }
-       
-       /* (non-Javadoc)
-        * @see org.eclipse.jface.viewers.IContentProvider#dispose()
-        */
+
        /**
         * <p>dispose</p>
         */
-       public void dispose() {
+       @Override
+    public void dispose() {
                featureNodeContainerCache.clear();
        }
 
-       /* (non-Javadoc)
-        * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
-        */
        /** {@inheritDoc} */
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}    
-       
+       @Override
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
+
+       public void toggleShowOnlyIndividualAssociations() {
+           showOnlyIndividualAssociations = !showOnlyIndividualAssociations;
+    }
+
 }