import java.util.Set;\r
import java.util.UUID;\r
\r
+import org.apache.commons.lang.StringUtils;\r
import org.apache.log4j.Logger;\r
\r
import eu.etaxonomy.cdm.common.CdmUtils;\r
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
import eu.etaxonomy.cdm.model.agent.INomenclaturalAuthor;\r
import eu.etaxonomy.cdm.model.agent.Team;\r
import eu.etaxonomy.cdm.model.common.Language;\r
import eu.etaxonomy.cdm.model.common.Representation;\r
+import eu.etaxonomy.cdm.model.name.BotanicalName;\r
+import eu.etaxonomy.cdm.model.name.HybridRelationship;\r
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;\r
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;\r
import eu.etaxonomy.cdm.model.name.NonViralName;\r
import eu.etaxonomy.cdm.model.name.Rank;\r
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;\r
+import eu.etaxonomy.cdm.strategy.TagEnum;\r
+import eu.etaxonomy.cdm.strategy.TaggedText;\r
+import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;\r
+import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImplRegExBase;\r
\r
\r
/**\r
- * This class is a default implementation for the INonViralNameCacheStrategy<T extends NonViralName> interface.\r
- * The method actually implements a cache strategy for botanical names so no method has to be overwritten by\r
+ * This class is a default implementation for the INonViralNameCacheStrategy<T extends NonViralName> \r
+ * interface.<BR>\r
+ * The method implements a cache strategy for botanical names so no method has to be overwritten by\r
* a subclass for botanic names.\r
- * Where differing from this Default BotanicNameCacheStrategy other subclasses should overwrite the existing methods\r
- * e.g. a CacheStrategy for zoological names should overwrite getAuthorAndExAuthor\r
+ * Where differing from this default botanic name strategy other subclasses should overwrite the\r
+ * existing methods, e.g. a CacheStrategy for zoological names should overwrite getAuthorAndExAuthor\r
* @author a.mueller\r
*/\r
/**\r
return new NonViralNameDefaultCacheStrategy();\r
}\r
\r
+ /**\r
+ * Factory method\r
+ * @return NonViralNameDefaultCacheStrategy A new instance of NonViralNameDefaultCacheStrategy\r
+ */\r
+ public static <T extends NonViralName<?>> NonViralNameDefaultCacheStrategy<T> NewInstance(Class<T> clazz){\r
+ return new NonViralNameDefaultCacheStrategy<T>();\r
+ }\r
+ \r
/**\r
* Constructor\r
*/\r
}\r
\r
\r
- public void setBasionymAuthorCombinationAuthorSeperator(\r
- CharSequence basionymAuthorCombinationAuthorSeperator) {\r
+ public void setBasionymAuthorCombinationAuthorSeperator( CharSequence basionymAuthorCombinationAuthorSeperator) {\r
BasionymAuthorCombinationAuthorSeperator = basionymAuthorCombinationAuthorSeperator;\r
}\r
\r
\r
//** *****************************************************************************************/\r
- \r
- \r
+\r
/* (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getNameCache()\r
+ * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTitleCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)\r
*/\r
@Override\r
public String getTitleCache(T nonViralName) {\r
- if (nonViralName == null){\r
+ List<TaggedText> tags = getTaggedTitle(nonViralName);\r
+ if (tags == null){\r
return null;\r
+ }else{\r
+ String result = createString(tags);\r
+ return result;\r
}\r
- String result = "";\r
- if (isAutonym(nonViralName)){\r
- String speciesPart = getSpeciesNameCache(nonViralName);\r
- //TODO should this include basionym authors and ex authors\r
- INomenclaturalAuthor author = nonViralName.getCombinationAuthorTeam();\r
- String authorPart = "";\r
- if (author != null){\r
- authorPart = CdmUtils.Nz(author.getNomenclaturalTitle());\r
- }\r
- INomenclaturalAuthor basAuthor = nonViralName.getBasionymAuthorTeam();\r
- String basAuthorPart = "";\r
- if (basAuthor != null){\r
- basAuthorPart = CdmUtils.Nz(basAuthor.getNomenclaturalTitle());\r
- }\r
- if (! "".equals(basAuthorPart)){\r
- authorPart = "("+ basAuthorPart +")" + authorPart;\r
- }\r
- String infraSpeciesPart = (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet()));\r
-\r
- String infraSpeciesSeparator = "";\r
- if (nonViralName.getRank() == null || !nonViralName.getRank().isInfraSpecific()){\r
- //TODO handle exception\r
- logger.warn("Rank for autonym does not exist or is not lower than species !!");\r
- }else{\r
- infraSpeciesSeparator = nonViralName.getRank().getAbbreviation();\r
- }\r
- \r
- result = CdmUtils.concat(" ", new String[]{speciesPart, authorPart, infraSpeciesSeparator, infraSpeciesPart});\r
- result = result.trim().replace("null", "");\r
- }else{ //not Autonym\r
- String nameCache = CdmUtils.Nz(getNameCache(nonViralName));\r
- String authorCache = CdmUtils.Nz(getAuthorshipCache(nonViralName));\r
- result = CdmUtils.concat(NameAuthorSeperator, nameCache, authorCache);\r
- }\r
- return result;\r
}\r
- \r
- \r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getFullTitleCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)\r
+ */\r
@Override\r
public String getFullTitleCache(T nonViralName) {\r
- //null\r
- if (nonViralName == null){\r
+ List<TaggedText> tags = getTaggedFullTitle(nonViralName);\r
+ if (tags == null){\r
return null;\r
+ }else{\r
+ String result = createString(tags);\r
+ return result;\r
}\r
- //full title cache\r
- if (nonViralName.isProtectedFullTitleCache() == true) {\r
- return nonViralName.getFullTitleCache();\r
- }\r
- \r
- String result = "";\r
- //title cache\r
- String titleCache = getTitleCache(nonViralName);\r
- \r
- String microReference = nonViralName.getNomenclaturalMicroReference();\r
- INomenclaturalReference ref = nonViralName.getNomenclaturalReference();\r
- String referenceBaseCache = null;\r
- if (ref != null){\r
- referenceBaseCache = ref.getNomenclaturalCitation(microReference);\r
- }\r
- \r
- //make nomenclatural status\r
- String ncStatusCache = "";\r
- Set<NomenclaturalStatus> ncStati = nonViralName.getStatus();\r
- Iterator<NomenclaturalStatus> iterator = ncStati.iterator();\r
- while (iterator.hasNext()) {\r
- NomenclaturalStatus ncStatus = (NomenclaturalStatus)iterator.next();\r
- NomenclaturalStatusType statusType = ncStatus.getType();\r
- Language lang = Language.LATIN();\r
- Representation repr = statusType.getRepresentation(lang);\r
- ncStatusCache = ", " + repr.getAbbreviatedLabel();\r
- }\r
- String refConcat = " ";\r
- if (referenceBaseCache != null && ! referenceBaseCache.trim().startsWith("in ")){\r
- refConcat = ", ";\r
- }\r
- result = CdmUtils.concat(refConcat, titleCache, referenceBaseCache);\r
- result = CdmUtils.concat("", result, ncStatusCache);\r
- return result;\r
}\r
- \r
+\r
\r
/**\r
* Generates and returns the "name cache" (only scientific name without author teams and year).\r
* @see eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy#getNameCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)\r
*/\r
public String getNameCache(T nonViralName) {\r
- if (nonViralName == null){\r
+ List<TaggedText> tags = getTaggedName(nonViralName);\r
+ if (tags == null){\r
return null;\r
+ }else{\r
+ String result = createString(tags);\r
+ return result;\r
}\r
- String result;\r
- Rank rank = nonViralName.getRank();\r
+ }\r
+ \r
+\r
+ /**\r
+ * Creates a string from tagged text.\r
+ * @param tags\r
+ * @return\r
+ */\r
+ protected static String createString(List<TaggedText> tags) {\r
+ StringBuffer result = new StringBuffer();\r
\r
- if (rank == null){\r
- result = getRanklessNameCache(nonViralName);\r
- }else if (rank.isInfraSpecific()){\r
- result = getInfraSpeciesNameCache(nonViralName);\r
- }else if (rank.isSpecies()){\r
- result = getSpeciesNameCache(nonViralName);\r
- }else if (rank.isInfraGeneric()){\r
- result = getInfraGenusNameCache(nonViralName);\r
- }else if (rank.isGenus()){\r
- result = getGenusOrUninomialNameCache(nonViralName);\r
- }else if (rank.isSupraGeneric()){\r
- result = getGenusOrUninomialNameCache(nonViralName);\r
- }else{ \r
- logger.warn("Name Strategy for Name (UUID: " + nonViralName.getUuid() + ") not yet implemented");\r
- result = "";\r
+ boolean isSeparator;\r
+ boolean wasSeparator = true; //true for start tag\r
+ for (TaggedText tag: tags){\r
+ isSeparator = tag.getType().equals(TagEnum.separator);\r
+ if (! wasSeparator && ! isSeparator ){\r
+ result.append(" ");\r
+ }\r
+ result.append(tag.getText());\r
+ wasSeparator = isSeparator;\r
}\r
- return result;\r
+ return result.toString();\r
}\r
\r
+// ******************* Authorship ******************************/ \r
+ \r
\r
/* (non-Javadoc)\r
* @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy#getAuthorCache(eu.etaxonomy.cdm.model.name.NonViralName)\r
if (nonViralName.isProtectedAuthorshipCache() == true) {\r
return nonViralName.getAuthorshipCache();\r
}\r
- \r
+ return getNonCacheAuthorshipCache(nonViralName);\r
+\r
+ }\r
+ \r
+ /**\r
+ * Returns the authorshipcache string for the atomized authorship fields. Does not use the authorshipfield.\r
+ * @throws NullPointerException if nonViralName is null.\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ protected String getNonCacheAuthorshipCache(T nonViralName){\r
String result = "";\r
INomenclaturalAuthor combinationAuthor = nonViralName.getCombinationAuthorTeam();\r
INomenclaturalAuthor exCombinationAuthor = nonViralName.getExCombinationAuthorTeam();\r
}\r
result = exAuthorString + authorString;\r
return result;\r
- \r
}\r
\r
\r
+ /**\r
+ * Checks if the given name should include the author in it's cached version.<BR>\r
+ * This is usually the case but not for <i>species aggregates</i>.\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ protected boolean nameIncludesAuthorship(NonViralName<?> nonViralName){\r
+ Rank rank = nonViralName.getRank();\r
+ if (rank != null && rank.isSpeciesAggregate()){\r
+ return false;\r
+ }else{\r
+ return true;\r
+ }\r
+ }\r
+ \r
+// ************* TAGGED NAME ***************************************/ \r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTaggedFullTitle(eu.etaxonomy.cdm.model.name.TaxonNameBase)\r
+ */\r
+ @Override\r
+ public List<TaggedText> getTaggedFullTitle(T nonViralName) {\r
+ List<TaggedText> tags = new ArrayList<TaggedText>();\r
+ \r
+ //null\r
+ if (nonViralName == null){\r
+ return null;\r
+ }\r
+ \r
+ //protected full title cache\r
+ if (nonViralName.isProtectedFullTitleCache()){\r
+ tags.add(new TaggedText(TagEnum.fullName, nonViralName.getFullTitleCache()));\r
+ return tags;\r
+ }\r
+ \r
+ //title cache\r
+// String titleCache = nonViralName.getTitleCache();\r
+ List<TaggedText> titleTags = getTaggedTitle(nonViralName);\r
+ tags.addAll(titleTags);\r
+ \r
+ \r
+ //reference\r
+ String microReference = nonViralName.getNomenclaturalMicroReference();\r
+ INomenclaturalReference ref = nonViralName.getNomenclaturalReference();\r
+ String referenceBaseCache = null;\r
+ if (ref != null){\r
+ INomenclaturalReference nomenclaturalReference = HibernateProxyHelper.deproxy(ref, INomenclaturalReference.class);\r
+ nomenclaturalReference.setCacheStrategy(nomenclaturalReference.getType().getCacheStrategy());\r
+ referenceBaseCache = nomenclaturalReference.getNomenclaturalCitation(microReference);\r
+ }\r
+ //add to tags\r
+ if (StringUtils.isNotBlank(referenceBaseCache)){\r
+ if (! referenceBaseCache.trim().startsWith("in ")){\r
+ String refConcat = ", ";\r
+ tags.add(new TaggedText(TagEnum.separator, refConcat));\r
+ }\r
+ tags.add(new TaggedText(TagEnum.reference, referenceBaseCache));\r
+ }\r
+ \r
+ //nomenclatural status\r
+ Set<NomenclaturalStatus> ncStati = nonViralName.getStatus();\r
+ Iterator<NomenclaturalStatus> iterator = ncStati.iterator();\r
+ List<TaggedText> nomStatusTags = new ArrayList<TaggedText>();\r
+ while (iterator.hasNext()) {\r
+ NomenclaturalStatus ncStatus = (NomenclaturalStatus)iterator.next();\r
+ // since the NewInstance method of nomencatural status allows null as parameter\r
+ // we have to check for null values here\r
+ String suffix = "not defined";\r
+ if(ncStatus.getType() != null){\r
+ NomenclaturalStatusType statusType = ncStatus.getType();\r
+ Language lang = Language.LATIN();\r
+ Representation repr = statusType.getRepresentation(lang);\r
+ if (repr != null){\r
+ suffix = repr.getAbbreviatedLabel();\r
+ }else{\r
+ String message = "No latin representation available for nom. status. " + statusType.getTitleCache();\r
+ logger.warn(message);\r
+ throw new IllegalStateException(message);\r
+ }\r
+ }else if(ncStatus.getRuleConsidered() != null && ! ncStatus.getRuleConsidered().equals("")){\r
+ suffix = ncStatus.getRuleConsidered();\r
+ }\r
+ String statusSeparator = ", ";\r
+ nomStatusTags.add(new TaggedText(TagEnum.separator, statusSeparator));\r
+ nomStatusTags.add(new TaggedText(TagEnum.nomStatus, suffix));\r
+ }\r
+ tags.addAll(nomStatusTags);\r
+ return tags;\r
+ \r
+ }\r
+ \r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTaggedTitle(eu.etaxonomy.cdm.model.name.TaxonNameBase)\r
+ */\r
+ public List<TaggedText> getTaggedTitle(T nonViralName) {\r
+ if (nonViralName == null){\r
+ return null;\r
+ }\r
+\r
+ List<TaggedText> tags = new ArrayList<TaggedText>();\r
+ \r
+ //TODO how to handle protected fullTitleCache here?\r
+ \r
+ if (nonViralName.isProtectedTitleCache()){\r
+ //protected title cache\r
+ tags.add(new TaggedText(TagEnum.name, nonViralName.getTitleCache()));\r
+ return tags;\r
+ }else if (nonViralName.isHybridFormula()){\r
+ //hybrid formula\r
+ String hybridSeparator = NonViralNameParserImplRegExBase.hybridSign;\r
+ boolean isFirst = true;\r
+ List<HybridRelationship> rels = nonViralName.getOrderedChildRelationships();\r
+ for (HybridRelationship rel: rels){\r
+ if (! isFirst){\r
+ tags.add(new TaggedText(TagEnum.hybridSign, hybridSeparator));\r
+ }\r
+ isFirst = false;\r
+ tags.addAll(getTaggedTitle((T)rel.getParentName()));\r
+ }\r
+ return tags;\r
+ }else if (nonViralName.isAutonym()){\r
+ //Autonym\r
+ tags.addAll(handleTaggedAutonym(nonViralName));\r
+ }else{ //not Autonym\r
+// String nameCache = nonViralName.getNameCache(); //OLD: CdmUtils.Nz(getNameCache(nonViralName));\r
+ List<TaggedText> nameTags = getTaggedName(nonViralName);\r
+ tags.addAll(nameTags);\r
+ if (nameIncludesAuthorship(nonViralName)){\r
+ String authorCache = getAuthorshipCache(nonViralName);\r
+ if (StringUtils.isNotBlank(authorCache)){\r
+ tags.add(new TaggedText(TagEnum.authors, authorCache));\r
+ }\r
+ }\r
+ }\r
+ return tags;\r
+\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Returns the tag list of the name part (without author and reference).\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ public List<TaggedText> getTaggedName(T nonViralName) {\r
+ if (nonViralName == null){\r
+ return null;\r
+ }\r
+ List<TaggedText> tags = new ArrayList<TaggedText>();\r
+ Rank rank = nonViralName.getRank();\r
+ \r
+ if (nonViralName.isProtectedNameCache()){\r
+ tags.add(new TaggedText(TagEnum.name, nonViralName.getNameCache()));\r
+ }else if (rank == null){\r
+ tags = getRanklessTaggedNameCache(nonViralName);\r
+// }else if (nonViralName.isInfragenericUnranked()){\r
+// result = getUnrankedInfragenericNameCache(nonViralName);\r
+ }else if (rank.isInfraSpecific()){\r
+ tags = getInfraSpeciesTaggedNameCache(nonViralName);\r
+ }else if (rank.isSpecies()){\r
+ tags = getSpeciesTaggedNameCache(nonViralName);\r
+ }else if (rank.isInfraGeneric()){\r
+ tags = getInfraGenusTaggedNameCache(nonViralName);\r
+ }else if (rank.isGenus()){\r
+ tags = getGenusOrUninomialTaggedNameCache(nonViralName);\r
+ }else if (rank.isSupraGeneric()){\r
+ tags = getGenusOrUninomialTaggedNameCache(nonViralName);\r
+ }else{ \r
+ logger.warn("Name Strategy for Name (UUID: " + nonViralName.getUuid() + ") not yet implemented");\r
+ }\r
+ //TODO handle appended phrase here instead of different places, check first if this is true for all\r
+ //cases\r
+ \r
+ return tags;\r
+\r
+ }\r
+\r
+\r
+ \r
+\r
+//***************************** PRIVATES ***************************************/\r
+ \r
+\r
+ /**\r
+ * Returns the tag list for an autonym taxon.\r
+ * \r
+ * @see NonViralName#isAutonym()\r
+ * @see BotanicalName#isAutonym()\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ private List<TaggedText> handleTaggedAutonym(T nonViralName) {\r
+ \r
+ //species part\r
+ List<TaggedText> tags = getSpeciesTaggedNameCache(nonViralName);\r
+ \r
+ //author\r
+ //TODO should this include basionym authors and ex authors\r
+ INomenclaturalAuthor author = nonViralName.getCombinationAuthorTeam();\r
+ String authorPart = "";\r
+ if (author != null){\r
+ authorPart = CdmUtils.Nz(author.getNomenclaturalTitle());\r
+ }\r
+ INomenclaturalAuthor basAuthor = nonViralName.getBasionymAuthorTeam();\r
+ String basAuthorPart = "";\r
+ if (basAuthor != null){\r
+ basAuthorPart = CdmUtils.Nz(basAuthor.getNomenclaturalTitle());\r
+ }\r
+ if (! "".equals(basAuthorPart)){\r
+ authorPart = "("+ basAuthorPart +") " + authorPart;\r
+ }\r
+ if (StringUtils.isNotBlank(authorPart)){\r
+ tags.add(new TaggedText(TagEnum.authors, authorPart));\r
+ }\r
+ \r
+ \r
+ //infra species marker\r
+ if (nonViralName.getRank() == null || !nonViralName.getRank().isInfraSpecific()){\r
+ //TODO handle exception\r
+ logger.warn("Rank for autonym does not exist or is not lower than species !!");\r
+ }else{\r
+ String infraSpeciesMarker = nonViralName.getRank().getAbbreviation();\r
+ if (StringUtils.isNotBlank(infraSpeciesMarker)){\r
+ tags.add(new TaggedText(TagEnum.rank, infraSpeciesMarker));\r
+ }\r
+ }\r
+ \r
+ //infra species\r
+ String infraSpeciesPart = CdmUtils.Nz(nonViralName.getInfraSpecificEpithet()).trim().replace("null", "");\r
+ if (StringUtils.isNotBlank(infraSpeciesPart)){\r
+ tags.add(new TaggedText(TagEnum.name, infraSpeciesPart));\r
+ }\r
+ \r
+ return tags;\r
+ }\r
+ \r
+ \r
+ \r
+ /**\r
+ * Returns the tag list for rankless taxa.\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ protected List<TaggedText> getRanklessTaggedNameCache(NonViralName<?> nonViralName){\r
+ List<TaggedText> tags = getUninomialTaggedPart(nonViralName);\r
+ String speciesEpi = CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim().replace("null", "");\r
+ if (StringUtils.isNotBlank(speciesEpi)){\r
+ tags.add(new TaggedText(TagEnum.name, speciesEpi));\r
+ }\r
+ \r
+ String infraSpeciesEpi = CdmUtils.Nz(nonViralName.getInfraSpecificEpithet()).trim().replace("null", "");\r
+ if (StringUtils.isNotBlank(infraSpeciesEpi)){\r
+ tags.add(new TaggedText(TagEnum.name, infraSpeciesEpi));\r
+ }\r
+ \r
+ //result += " (rankless)";\r
+ addAppendedTaggedPhrase(tags, nonViralName);\r
+ return tags; \r
+ }\r
+\r
+ /**\r
+ * Returns the tag list for the first epithet (including a hybrid sign if required).\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ private List<TaggedText> getUninomialTaggedPart(NonViralName<?> nonViralName) {\r
+ List<TaggedText> tags = new ArrayList<TaggedText>();\r
+ \r
+ if (nonViralName.isMonomHybrid()){\r
+ addHybridPrefix(tags);\r
+ }\r
+ \r
+ String uninomial = CdmUtils.Nz(nonViralName.getGenusOrUninomial()).trim().replace("null", "");\r
+ if (StringUtils.isNotBlank(uninomial)){\r
+ tags.add(new TaggedText(TagEnum.name, uninomial));\r
+ }\r
+ \r
+ return tags;\r
+ }\r
+ \r
+ /**\r
+ * Returns the tag list for an genus or higher taxon.\r
+ * \r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ protected List<TaggedText> getGenusOrUninomialTaggedNameCache(NonViralName<?> nonViralName){\r
+ List<TaggedText> tags = getUninomialTaggedPart(nonViralName);\r
+ addAppendedTaggedPhrase(tags, nonViralName);\r
+ return tags;\r
+ }\r
+ \r
+ /**\r
+ * Returns the tag list for an infrageneric taxon (including species aggregates).\r
+ * \r
+ * @see #getSpeciesAggregateTaggedCache(NonViralName)\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ protected List<TaggedText> getInfraGenusTaggedNameCache(NonViralName<?> nonViralName){\r
+ Rank rank = nonViralName.getRank();\r
+ if (rank.isSpeciesAggregate()){\r
+ return getSpeciesAggregateTaggedCache(nonViralName);\r
+ }\r
+ \r
+ //genus\r
+ List<TaggedText> tags = getUninomialTaggedPart(nonViralName);\r
+ \r
+ //marker\r
+ String infraGenericMarker = "'unhandled infrageneric rank'";\r
+ if (rank != null){\r
+ try {\r
+ infraGenericMarker = rank.getInfraGenericMarker();\r
+ } catch (UnknownCdmTypeException e) {\r
+ infraGenericMarker = "'unhandled infrageneric rank'";\r
+ }\r
+ }\r
+ tags.add(new TaggedText(TagEnum.rank, infraGenericMarker));\r
+ \r
+ \r
+ String infraGenEpi = CdmUtils.Nz(nonViralName.getInfraGenericEpithet()).trim().replace("null", "");\r
+ if (StringUtils.isNotBlank(infraGenEpi)){\r
+ tags.add(new TaggedText(TagEnum.name, infraGenEpi));\r
+ }\r
+ \r
+ addAppendedTaggedPhrase(tags, nonViralName);\r
+ return tags;\r
+ }\r
+ \r
+ /**\r
+ * Returns the tag list for a species aggregate (or similar) taxon.<BR>\r
+ * Possible ranks for a <i>species aggregate</i> are "aggr.", "species group", ... \r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ protected List<TaggedText> getSpeciesAggregateTaggedCache(NonViralName<?> nonViralName){\r
+ List<TaggedText> tags = getGenusAndSpeciesTaggedPart(nonViralName);\r
+ \r
+ addSpeciesAggregateTaggedEpithet(tags, nonViralName);\r
+ addAppendedTaggedPhrase(tags, nonViralName);\r
+ return tags;\r
+ }\r
+ \r
+ /**\r
+ * Adds the aggregate tag to the tag list.\r
+ * @param tags\r
+ * @param nonViralName\r
+ */\r
+ private void addSpeciesAggregateTaggedEpithet(List<TaggedText> tags, NonViralName<?> nonViralName) {\r
+ String marker;\r
+ try {\r
+ marker = nonViralName.getRank().getInfraGenericMarker();\r
+ } catch (UnknownCdmTypeException e) {\r
+ marker = "'unknown aggregat type'";\r
+ }\r
+ if (StringUtils.isNotBlank(marker)){\r
+ tags.add(new TaggedText(TagEnum.rank, marker));\r
+ }\r
+ }\r
+\r
+ \r
+ /**\r
+ * Returns the tag list for a species taxon.\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ protected List<TaggedText> getSpeciesTaggedNameCache(NonViralName<?> nonViralName){\r
+ List<TaggedText> tags = getGenusAndSpeciesTaggedPart(nonViralName);\r
+ addAppendedTaggedPhrase(tags, nonViralName);\r
+ return tags;\r
+ }\r
+\r
+ /**\r
+ * Creates the tag list for an infraspecific taxon. In include is true the result will contain\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ protected List<TaggedText> getInfraSpeciesTaggedNameCache(NonViralName<?> nonViralName){\r
+ return getInfraSpeciesTaggedNameCache(nonViralName, true);\r
+ }\r
+ \r
+ /**\r
+ * Creates the tag list for an infraspecific taxon. In include is true the result will contain\r
+ * the infraspecific marker (e.g. "var.")\r
+ * @param nonViralName\r
+ * @param includeMarker\r
+ * @return\r
+ */\r
+ protected List<TaggedText> getInfraSpeciesTaggedNameCache(NonViralName<?> nonViralName, boolean includeMarker){\r
+ List<TaggedText> tags = getGenusAndSpeciesTaggedPart(nonViralName);\r
+ if (includeMarker){ \r
+ String marker = (nonViralName.getRank().getAbbreviation()).trim().replace("null", "");\r
+ if (StringUtils.isNotBlank(marker)){\r
+ tags.add(new TaggedText(TagEnum.rank, marker));\r
+ }\r
+ }\r
+ String infrSpecEpi = CdmUtils.Nz(nonViralName.getInfraSpecificEpithet());\r
+ if (nonViralName.isTrinomHybrid()){\r
+ addHybridPrefix(tags);\r
+ }\r
+ \r
+ infrSpecEpi = infrSpecEpi.trim().replace("null", "");\r
+ if (StringUtils.isNotBlank(infrSpecEpi)){\r
+ tags.add(new TaggedText(TagEnum.name, infrSpecEpi));\r
+ }\r
+ \r
+ addAppendedTaggedPhrase(tags, nonViralName);\r
+ return tags;\r
+ }\r
+\r
+\r
+ /**\r
+ * Adds a tag for the hybrid sign and an empty separator to avoid trailing whitespaces.\r
+ * @param tags\r
+ */\r
+ private void addHybridPrefix(List<TaggedText> tags) {\r
+ tags.add(new TaggedText(TagEnum.hybridSign, NonViralNameParserImplRegExBase.hybridSign));\r
+ tags.add(new TaggedText(TagEnum.separator, "")); //no whitespace separator\r
+ }\r
+\r
+ /**\r
+ * Creates the tag list for the genus and species part.\r
+ * @param nonViralName\r
+ * @return\r
+ */\r
+ private List<TaggedText> getGenusAndSpeciesTaggedPart(NonViralName<?> nonViralName) {\r
+ //Uninomial\r
+ List<TaggedText> tags = getUninomialTaggedPart(nonViralName);\r
+ \r
+ //InfraGenericEpi\r
+ boolean hasInfraGenericEpi = StringUtils.isNotBlank(nonViralName.getInfraGenericEpithet());\r
+ if (hasInfraGenericEpi){\r
+ String infrGenEpi = nonViralName.getInfraGenericEpithet().trim();\r
+ if (nonViralName.isBinomHybrid()){\r
+// addHybridPrefix(tags); FIXME hybridSign should be tag, but then we need to handle "(" ")" differently.\r
+ infrGenEpi = NonViralNameParserImplRegExBase.hybridSign + infrGenEpi;\r
+ }\r
+ infrGenEpi = "(" + infrGenEpi + ")";\r
+ tags.add(new TaggedText(TagEnum.name, infrGenEpi));\r
+ }\r
+\r
+ //Species Epi\r
+ String specEpi = CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim().replace("null", "");\r
+ if (! hasInfraGenericEpi && nonViralName.isBinomHybrid() || \r
+ hasInfraGenericEpi && nonViralName.isTrinomHybrid()){\r
+ addHybridPrefix(tags); \r
+ }\r
+ if (StringUtils.isNotBlank(specEpi)){\r
+ tags.add(new TaggedText(TagEnum.name, specEpi));\r
+ }\r
+ return tags;\r
+ }\r
+ \r
+ /**\r
+ * Adds the tag for the appended phrase if an appended phrase exists\r
+ * @param tags\r
+ * @param nonViralName\r
+ */\r
+ protected void addAppendedTaggedPhrase(List<TaggedText> tags, NonViralName<?> nonViralName){\r
+ String appendedPhrase = nonViralName ==null ? null : nonViralName.getAppendedPhrase();\r
+ if (StringUtils.isNotEmpty(appendedPhrase)){\r
+ tags.add(new TaggedText(TagEnum.name, appendedPhrase));\r
+ }\r
+ }\r
+\r
+ public String getLastEpithet(T taxonNameBase) {\r
+ Rank rank = taxonNameBase.getRank();\r
+ if(rank.isGenus() || rank.isSupraGeneric()) {\r
+ return taxonNameBase.getGenusOrUninomial();\r
+ } else if(rank.isInfraGeneric()) {\r
+ return taxonNameBase.getInfraGenericEpithet();\r
+ } else if(rank.isSpecies()) {\r
+ return taxonNameBase.getSpecificEpithet();\r
+ } else {\r
+ return taxonNameBase.getInfraSpecificEpithet();\r
+ }\r
+ }\r
+ \r
+// *************************** DEPRECATED ***************************************************/\r
+ \r
+\r
+ //Old: may be replaced once getTagged(Full)Title is fully tested\r
/* (non-Javadoc)\r
* @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTaggedName(eu.etaxonomy.cdm.model.common.CdmBase)\r
*/\r
@Override\r
- public List<Object> getTaggedName(T nonViralName) {\r
+ @Deprecated\r
+ public List<Object> getTaggedNameDeprecated(T nonViralName) {\r
List<Object> tags = new ArrayList<Object>();\r
- tags.add(nonViralName.getGenusOrUninomial());\r
+ \r
+ if (nonViralName.isProtectedNameCache() ||\r
+ nonViralName.isProtectedAuthorshipCache() ||\r
+ nonViralName.isProtectedFullTitleCache() ||\r
+ nonViralName.isProtectedTitleCache()){\r
+ tags.add(nonViralName.getTitleCache());\r
+ return tags;\r
+ }\r
+ \r
+ // Why does it make sense to add the nameCache in case of non existing genusOrUninomial?\r
+// if (nonViralName.getGenusOrUninomial() == null){\r
+// tags.add(nonViralName.getNameCache());\r
+// }else{\r
+ \r
+ if (nonViralName.getGenusOrUninomial() != null) {\r
+ tags.add(nonViralName.getGenusOrUninomial());\r
+ }\r
if (nonViralName.isSpecies() || nonViralName.isInfraSpecific()){\r
tags.add(nonViralName.getSpecificEpithet()); \r
}\r
if (nonViralName.isInfraGeneric()){\r
//TODO choose right strategy or generic approach?\r
// --- strategy 1 --- \r
- tags.add(nonViralName.getRank()); \r
- tags.add(nonViralName.getInfraGenericEpithet()); \r
+ \r
+ if (nonViralName.getRank().isSpeciesAggregate()){\r
+ tags.add(nonViralName.getSpecificEpithet());\r
+ tags.add(getSpeciesAggregateEpithet(nonViralName));\r
+ }else{\r
+ tags.add(nonViralName.getRank()); \r
+ tags.add(nonViralName.getInfraGenericEpithet()); \r
+ }\r
// --- strategy 2 --- \r
// tags.add('('+nvn.getInfraGenericEpithet()+')'); \r
}\r
Team authorTeam = Team.NewInstance();\r
authorTeam.setProtectedTitleCache(true);\r
- authorTeam.setTitleCache(nonViralName.getAuthorshipCache());\r
+ authorTeam.setTitleCache(nonViralName.getAuthorshipCache(), true);\r
tags.add(authorTeam);\r
\r
- // Name is an autonym. Rank and infraspecific eitheton follow the author\r
+ // Name is an autonym. Rank and infraspecific epitheton follow the author\r
if (nonViralName.isInfraSpecific() && nonViralName.getSpecificEpithet().equals(nonViralName.getInfraSpecificEpithet())){\r
tags.add(nonViralName.getRank()); \r
tags.add(nonViralName.getInfraSpecificEpithet()); \r
}\r
\r
- if(! "".equals(nonViralName.getAppendedPhrase())){\r
+ if(! "".equals(nonViralName.getAppendedPhrase())&& (nonViralName.getAppendedPhrase() != null)){\r
tags.add(nonViralName.getAppendedPhrase());\r
}\r
\r
return tags;\r
}\r
\r
-\r
- /************** PRIVATES ****************/\r
- \r
- protected String getRanklessNameCache(NonViralName nonViralName){\r
- String result = "";\r
- result = (result + (nonViralName.getGenusOrUninomial())).trim().replace("null", "");\r
- result += " " + (CdmUtils.Nz(nonViralName.getSpecificEpithet())).trim();\r
- result += " " + (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet())).trim();\r
- result = result.trim().replace("null", "");\r
- //result += " (rankless)";\r
- result = addAppendedPhrase(result, nonViralName);\r
- return result; \r
- }\r
- \r
\r
- protected String getGenusOrUninomialNameCache(NonViralName nonViralName){\r
- String result;\r
- result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());\r
- result = addAppendedPhrase(result, nonViralName);\r
- return result;\r
- }\r
- \r
- protected String getInfraGenusNameCache(NonViralName nonViralName){\r
- String result;\r
- result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());\r
- result += " (" + (CdmUtils.Nz(nonViralName.getInfraGenericEpithet()) + ")").trim().replace("null", "");\r
- result = addAppendedPhrase(result, nonViralName);\r
- return result;\r
+ /**\r
+ * @deprecated use only for {@link #getTaggedNameDeprecated(NonViralName)}. Delete when the later \r
+ * is deleted.\r
+ */\r
+ @Deprecated \r
+ private String getSpeciesAggregateEpithet(NonViralName<?> nonViralName) {\r
+ String marker;\r
+ try {\r
+ marker = nonViralName.getRank().getInfraGenericMarker();\r
+ } catch (UnknownCdmTypeException e) {\r
+ marker = "'unknown aggregat type'";\r
}\r
+ return marker;\r
+ }\r
\r
- \r
- protected String getSpeciesNameCache(NonViralName nonViralName){\r
- String result;\r
- result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());\r
- result += " " + CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim().replace("null", "");\r
- result = addAppendedPhrase(result, nonViralName);\r
- return result;\r
- }\r
- \r
- \r
- protected String getInfraSpeciesNameCache(NonViralName nonViralName){\r
- String result;\r
- result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());\r
- result += " " + (CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim()).replace("null", "");\r
- if (! isAutonym(nonViralName)){\r
- result += " " + (nonViralName.getRank().getAbbreviation()).trim().replace("null", "");\r
- }\r
- result += " " + (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet())).trim().replace("null", "");\r
- result = addAppendedPhrase(result, nonViralName);\r
- return result;\r
- }\r
- \r
- \r
- /**\r
- * @param name\r
- * @return true, if name has Rank, Rank is below species and species epithet equals infraSpeciesEpithtet, else false\r
- */\r
- protected boolean isAutonym(NonViralName nonViralName){\r
- if (nonViralName != null && nonViralName.getRank() != null && nonViralName.getSpecificEpithet() != null && nonViralName.getInfraSpecificEpithet() != null && \r
- nonViralName.getRank().isInfraSpecific() && nonViralName.getSpecificEpithet().trim().equals(nonViralName.getInfraSpecificEpithet().trim())){\r
- return true;\r
- }else{\r
- return false;\r
- }\r
- }\r
- \r
- protected String addAppendedPhrase(String resultString, NonViralName nonViralName){\r
- String appendedPhrase = nonViralName ==null ? null : nonViralName.getAppendedPhrase();\r
- if (resultString == null){\r
- return appendedPhrase;\r
- }else if(appendedPhrase == null || "".equals(appendedPhrase.trim())) {\r
- return resultString;\r
- }else if ("".equals(resultString)){\r
- return resultString + appendedPhrase;\r
- }else {\r
- return resultString + " " + appendedPhrase;\r
- }\r
- }\r
\r
}\r