cleanup
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / strategy / cache / name / NameCacheStrategyBase.java
index e7598cbecad89591282f0e14e6211adf82b8e45a..205be2e2458a8905ae3922876fff3291d5925c18 100644 (file)
@@ -9,63 +9,51 @@
 package eu.etaxonomy.cdm.strategy.cache.name;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 import java.util.UUID;
 
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import eu.etaxonomy.cdm.common.CdmUtils;
-import eu.etaxonomy.cdm.common.UTF8;
-import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.compare.name.NomenclaturalStatusComparator;
+import eu.etaxonomy.cdm.format.reference.NomenclaturalSourceFormatter;
 import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.common.Language;
-import eu.etaxonomy.cdm.model.common.Representation;
 import eu.etaxonomy.cdm.model.name.INonViralName;
-import eu.etaxonomy.cdm.model.name.ITaxonNameBase;
-import eu.etaxonomy.cdm.model.name.NameRelationship;
-import eu.etaxonomy.cdm.model.name.NameRelationshipType;
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
 import eu.etaxonomy.cdm.model.name.TaxonName;
-import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
-import eu.etaxonomy.cdm.model.reference.Reference;
+import eu.etaxonomy.cdm.model.term.Representation;
+import eu.etaxonomy.cdm.ref.TypedEntityReference;
 import eu.etaxonomy.cdm.strategy.StrategyBase;
 import eu.etaxonomy.cdm.strategy.cache.HTMLTagRules;
 import eu.etaxonomy.cdm.strategy.cache.TagEnum;
 import eu.etaxonomy.cdm.strategy.cache.TaggedCacheHelper;
 import eu.etaxonomy.cdm.strategy.cache.TaggedText;
+import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImplRegExBase;
 
 /**
  * @author AM
  */
-public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
+public abstract class NameCacheStrategyBase
         extends StrategyBase
