Merge branch 'develop' into termSearch
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / model / DescriptionHelper.java
index 658b72c31738fee7aafe23666f4bdb09fd9fbdc5..b54b5d8a4717fd65673a33a37caa5708c68ba1b7 100644 (file)
@@ -1,4 +1,3 @@
-// $Id$
 /**
 * Copyright (C) 2007 EDIT
 * European Distributed Institute of Taxonomy
 
 package eu.etaxonomy.taxeditor.model;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
 
+import org.apache.commons.lang.StringUtils;
 import org.hibernate.LazyInitializationException;
 
+import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
 import eu.etaxonomy.cdm.api.service.DefaultCategoricalDescriptionBuilder;
 import eu.etaxonomy.cdm.api.service.DefaultQuantitativeDescriptionBuilder;
 import eu.etaxonomy.cdm.api.service.DescriptionBuilder;
 import eu.etaxonomy.cdm.common.CdmUtils;
-import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
-import eu.etaxonomy.cdm.model.common.ISourceable;
+import eu.etaxonomy.cdm.model.agent.AgentBase;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.common.Group;
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
 import eu.etaxonomy.cdm.model.common.Language;
 import eu.etaxonomy.cdm.model.common.LanguageString;
@@ -28,6 +33,11 @@ import eu.etaxonomy.cdm.model.common.LanguageStringBase;
 import eu.etaxonomy.cdm.model.common.Marker;
 import eu.etaxonomy.cdm.model.common.MarkerType;
 import eu.etaxonomy.cdm.model.common.OriginalSourceBase;
+import eu.etaxonomy.cdm.model.common.RelationshipBase;
+import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
+import eu.etaxonomy.cdm.model.common.Representation;
+import eu.etaxonomy.cdm.model.common.TimePeriod;
+import eu.etaxonomy.cdm.model.common.User;
 import eu.etaxonomy.cdm.model.description.CategoricalData;
 import eu.etaxonomy.cdm.model.description.CommonTaxonName;
 import eu.etaxonomy.cdm.model.description.DescriptionBase;
@@ -36,14 +46,32 @@ import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
 import eu.etaxonomy.cdm.model.description.Distribution;
 import eu.etaxonomy.cdm.model.description.Feature;
 import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
+import eu.etaxonomy.cdm.model.description.KeyStatement;
 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
 import eu.etaxonomy.cdm.model.description.QuantitativeData;
+import eu.etaxonomy.cdm.model.description.SpecimenDescription;
+import eu.etaxonomy.cdm.model.description.TaxonDescription;
 import eu.etaxonomy.cdm.model.description.TaxonInteraction;
+import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
 import eu.etaxonomy.cdm.model.description.TextData;
 import eu.etaxonomy.cdm.model.location.NamedArea;
 import eu.etaxonomy.cdm.model.media.Media;
+import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
+import eu.etaxonomy.cdm.model.name.HybridRelationship;
+import eu.etaxonomy.cdm.model.name.NameRelationship;
+import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
+import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
+import eu.etaxonomy.cdm.model.name.TaxonName;
+import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
+import eu.etaxonomy.cdm.model.name.TypeDesignationStatusBase;
+import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
+import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
+import eu.etaxonomy.cdm.model.taxon.Classification;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 
 /**
@@ -51,8 +79,6 @@ import eu.etaxonomy.taxeditor.store.CdmStore;
  *
  * @author p.ciardelli
  * @author n.hoffmann
- * @created 02.04.2009
- * @version 1.0
  */
 public class DescriptionHelper {
 
@@ -66,9 +92,35 @@ public class DescriptionHelper {
         */
        public static String getCache(DescriptionElementBase element,
                        Language language) {
+
+               String mainElementLabel= null;
+               DescriptionBase<?> descr = element.getInDescription();
+               descr = CdmBase.deproxy(descr, DescriptionBase.class);
+
+               if (descr != null){
+                       if (descr.isInstanceOf(TaxonDescription.class)){
+                               Taxon taxon = CdmBase.deproxy(descr, TaxonDescription.class).getTaxon();
+                               if (taxon != null){
+                                       mainElementLabel = taxon.getTitleCache();
+                               }
+                       }else if (descr.isInstanceOf(SpecimenDescription.class)){
+                               SpecimenOrObservationBase<?> specimen = CdmBase.deproxy(descr, SpecimenDescription.class).getDescribedSpecimenOrObservation();
+                               if (specimen != null){
+                                       mainElementLabel = specimen.getTitleCache();
+                               }
+                       }else if (descr.isInstanceOf(TaxonNameDescription.class)){
+                               TaxonName name = CdmBase.deproxy(descr, TaxonNameDescription.class).getTaxonName();
+                               if (name != null){
+                                       mainElementLabel = name.getTitleCache();
+                               }
+                       }
+               }
+
+
                String cache = null;
                if (element instanceof TextData) {
-                       cache = ((TextData) element).getText(language);
+                       //cache = ((TextData) element).getText(language);
+                   cache = "Text Data";
                }
                if (element instanceof CommonTaxonName) {
                        cache = ((CommonTaxonName) element).getName();
@@ -97,7 +149,11 @@ public class DescriptionHelper {
                                }
                        }
                }
-               return cache == null ? "" : cache;
+               String result = cache == null ? "" : cache;
+               if (isNotBlank(mainElementLabel)){
+                       result = CdmUtils.concat(" ", result, "(" + mainElementLabel + ")");
+               }
+               return result;
        }
 
        /**
@@ -124,19 +180,17 @@ public class DescriptionHelper {
                if (element instanceof TextData) {
                        ((TextData) element).putText(language, value);
                        return;
-               }
-               if (element instanceof CommonTaxonName) {
+               }else if (element instanceof CommonTaxonName) {
                        ((CommonTaxonName) element).setName(value);
                        return;
-               }
-               if (element instanceof TaxonInteraction) {
+               }else if (element instanceof TaxonInteraction) {
 
-               }
-               if(element instanceof Distribution){
+               }else if(element instanceof Distribution){
                        MessagingUtils.warn(DescriptionHelper.class, "trying to set cache on distribution, don't know what to do at the moment.");
                        return;
+               }else{
+                       MessagingUtils.warn(DescriptionHelper.class, "No matching subclass found for DescriptionElementBase object, 'cache' not set.");
                }
-               MessagingUtils.warn(DescriptionHelper.class, "No matching subclass found for DescriptionElementBase object, 'cache' not set.");
        }
 
        /**
@@ -151,9 +205,7 @@ public class DescriptionHelper {
                setCache(element, value, CdmStore.getDefaultLanguage());
        }
 
-       /* (non-Javadoc)
-        * @see eu.etaxonomy.taxeditor.bulkeditor.referencingobjects.IReferencingObjectsService#getObjectDescription(java.lang.Object)
-        */
+
        /**
         * <p>getObjectDescription</p>
         *
@@ -161,50 +213,305 @@ public class DescriptionHelper {
         * @return a {@link java.lang.String} object.
         */
        public static String getObjectDescription(Object element) {
+           String resultString = null;
                if (element instanceof IdentifiableEntity) {
                        try{
-                               return ((IdentifiableEntity) element).getTitleCache();
+                           resultString = ((IdentifiableEntity) element).getTitleCache();
                        }catch(LazyInitializationException e){
                                String result = "No Session to initialize title cache for IdentifiableEntity";
                                MessagingUtils.error(DescriptionHelper.class, result, e);
-                               return "TODO: " + result;
+                               resultString = "TODO: " + result;
                        }
-               }
-               if (element instanceof OriginalSourceBase) {
+               }else if (element instanceof OriginalSourceBase) {
                        try{
-                               OriginalSourceBase originalSource = (OriginalSourceBase) element;
-                               ISourceable sourcedObject = originalSource.getSourcedObj();
-                               String sourceObjectTitle = "";
-                               if(sourcedObject instanceof IIdentifiableEntity){
-                                       sourceObjectTitle = ((IdentifiableEntity) sourcedObject).getTitleCache();
-                               }else if(sourcedObject instanceof DescriptionElementBase){
-                                       sourceObjectTitle = "Element for description: " + ((DescriptionElementBase) sourcedObject).getInDescription().getTitleCache();
-                               }else{
-                                       throw new IllegalStateException("Unknown ISourceable object for given OriginalSourceBase");
-                               }
-
-                               return CdmUtils.concat("; ", new String[]{originalSource.getIdNamespace(), originalSource.getIdInSource(), sourceObjectTitle});
+                               OriginalSourceBase<?> originalSource = (OriginalSourceBase<?>) element;
+//                             ISourceable sourcedObject = originalSource.getSourcedObj();
+                               //due to #5743 the bidirectionality for sourced object had to be removed
+                               String sourceObjectTitle = "sourced object data not available (#5743)";
+//                             if(sourcedObject instanceof IIdentifiableEntity){
+//                                     sourceObjectTitle = ((IdentifiableEntity) sourcedObject).getTitleCache();
+//                             }else if(sourcedObject instanceof DescriptionElementBase){
+//                                     sourceObjectTitle = "Element for description: " + ((DescriptionElementBase) sourcedObject).getInDescription().getTitleCache();
+//                             }else{
+//                                     throw new IllegalStateException("Unknown ISourceable object for given OriginalSourceBase");
+//                             }
+
+                               resultString = CdmUtils.concat("; ", new String[]{originalSource.getIdNamespace(), originalSource.getIdInSource(), sourceObjectTitle});
                        }catch(LazyInitializationException e){
                                String result = "Error initializing title cache for ISourceable of an OriginalSourceBase";
                                MessagingUtils.error(DescriptionHelper.class, result, e);
-                               return "TODO: " + result;
+                               resultString = "TODO: " + result;
                        }
+               }else if (element instanceof LanguageStringBase) {
+                   resultString = ((LanguageStringBase) element).getText();
+               }else if (element instanceof DescriptionElementBase) {
+                   resultString = getCache((DescriptionElementBase) element);
+               }else if (element instanceof RelationshipBase<?, ?, ?>) {
+                   resultString = getCache((RelationshipBase<?, ?, ?>) element);
+               }else if (element instanceof TypeDesignationBase<?>) {
+                   resultString = getCache((TypeDesignationBase<?>) element);
+               }else if (element instanceof HomotypicalGroup) {
+                   resultString = getCache((HomotypicalGroup) element);
+               }else if (element instanceof TaxonNode) {
+                   resultString = getCache((TaxonNode) element);
+               }else if (element instanceof DeterminationEvent) {
+                   resultString = getCache((DeterminationEvent) element);
+               }else if (element instanceof GatheringEvent){
+                       resultString = getCache((GatheringEvent) element);
+               }else if (element instanceof Marker) {
+                       Marker marker = (Marker) element;
+                       MarkerType type = marker.getMarkerType();
+                       resultString = (type == null ? "- no marker type -" : marker.getMarkerType().getLabel()) + " (" + marker.getFlag() + ")";
+               }else if (element instanceof User) {
+                       User user = (User) element;
+                       resultString = user.getUsername();
+               }else if (element instanceof Group) {
+                       Group group = (Group) element;
+                       resultString = group.getName();
+               }else if (element instanceof KeyStatement) {
+            KeyStatement keyStatement = (KeyStatement) element;
+            resultString = getCache(keyStatement);
+        }else{
+                       // TODO write return texts for HomotypicalGroup, etc.
+            resultString = element.toString();
+               }
+
+               if (resultString == null){
+                   resultString = element.toString();
+               }
+               return resultString;
+       }
+       
+       private static String getCache(GatheringEvent gatheringEvent){
+               String ALTITUDE_PREFIX = "alt. ";
+               final String METER = "m";
+
+               String result = "";
+
+               //collector
+               AgentBase<?> collector = CdmBase.deproxy(gatheringEvent.getCollector());
+               String collectorStr = collector == null? null : collector.getTitleCache();
+               result = CdmUtils.concat(", ", result, collectorStr);
+               
+               //gathering period
+               TimePeriod gatheringPeriod = gatheringEvent.getTimeperiod();
+               result = CdmUtils.concat(", ", result, (gatheringPeriod == null? null : gatheringPeriod.toString()));
+               
+               //country
+               String strCountry = null;
+               NamedArea country = gatheringEvent.getCountry();
+               Representation repCountry = country == null ? null : country.getRepresentation(Language.DEFAULT());
+               strCountry = repCountry == null ? null: repCountry.getLabel();
+               result = CdmUtils.concat(", ", result, strCountry);
+
+               //locality
+               LanguageString locality = gatheringEvent.getLocality();
+               if (locality != null) {
+                       result = CdmUtils.concat(", ", result, locality.getText());
+               }
+
+               //elevation
+               String elevationStr;
+               if (isNotBlank(gatheringEvent.getAbsoluteElevationText())){
+                       elevationStr = gatheringEvent.getAbsoluteElevationText();
+               }else{
+                       String text = gatheringEvent.getAbsoluteElevationText();
+                       Integer min = gatheringEvent.getAbsoluteElevation();
+                       Integer max = gatheringEvent.getAbsoluteElevationMax();
+                       elevationStr = DerivedUnitFacade.distanceString(min, max, text, METER);
                }
-               if (element instanceof LanguageStringBase) {
-                       return ((LanguageStringBase) element).getText();
+               if (isNotBlank(elevationStr)){
+                       result = CdmUtils.concat(", " , result, ALTITUDE_PREFIX);
+                       result += elevationStr;
                }
-               if (element instanceof DescriptionElementBase) {
-                       return getCache((DescriptionElementBase) element);
+
+               //exact locality
+               if (gatheringEvent.getExactLocation() != null){
+                       String exactLocation = gatheringEvent.getExactLocation().toSexagesimalString(false, false);
+                       result = CdmUtils.concat(", ", result, exactLocation);
                }
-               if (element instanceof Marker) {
-                       Marker marker = (Marker) element;
-                       MarkerType type = marker.getMarkerType();
-                       return (type == null ? "- no marker type -" : marker.getMarkerType().getLabel()) + " (" + marker.getFlag() + ")";
+
+               return result;
+       }
+
+
+       private static String getCache(DeterminationEvent detEvent) {
+               //taxon
+               String taxonStr = null;
+               TaxonName taxonName = detEvent.getTaxonName();
+               TaxonBase<?> taxon = detEvent.getTaxon();
+               if (taxonName != null){
+                       taxonStr = taxonName.getTitleCache();
+               }
+               if (isBlank(taxonStr) && taxon != null){
+                       taxonStr = taxon.getTitleCache();
                }
-               // TODO write return texts for NameRelationship, HomotypicalGroup, SpecimenTypeDesignation, etc.
-               return element.toString();
+               if (isBlank(taxonStr)){
+                       taxonStr = "no or unlabled taxon";
+               }
+
+
+               //unit
+               SpecimenOrObservationBase<?> unit = detEvent.getIdentifiedUnit();
+               String unitStr;
+               if (unit != null){
+                       unitStr = unit.getTitleCache();
+                       if (isBlank(unitStr)){
+                               unitStr = "Unlabled unit";
+                       }
+               }else{
+                       unitStr = "no unit";
+               }
+
+               String result = CdmUtils.concat(" determined as ", unitStr, taxonStr);
+
+               return result;
        }
 
+       private static String getCache(TaxonNode taxonNode) {
+               String result = "";
+               Classification classification = taxonNode.getClassification();
+               if (classification != null){
+                       String classificationStr = classification.getName() == null ? "" : classification.getName().getText();
+                       result = CdmUtils.concat("" , result, classificationStr);
+                       if (isBlank(result)){
+                               result = classification.toString();
+                       }
+               }
+               String parentStr;
+               TaxonNode parentNode = taxonNode.getParent();
+               if (parentNode == null){
+                       parentStr = "no parent";
+               }else{
+                       Taxon parentTaxon = parentNode.getTaxon();
+                       if (parentTaxon == null){
+                               parentStr = "no parent taxon";
+                       }else{
+                               TaxonName parentName = parentTaxon.getName();
+                               if (parentName == null){
+                                       parentStr = "child of " + parentTaxon.getTitleCache();
+                               }else{
+                                       parentStr = "child of " + parentName.getTitleCache();
+                               }
+                       }
+               }
+               result = CdmUtils.concat(": ", result, parentStr);
+
+               return result;
+       }
+
+       private static String getCache(TypeDesignationBase<?> designation) {
+               designation = CdmBase.deproxy(designation);
+               TypeDesignationStatusBase<?> status = designation.getTypeStatus();
+               Set<TaxonName> from;
+               IdentifiableEntity<?> to;
+               from = designation.getTypifiedNames();
+               if (designation.isInstanceOf(SpecimenTypeDesignation.class)){
+                       to = ((SpecimenTypeDesignation)designation).getTypeSpecimen();
+               }else if (designation.isInstanceOf(NameTypeDesignation.class)){
+                       to = ((NameTypeDesignation)designation).getTypeName();
+               }else{
+                       throw new RuntimeException("Type Designation class not supported: " +  designation.getClass().getName());
+               }
+               String typeLabel = null;
+               if (status != null){
+                       Representation typeRepr = status.getPreferredRepresentation(CdmStore.getDefaultLanguage());
+                       if (typeRepr != null){
+                               typeLabel = typeRepr.getAbbreviatedLabel();
+                       }
+                       if (isBlank(typeLabel) && typeRepr != null){
+                               typeLabel = typeRepr.getLabel();
+                       }
+                       if (isBlank(typeLabel) ){
+                               typeLabel = status.getSymbol();
+                       }
+                       if (isBlank(typeLabel)){
+                               typeLabel = status.getTitleCache();
+                       }
+               }
+               if (isBlank(typeLabel)){
+                       typeLabel = "->";
+               }
+               String fromString = "";
+               for (TaxonName name : from){
+                       CdmUtils.concat(",", fromString, name.getTitleCache());
+               }
+               String result = CdmUtils.concat(" ", new String[]{from == null ? null : fromString,
+                               typeLabel, to == null? null : to.getTitleCache()});
+               return result;
+       }
+
+       private static String getCache(RelationshipBase<?, ?, ?> rel) {
+               rel = CdmBase.deproxy(rel);
+               RelationshipTermBase<?> type = rel.getType();
+               IdentifiableEntity<?> from;
+               IdentifiableEntity<?> to;
+               if (rel.isInstanceOf(NameRelationship.class)){
+                       from = ((NameRelationship)rel).getFromName();
+                       to = ((NameRelationship)rel).getToName();
+               }else if (rel.isInstanceOf(HybridRelationship.class)){
+                       from = ((HybridRelationship)rel).getParentName();
+                       to = ((HybridRelationship)rel).getHybridName();
+               }else if (rel.isInstanceOf(TaxonRelationship.class)){
+                       from = ((TaxonRelationship)rel).getFromTaxon();
+                       to = ((TaxonRelationship)rel).getToTaxon();
+               }else{
+                       try {
+                               Method fromMethod = rel.getClass().getMethod("getRelatedFrom");
+                               Method toMethod = rel.getClass().getMethod("getRelatedFrom");
+                               fromMethod.setAccessible(true);
+                               toMethod.setAccessible(true);
+                               from = (IdentifiableEntity<?>)fromMethod.invoke(rel);
+                               to = (IdentifiableEntity<?>)toMethod.invoke(rel);
+                       } catch (NoSuchMethodException | SecurityException | IllegalAccessException
+                               | IllegalArgumentException | InvocationTargetException e) {
+                               throw new RuntimeException(e);
+                       }
+               }
+               String typeLabel = null;
+               if (type != null){
+                       Representation typeRepr = type.getPreferredRepresentation(CdmStore.getDefaultLanguage());
+                       if (typeRepr != null){
+                               typeLabel = typeRepr.getAbbreviatedLabel();
+                       }
+                       if (isBlank(typeLabel) && typeRepr != null){
+                               typeLabel = typeRepr.getLabel();
+                       }
+                       if (isBlank(typeLabel) ){
+                               typeLabel = type.getSymbol();
+                       }
+                       if (isBlank(typeLabel)){
+                               typeLabel = type.getTitleCache();
+                       }
+               }
+               if (isBlank(typeLabel)){
+                       typeLabel = "->";
+               }
+               String result = CdmUtils.concat(" ", new String[]{from == null ? null : from.getTitleCache(),
+                               typeLabel, to == null? null : to.getTitleCache()});
+               return result;
+       }
+
+
+       private static String getCache(HomotypicalGroup hg) {
+               String result = "";
+               for (TaxonName tnb : hg.getTypifiedNames()){
+                       result = CdmUtils.concat(", ", result, tnb.getTitleCache());
+               }
+               if (isBlank(result)){
+                       result = "No typified names";
+               }
+               return result;
+       }
+
+       private static String getCache(KeyStatement ks) {
+        String result = "";
+
+        result = "KeyStatement";
+
+        return result;
+    }
+
        /**
         * <p>getObjectClassname</p>
         *
@@ -328,7 +635,7 @@ public class DescriptionHelper {
                                        text += " [ " + source.getNameUsedInSource().getTitleCache() + " ]";
                                }
                        }
-                       if(CdmUtils.isEmpty(text)){
+                       if(isBlank(text)){
                                text = "No sources provided";
                        }
                }else{
@@ -336,7 +643,7 @@ public class DescriptionHelper {
                        LanguageString languageString = element.getPreferredLanguageString(languages);
                        text = languageString != null ? languageString.getText() : null;
                }
-               return CdmUtils.isEmpty(text) ? "No text provided" : text;
+               return isBlank(text) ? "No text provided" : text;
        }
 
        /**
@@ -389,7 +696,7 @@ public class DescriptionHelper {
                        text = "No label provided";
                }
 
-               return "Description: " + text;
+               return text;
        }
 
        /**
@@ -403,7 +710,7 @@ public class DescriptionHelper {
                if(derivedUnit != null){
                        return derivedUnit.getTitleCache();
                }
-               return "No text provided";
+               return "No unit chosen";
        }
 
        /**
@@ -422,7 +729,7 @@ public class DescriptionHelper {
                }
                else if(element instanceof CategoricalData){
                        String categoricalDataText = getCategoricalDataText((CategoricalData) element);
-                       if(categoricalDataText.isEmpty()){
+                       if(categoricalDataText==null || categoricalDataText.isEmpty()){
                            categoricalDataText = noLabelString;
                        }
             return categoricalDataText;
@@ -438,7 +745,7 @@ public class DescriptionHelper {
                }
                else if (element instanceof QuantitativeData) {
                        String quantitativeDataText = getQuantitativeDataText((QuantitativeData) element);
-                       if(quantitativeDataText.isEmpty()){
+                       if(quantitativeDataText==null || quantitativeDataText.isEmpty()){
                 quantitativeDataText = noLabelString;
                        }
             return quantitativeDataText;
@@ -453,4 +760,12 @@ public class DescriptionHelper {
                        return element.toString();
                }
        }
+       
+       private static boolean isNotBlank(String str){
+               return StringUtils.isNotBlank(str);
+       }
+       
+       private static boolean isBlank(String str){
+               return StringUtils.isBlank(str);
+       }
 }