-        implements INameCacheStrategy<T> {
+        implements INameCacheStrategy {
     private static final long serialVersionUID = -2322348388258675517L;
 
-    private static final Logger logger = Logger.getLogger(NameCacheStrategyBase.class);
+    private static final Logger logger = LogManager.getLogger(NameCacheStrategyBase.class);
 
     final static UUID uuid = UUID.fromString("817ae5b5-3ac2-414b-a134-a9ae86cba040");
 
-    /**
-     * Constructor
-     */
     public NameCacheStrategyBase() {
         super();
     }
 
-//    @Override
-//    public abstract String getFullTitleCache(T name);
-//
-//    @Override
-//    public abstract String getFullTitleCache(T name, HTMLTagRules rules);
-
-
     @Override
-    public String getFullTitleCache(T taxonName, HTMLTagRules htmlTagRules) {
+    public String getFullTitleCache(TaxonName taxonName, HTMLTagRules htmlTagRules) {
         List<TaggedText> tags = getTaggedFullTitle(taxonName);
         if (tags == null){
             return null;
@@ -76,21 +64,21 @@ public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
     }
 
     @Override
-    public String getFullTitleCache(T taxonName) {
+    public String getFullTitleCache(TaxonName taxonName) {
         return getFullTitleCache(taxonName, null);
     }
 
-
-    /**
-     * @param nonViralName
-     * @param tags
-     * @return
-     */
     @Override
-    public List<TaggedText> getNomStatusTags(T nonViralName, boolean includeSeparatorBefore,
+    public List<TaggedText> getNomStatusTags(TaxonName taxonName, boolean includeSeparatorBefore,
             boolean includeSeparatorAfter) {
 
-        Set<NomenclaturalStatus> ncStati = nonViralName.getStatus();
+
+        Collection<NomenclaturalStatus> ncStati = taxonName.getStatus();
+        if (ncStati.size() > 1) {
+            //order to have defined behavior
+            ncStati = new ArrayList<>(ncStati);
+            ((List<NomenclaturalStatus>)ncStati).sort(NomenclaturalStatusComparator.SINGLETON());
+        }
         Iterator<NomenclaturalStatus> iterator = ncStati.iterator();
         List<TaggedText> nomStatusTags = new ArrayList<>();
         while (iterator.hasNext()) {
@@ -100,23 +88,27 @@ public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
             String nomStatusStr = "not defined";
             if(ncStatus.getType() != null){
                 NomenclaturalStatusType statusType =  ncStatus.getType();
-                Language lang = Language.LATIN();
-                Representation repr = statusType.getRepresentation(lang);
+                List<Language> prefLangs = Arrays.asList(new Language[]{Language.LATIN(), Language.DEFAULT()});
+                Representation repr = statusType.getPreferredRepresentation(prefLangs);
                 if (repr != null){
+                    if(!Language.LATIN().equals(repr.getLanguage())){
+                        String message = "No latin representation available for nom. status. " + statusType.getTitleCache();
+                        logger.info(message);
+                    }
                     nomStatusStr = repr.getAbbreviatedLabel();
                 }else{
-                    String message = "No latin representation available for nom. status. " + statusType.getTitleCache();
+                    String message = "No representation available for nom. status. " + statusType.getTitleCache();
                     logger.warn(message);
-                    throw new IllegalStateException(message);
+                    nomStatusStr = statusType.getTitleCache();
                 }
-            }else if(StringUtils.isNotBlank(ncStatus.getRuleConsidered())){
+            }else if(isNotBlank(ncStatus.getRuleConsidered())){
                 nomStatusStr = ncStatus.getRuleConsidered();
             }
             String statusSeparator = ", ";
             if (includeSeparatorBefore){
                 nomStatusTags.add(new TaggedText(TagEnum.separator, statusSeparator));
             }
-            nomStatusTags.add(new TaggedText(TagEnum.nomStatus, nomStatusStr));
+            nomStatusTags.add(new TaggedText(TagEnum.nomStatus, nomStatusStr, new TypedEntityReference<>(ncStatus.getClass(), ncStatus.getUuid())));
             if (includeSeparatorAfter){
                 nomStatusTags.add(new TaggedText(TagEnum.postSeparator, ","));
             }
@@ -124,13 +116,8 @@ public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
         return nomStatusTags;
     }
 
-
-    /**
-     * Generates and returns the "name cache" (only scientific name without author teams and year).
-     * @see eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy#getNameCache(eu.etaxonomy.cdm.model.name.TaxonName)
-     */
     @Override
-    public String getNameCache(T nonViralName) {
+    public String getNameCache(TaxonName nonViralName) {
         List<TaggedText> tags = getTaggedName(nonViralName);
         if (tags == null){
             return null;
@@ -140,6 +127,16 @@ public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
         }
     }
 
+    @Override
+    public String getNameCache(TaxonName nonViralName, HTMLTagRules htmlTagRules) {
+        List<TaggedText> tags = getTaggedName(nonViralName);
+        if (tags == null){
+            return null;
+        }else{
+            String result = createString(tags, htmlTagRules);
+            return result;
+        }
+    }
 
     /**
      * Generates and returns the title cache of the given name.
@@ -149,13 +146,13 @@ public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
      * @see eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy#getTitleCache(eu.etaxonomy.cdm.model.common.IdentifiableEntity)
      */
     @Override
-    public String getTitleCache(T nonViralName) {
-        return getTitleCache(nonViralName, null);
+    public String getTitleCache(TaxonName taxonName) {
+        return getTitleCache(taxonName, null);
     }
 
     @Override
-    public String getTitleCache(T nonViralName, HTMLTagRules htmlTagRules) {
-        List<TaggedText> tags = getTaggedTitle(nonViralName);
+    public String getTitleCache(TaxonName taxonName, HTMLTagRules htmlTagRules) {
+        List<TaggedText> tags = getTaggedTitle(taxonName);
         if (tags == null){
             return null;
         }else{
@@ -165,7 +162,7 @@ public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
     }
 
     @Override
-    public List<TaggedText> getTaggedTitle(T taxonName) {
+    public List<TaggedText> getTaggedTitle(TaxonName taxonName) {
         if (taxonName == null){
             return null;
         }
@@ -179,41 +176,34 @@ public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
         }else{
             return doGetTaggedTitle(taxonName);
         }
-
     }
 
-    protected abstract List<TaggedText> doGetTaggedTitle(T taxonName);
+    protected abstract List<TaggedText> doGetTaggedTitle(TaxonName taxonName);
 
     @Override
-    public List<TaggedText> getTaggedFullTitle(T nonViralName) {
+    public List<TaggedText> getTaggedFullTitle(TaxonName taxonName) {
         List<TaggedText> tags = new ArrayList<>();
 
         //null
-        if (nonViralName == null){
+        if (taxonName == null){
             return null;
         }
 
         //protected full title cache
-        if (nonViralName.isProtectedFullTitleCache()){
-            tags.add(new TaggedText(TagEnum.fullName, nonViralName.getFullTitleCache()));
+        if (taxonName.isProtectedFullTitleCache()){
+            tags.add(new TaggedText(TagEnum.fullName, taxonName.getFullTitleCache()));
             return tags;
         }
 
         //title cache
 //      String titleCache = nonViralName.getTitleCache();
-        List<TaggedText> titleTags = getTaggedTitle(nonViralName);
+        List<TaggedText> titleTags = getTaggedTitle(taxonName);
         tags.addAll(titleTags);
 
         //reference
-        String microReference = nonViralName.getNomenclaturalMicroReference();
-        INomenclaturalReference ref = nonViralName.getNomenclaturalReference();
-        String referenceCache = null;
-        if (ref != null){
-            Reference reference = HibernateProxyHelper.deproxy(ref, Reference.class);
-            referenceCache = reference.getNomenclaturalCitation(microReference);
-        }
+        String referenceCache = NomenclaturalSourceFormatter.INSTANCE().format(taxonName.getNomenclaturalSource());
             //add to tags
-        if (StringUtils.isNotBlank(referenceCache)){
+        if (isNotBlank(referenceCache)){
             if (! referenceCache.trim().startsWith("in ")){
                 String refConcat = ", ";
                 tags.add(new TaggedText(TagEnum.separator, refConcat));
@@ -221,56 +211,51 @@ public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
             tags.add(new TaggedText(TagEnum.reference, referenceCache));
         }
 
-        addOriginalSpelling(tags, nonViralName);
+        addOriginalSpelling(tags, taxonName);
 
         //nomenclatural status
-        tags.addAll(getNomStatusTags(nonViralName, true, false));
+        tags.addAll(getNomStatusTags(taxonName, true, false));
         return tags;
-
     }
 
-    protected void addOriginalSpelling(List<TaggedText> tags, ITaxonNameBase name){
-        String originalName = getOriginalNameString(name, tags);
-        if (StringUtils.isNotBlank(originalName)){
-            tags.add(new TaggedText(TagEnum.name, originalName));
-        }
-    }
+    protected void addOriginalSpelling(List<TaggedText> tags, TaxonName currentName){
 
-    private String getOriginalNameString(ITaxonNameBase currentName, List<TaggedText> originalNameTaggs) {
-        List<String> originalNameStrings = new ArrayList<>(1);
         currentName = CdmBase.deproxy(currentName);
         //Hibernate.initialize(currentName.getRelationsToThisName());
-        for (NameRelationship nameRel : currentName.getRelationsToThisName()){  //handle list, just in case we have strange data; this may result in strange looking results
-            NameRelationshipType type = nameRel.getType();
-            if(type != null && type.equals(NameRelationshipType.ORIGINAL_SPELLING())){
-                String originalNameString;
-                TaxonName originalName = nameRel.getFromName();
-                if (!originalName.isNonViral()){
-                    originalNameString = originalName.getTitleCache();
-                }else{
-                    INonViralName originalNvName = CdmBase.deproxy(originalName);
-                    originalNameString = makeOriginalNameString(currentName, originalNvName, originalNameTaggs);
+        TaxonName originalName = currentName.getOriginalSpelling();
+        if (originalName != null){
+            String originalInfo;
+            tags.add(TaggedText.NewSeparatorInstance(" [as \""));
+            if (!originalName.isNonViral()){
+                originalInfo = originalName.getTitleCache();
+                tags.add(new TaggedText(TagEnum.name, originalInfo));
+            }else{
+                INonViralName originalNvName = CdmBase.deproxy(originalName);
+                originalInfo = makeOriginalInfo(originalNvName, tags);
+                for (String split : originalInfo.split(" ")){
+                    if (split.matches(NonViralNameParserImplRegExBase.infraSpeciesMarker)
+                            || split.matches(NonViralNameParserImplRegExBase.oldInfraSpeciesMarker)) {
+                        tags.add(new TaggedText(TagEnum.rank, split));
+                    }else{
+                        tags.add(new TaggedText(TagEnum.name, split));
+                    }
                 }
-                originalNameStrings.add("[as " + UTF8.QUOT_DBL_LOW9 + originalNameString + UTF8.QUOT_DBL_LEFT + "]");
             }
-        }
-        if (originalNameStrings.size() > 0){
-            String result = CdmUtils.concat("", originalNameStrings.toArray(new String[originalNameStrings.size()])) ;
-            return result;
+            tags.add(TaggedText.NewSeparatorInstance("\"]"));
         }else{
-            return null;
+            return;
         }
     }
 
-    private String makeOriginalNameString(ITaxonNameBase currentName, INonViralName originalName,
+    private String makeOriginalInfo(INonViralName originalName,
             List<TaggedText> currentNameTags) {
         //use cache if necessary
         String cacheToUse = null;
-        if (originalName.isProtectedNameCache() && StringUtils.isNotBlank(originalName.getNameCache())){
+        if (originalName.isProtectedNameCache() && isNotBlank(originalName.getNameCache())){
             cacheToUse = originalName.getNameCache();
-        }else if (originalName.isProtectedTitleCache() && StringUtils.isNotBlank(originalName.getTitleCache())){
+        }else if (originalName.isProtectedTitleCache() && isNotBlank(originalName.getTitleCache())){
             cacheToUse = originalName.getTitleCache();
-        }else if (originalName.isProtectedFullTitleCache() && StringUtils.isNotBlank(originalName.getFullTitleCache())){
+        }else if (originalName.isProtectedFullTitleCache() && isNotBlank(originalName.getFullTitleCache())){
             cacheToUse = originalName.getFullTitleCache();
         }
         if (cacheToUse != null){
@@ -278,48 +263,41 @@ public abstract class NameCacheStrategyBase<T extends ITaxonNameBase>
         }
         //use atomized data
         //get originalNameParts array
-        String originalNameString = originalName.getNameCache();
-        if (originalNameString == null){
-            originalNameString = originalName.getTitleCache();
+        String originalInfo = originalName.getNameCache();
+        if (originalInfo == null){
+            originalInfo = originalName.getTitleCache();
         }
-        if (originalNameString == null){  //should not happen
-            originalNameString = originalName.getFullTitleCache();
+        if (originalInfo == null){  //should not happen
+            originalInfo = originalName.getFullTitleCache();
         }
-        String[] originalNameSplit = originalNameString.split("\\s+");
+        String[] originalNameSplit = originalInfo.split("\\s+");
 
         //get current name parts
         String currentNameString = createString(currentNameTags);
         String[] currentNameSplit = currentNameString.split("\\s+");
 
         //compute string
-        String result = originalNameString;
+        String result = originalInfo;
+        Integer firstDiff = null;
+        Integer lastDiff = -1;
         for (int i = 0; i < Math.min(originalNameSplit.length, currentNameSplit.length); i++){
-            if (originalNameSplit[i].equals(currentNameSplit[i])){
-                result = result.replaceFirst(originalNameSplit[i], "").trim();
+            if (!originalNameSplit[i].equals(currentNameSplit[i])){
+                lastDiff = i;
+                firstDiff = (firstDiff == null) ? i : firstDiff;
             }
         }
-        //old
-//      if (originalName.getGenusOrUninomial() != null && originalName.getGenusOrUninomial().equals(currentName.getGenusOrUninomial())){
-//
-//      }
+        if (firstDiff != null){
+            result = CdmUtils.concat(" ", Arrays.asList(originalNameSplit).subList(firstDiff, lastDiff+1).toArray(new String[0]));
+        }
+
         return result;
     }
 
-    /**
-     * @param tags
-     * @return
-     */
     protected String createString(List<TaggedText> tags) {
         return TaggedCacheHelper.createString(tags);
     }
 
-    /**
-     * @param tags
-     * @param htmlTagRules
-     * @return
-     */
     protected String createString(List<TaggedText> tags, HTMLTagRules htmlTagRules) {
         return TaggedCacheHelper.createString(tags, htmlTagRules);
     }
-
-}
+}
\ No newline at end of file