2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.strategy
.cache
.name
;
11 import java
.util
.ArrayList
;
12 import java
.util
.Iterator
;
13 import java
.util
.List
;
15 import java
.util
.UUID
;
17 import org
.apache
.commons
.lang
.StringUtils
;
18 import org
.apache
.log4j
.Logger
;
20 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
21 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
22 import eu
.etaxonomy
.cdm
.model
.agent
.INomenclaturalAuthor
;
23 import eu
.etaxonomy
.cdm
.model
.agent
.Team
;
24 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
25 import eu
.etaxonomy
.cdm
.model
.common
.Representation
;
26 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
27 import eu
.etaxonomy
.cdm
.model
.name
.HybridRelationship
;
28 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
29 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
30 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
31 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
32 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
33 import eu
.etaxonomy
.cdm
.strategy
.TagEnum
;
34 import eu
.etaxonomy
.cdm
.strategy
.TaggedText
;
35 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
36 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImplRegExBase
;
40 * This class is a default implementation for the INonViralNameCacheStrategy<T extends NonViralName>
42 * The method implements a cache strategy for botanical names so no method has to be overwritten by
43 * a subclass for botanic names.
44 * Where differing from this default botanic name strategy other subclasses should overwrite the
45 * existing methods, e.g. a CacheStrategy for zoological names should overwrite getAuthorAndExAuthor
53 public class NonViralNameDefaultCacheStrategy
<T
extends NonViralName
> extends NameCacheStrategyBase
<T
> implements INonViralNameCacheStrategy
<T
> {
54 private static final Logger logger
= Logger
.getLogger(NonViralNameDefaultCacheStrategy
.class);
56 final static UUID uuid
= UUID
.fromString("1cdda0d1-d5bc-480f-bf08-40a510a2f223");
58 protected String NameAuthorSeperator
= " ";
59 protected String BasionymStart
= "(";
60 protected String BasionymEnd
= ")";
61 protected String ExAuthorSeperator
= " ex ";
62 protected CharSequence BasionymAuthorCombinationAuthorSeperator
= " ";
65 public UUID
getUuid(){
72 * @return NonViralNameDefaultCacheStrategy A new instance of NonViralNameDefaultCacheStrategy
74 public static NonViralNameDefaultCacheStrategy
NewInstance(){
75 return new NonViralNameDefaultCacheStrategy();
80 * @return NonViralNameDefaultCacheStrategy A new instance of NonViralNameDefaultCacheStrategy
82 public static <T
extends NonViralName
<?
>> NonViralNameDefaultCacheStrategy
<T
> NewInstance(Class
<T
> clazz
){
83 return new NonViralNameDefaultCacheStrategy
<T
>();
89 protected NonViralNameDefaultCacheStrategy(){
93 /* **************** GETTER / SETTER **************************************/
96 * String that separates the NameCache part from the AuthorCache part
99 public String
getNameAuthorSeperator() {
100 return NameAuthorSeperator
;
104 public void setNameAuthorSeperator(String nameAuthorSeperator
) {
105 NameAuthorSeperator
= nameAuthorSeperator
;
110 * String the basionym author part starts with e.g. '('.
111 * This should correspond with the {@link NonViralNameDefaultCacheStrategy#getBasionymEnd() basionymEnd} attribute
114 public String
getBasionymStart() {
115 return BasionymStart
;
119 public void setBasionymStart(String basionymStart
) {
120 BasionymStart
= basionymStart
;
125 * String the basionym author part ends with e.g. ')'.
126 * This should correspond with the {@link NonViralNameDefaultCacheStrategy#getBasionymStart() basionymStart} attribute
129 public String
getBasionymEnd() {
134 public void setBasionymEnd(String basionymEnd
) {
135 BasionymEnd
= basionymEnd
;
140 * String to seperate ex author from author.
143 public String
getExAuthorSeperator() {
144 return ExAuthorSeperator
;
148 public void setExAuthorSeperator(String exAuthorSeperator
) {
149 ExAuthorSeperator
= exAuthorSeperator
;
154 * String that seperates the basionym/original_combination author part from the combination author part
157 public CharSequence
getBasionymAuthorCombinationAuthorSeperator() {
158 return BasionymAuthorCombinationAuthorSeperator
;
162 public void setBasionymAuthorCombinationAuthorSeperator( CharSequence basionymAuthorCombinationAuthorSeperator
) {
163 BasionymAuthorCombinationAuthorSeperator
= basionymAuthorCombinationAuthorSeperator
;
167 //** *****************************************************************************************/
170 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTitleCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)
173 public String
getTitleCache(T nonViralName
) {
174 List
<TaggedText
> tags
= getTaggedTitle(nonViralName
);
178 String result
= createString(tags
);
184 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getFullTitleCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)
187 public String
getFullTitleCache(T nonViralName
) {
188 List
<TaggedText
> tags
= getTaggedFullTitle(nonViralName
);
192 String result
= createString(tags
);
199 * Generates and returns the "name cache" (only scientific name without author teams and year).
200 * @see eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy#getNameCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)
202 public String
getNameCache(T nonViralName
) {
203 List
<TaggedText
> tags
= getTaggedName(nonViralName
);
207 String result
= createString(tags
);
214 * Creates a string from tagged text.
218 protected String
createString(List
<TaggedText
> tags
) {
219 StringBuffer result
= new StringBuffer();
222 boolean wasSeparator
= true; //true for start tag
223 for (TaggedText tag
: tags
){
224 isSeparator
= tag
.getType().equals(TagEnum
.separator
);
225 if (! wasSeparator
&& ! isSeparator
){
228 result
.append(tag
.getText());
229 wasSeparator
= isSeparator
;
231 return result
.toString();
234 // ******************* Authorship ******************************/
238 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy#getAuthorCache(eu.etaxonomy.cdm.model.name.NonViralName)
240 public String
getAuthorshipCache(T nonViralName
) {
241 if (nonViralName
== null){
245 if (nonViralName
.isProtectedAuthorshipCache() == true) {
246 return nonViralName
.getAuthorshipCache();
248 return getNonCacheAuthorshipCache(nonViralName
);
253 * Returns the authorshipcache string for the atomized authorship fields. Does not use the authorshipfield.
254 * @throws NullPointerException if nonViralName is null.
255 * @param nonViralName
258 protected String
getNonCacheAuthorshipCache(T nonViralName
){
260 INomenclaturalAuthor combinationAuthor
= nonViralName
.getCombinationAuthorTeam();
261 INomenclaturalAuthor exCombinationAuthor
= nonViralName
.getExCombinationAuthorTeam();
262 INomenclaturalAuthor basionymAuthor
= nonViralName
.getBasionymAuthorTeam();
263 INomenclaturalAuthor exBasionymAuthor
= nonViralName
.getExBasionymAuthorTeam();
264 String basionymPart
= "";
265 String authorPart
= "";
267 if (basionymAuthor
!= null || exBasionymAuthor
!= null){
268 basionymPart
= BasionymStart
+ getAuthorAndExAuthor(basionymAuthor
, exBasionymAuthor
) + BasionymEnd
;
270 if (combinationAuthor
!= null || exCombinationAuthor
!= null){
271 authorPart
= getAuthorAndExAuthor(combinationAuthor
, exCombinationAuthor
);
273 result
= CdmUtils
.concat(BasionymAuthorCombinationAuthorSeperator
, basionymPart
, authorPart
);
278 * Returns the AuthorCache part for a combination of an author and an ex author. This applies on combination authors
279 * as well as on basionym/orginal combination authors.
280 * @param author the author
281 * @param exAuthor the ex-author
284 protected String
getAuthorAndExAuthor(INomenclaturalAuthor author
, INomenclaturalAuthor exAuthor
){
286 String authorString
= "";
287 String exAuthorString
= "";
289 authorString
= CdmUtils
.Nz(author
.getNomenclaturalTitle());
291 if (exAuthor
!= null){
292 exAuthorString
= CdmUtils
.Nz(exAuthor
.getNomenclaturalTitle());
294 if (exAuthorString
.length() > 0 ){
295 exAuthorString
= exAuthorString
+ ExAuthorSeperator
;
297 result
= exAuthorString
+ authorString
;
303 * Checks if the given name should include the author in it's cached version.<BR>
304 * This is usually the case but not for <i>species aggregates</i>.
305 * @param nonViralName
308 protected boolean nameIncludesAuthorship(NonViralName
<?
> nonViralName
){
309 Rank rank
= nonViralName
.getRank();
310 if (rank
!= null && rank
.isSpeciesAggregate()){
317 // ************* TAGGED NAME ***************************************/
320 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTaggedFullTitle(eu.etaxonomy.cdm.model.name.TaxonNameBase)
323 public List
<TaggedText
> getTaggedFullTitle(T nonViralName
) {
324 List
<TaggedText
> tags
= new ArrayList
<TaggedText
>();
327 if (nonViralName
== null){
331 //protected full title cache
332 if (nonViralName
.isProtectedFullTitleCache()){
333 tags
.add(new TaggedText(TagEnum
.fullName
, nonViralName
.getFullTitleCache()));
338 // String titleCache = nonViralName.getTitleCache();
339 List
<TaggedText
> titleTags
= getTaggedTitle(nonViralName
);
340 tags
.addAll(titleTags
);
344 String microReference
= nonViralName
.getNomenclaturalMicroReference();
345 INomenclaturalReference ref
= nonViralName
.getNomenclaturalReference();
346 String referenceBaseCache
= null;
348 INomenclaturalReference nomenclaturalReference
= HibernateProxyHelper
.deproxy(ref
, INomenclaturalReference
.class);
349 nomenclaturalReference
.setCacheStrategy(nomenclaturalReference
.getType().getCacheStrategy());
350 referenceBaseCache
= nomenclaturalReference
.getNomenclaturalCitation(microReference
);
353 if (StringUtils
.isNotBlank(referenceBaseCache
)){
354 if (! referenceBaseCache
.trim().startsWith("in ")){
355 String refConcat
= ", ";
356 tags
.add(new TaggedText(TagEnum
.separator
, refConcat
));
358 tags
.add(new TaggedText(TagEnum
.reference
, referenceBaseCache
));
361 //nomenclatural status
362 Set
<NomenclaturalStatus
> ncStati
= nonViralName
.getStatus();
363 Iterator
<NomenclaturalStatus
> iterator
= ncStati
.iterator();
364 List
<TaggedText
> nomStatusTags
= new ArrayList
<TaggedText
>();
365 while (iterator
.hasNext()) {
366 NomenclaturalStatus ncStatus
= (NomenclaturalStatus
)iterator
.next();
367 // since the NewInstance method of nomencatural status allows null as parameter
368 // we have to check for null values here
369 String suffix
= "not defined";
370 if(ncStatus
.getType() != null){
371 NomenclaturalStatusType statusType
= ncStatus
.getType();
372 Language lang
= Language
.LATIN();
373 Representation repr
= statusType
.getRepresentation(lang
);
375 suffix
= repr
.getAbbreviatedLabel();
377 String message
= "No latin representation available for nom. status. " + statusType
.getTitleCache();
378 logger
.warn(message
);
379 throw new IllegalStateException(message
);
381 }else if(ncStatus
.getRuleConsidered() != null && ! ncStatus
.getRuleConsidered().equals("")){
382 suffix
= ncStatus
.getRuleConsidered();
384 String statusSeparator
= ", ";
385 nomStatusTags
.add(new TaggedText(TagEnum
.separator
, statusSeparator
));
386 nomStatusTags
.add(new TaggedText(TagEnum
.nomStatus
, suffix
));
388 tags
.addAll(nomStatusTags
);
394 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTaggedTitle(eu.etaxonomy.cdm.model.name.TaxonNameBase)
396 public List
<TaggedText
> getTaggedTitle(T nonViralName
) {
397 if (nonViralName
== null){
401 List
<TaggedText
> tags
= new ArrayList
<TaggedText
>();
403 //TODO how to handle protected fullTitleCache here?
405 if (nonViralName
.isProtectedTitleCache()){
406 //protected title cache
407 tags
.add(new TaggedText(TagEnum
.name
, nonViralName
.getTitleCache()));
409 }else if (nonViralName
.isHybridFormula()){
411 String hybridSeparator
= NonViralNameParserImplRegExBase
.hybridSign
;
412 boolean isFirst
= true;
413 List
<HybridRelationship
> rels
= nonViralName
.getOrderedChildRelationships();
414 for (HybridRelationship rel
: rels
){
416 tags
.add(new TaggedText(TagEnum
.hybridSign
, hybridSeparator
));
419 tags
.addAll(getTaggedTitle((T
)rel
.getParentName()));
422 }else if (nonViralName
.isAutonym()){
424 tags
.addAll(handleTaggedAutonym(nonViralName
));
426 // String nameCache = nonViralName.getNameCache(); //OLD: CdmUtils.Nz(getNameCache(nonViralName));
427 List
<TaggedText
> nameTags
= getTaggedName(nonViralName
);
428 tags
.addAll(nameTags
);
429 if (nameIncludesAuthorship(nonViralName
)){
430 String authorCache
= getAuthorshipCache(nonViralName
);
431 if (StringUtils
.isNotBlank(authorCache
)){
432 tags
.add(new TaggedText(TagEnum
.authors
, authorCache
));
442 * Returns the tag list of the name part (without author and reference).
443 * @param nonViralName
446 public List
<TaggedText
> getTaggedName(T nonViralName
) {
447 if (nonViralName
== null){
450 List
<TaggedText
> tags
= new ArrayList
<TaggedText
>();
451 Rank rank
= nonViralName
.getRank();
453 if (nonViralName
.isProtectedNameCache()){
454 tags
.add(new TaggedText(TagEnum
.name
, nonViralName
.getNameCache()));
455 }else if (rank
== null){
456 tags
= getRanklessTaggedNameCache(nonViralName
);
457 // }else if (nonViralName.isInfragenericUnranked()){
458 // result = getUnrankedInfragenericNameCache(nonViralName);
459 }else if (rank
.isInfraSpecific()){
460 tags
= getInfraSpeciesTaggedNameCache(nonViralName
);
461 }else if (rank
.isSpecies()){
462 tags
= getSpeciesTaggedNameCache(nonViralName
);
463 }else if (rank
.isInfraGeneric()){
464 tags
= getInfraGenusTaggedNameCache(nonViralName
);
465 }else if (rank
.isGenus()){
466 tags
= getGenusOrUninomialTaggedNameCache(nonViralName
);
467 }else if (rank
.isSupraGeneric()){
468 tags
= getGenusOrUninomialTaggedNameCache(nonViralName
);
470 logger
.warn("Name Strategy for Name (UUID: " + nonViralName
.getUuid() + ") not yet implemented");
472 //TODO handle appended phrase here instead of different places, check first if this is true for all
482 //***************************** PRIVATES ***************************************/
486 * Returns the tag list for an autonym taxon.
488 * @see NonViralName#isAutonym()
489 * @see BotanicalName#isAutonym()
490 * @param nonViralName
493 private List
<TaggedText
> handleTaggedAutonym(T nonViralName
) {
496 List
<TaggedText
> tags
= getSpeciesTaggedNameCache(nonViralName
);
499 //TODO should this include basionym authors and ex authors
500 INomenclaturalAuthor author
= nonViralName
.getCombinationAuthorTeam();
501 String authorPart
= "";
503 authorPart
= CdmUtils
.Nz(author
.getNomenclaturalTitle());
505 INomenclaturalAuthor basAuthor
= nonViralName
.getBasionymAuthorTeam();
506 String basAuthorPart
= "";
507 if (basAuthor
!= null){
508 basAuthorPart
= CdmUtils
.Nz(basAuthor
.getNomenclaturalTitle());
510 if (! "".equals(basAuthorPart
)){
511 authorPart
= "("+ basAuthorPart
+") " + authorPart
;
513 if (StringUtils
.isNotBlank(authorPart
)){
514 tags
.add(new TaggedText(TagEnum
.authors
, authorPart
));
518 //infra species marker
519 if (nonViralName
.getRank() == null || !nonViralName
.getRank().isInfraSpecific()){
520 //TODO handle exception
521 logger
.warn("Rank for autonym does not exist or is not lower than species !!");
523 String infraSpeciesMarker
= nonViralName
.getRank().getAbbreviation();
524 if (StringUtils
.isNotBlank(infraSpeciesMarker
)){
525 tags
.add(new TaggedText(TagEnum
.rank
, infraSpeciesMarker
));
530 String infraSpeciesPart
= CdmUtils
.Nz(nonViralName
.getInfraSpecificEpithet()).trim().replace("null", "");
531 if (StringUtils
.isNotBlank(infraSpeciesPart
)){
532 tags
.add(new TaggedText(TagEnum
.name
, infraSpeciesPart
));
541 * Returns the tag list for rankless taxa.
542 * @param nonViralName
545 protected List
<TaggedText
> getRanklessTaggedNameCache(NonViralName
<?
> nonViralName
){
546 List
<TaggedText
> tags
= getUninomialTaggedPart(nonViralName
);
547 String speciesEpi
= CdmUtils
.Nz(nonViralName
.getSpecificEpithet()).trim().replace("null", "");
548 if (StringUtils
.isNotBlank(speciesEpi
)){
549 tags
.add(new TaggedText(TagEnum
.name
, speciesEpi
));
552 String infraSpeciesEpi
= CdmUtils
.Nz(nonViralName
.getInfraSpecificEpithet()).trim().replace("null", "");
553 if (StringUtils
.isNotBlank(infraSpeciesEpi
)){
554 tags
.add(new TaggedText(TagEnum
.name
, infraSpeciesEpi
));
557 //result += " (rankless)";
558 addAppendedTaggedPhrase(tags
, nonViralName
);
563 * Returns the tag list for the first epithet (including a hybrid sign if required).
564 * @param nonViralName
567 private List
<TaggedText
> getUninomialTaggedPart(NonViralName
<?
> nonViralName
) {
568 List
<TaggedText
> tags
= new ArrayList
<TaggedText
>();
570 if (nonViralName
.isMonomHybrid()){
571 addHybridPrefix(tags
);
574 String uninomial
= CdmUtils
.Nz(nonViralName
.getGenusOrUninomial()).trim().replace("null", "");
575 if (StringUtils
.isNotBlank(uninomial
)){
576 tags
.add(new TaggedText(TagEnum
.name
, uninomial
));
583 * Returns the tag list for an genus or higher taxon.
585 * @param nonViralName
588 protected List
<TaggedText
> getGenusOrUninomialTaggedNameCache(NonViralName
<?
> nonViralName
){
589 List
<TaggedText
> tags
= getUninomialTaggedPart(nonViralName
);
590 addAppendedTaggedPhrase(tags
, nonViralName
);
595 * Returns the tag list for an infrageneric taxon (including species aggregates).
597 * @see #getSpeciesAggregateTaggedCache(NonViralName)
598 * @param nonViralName
601 protected List
<TaggedText
> getInfraGenusTaggedNameCache(NonViralName
<?
> nonViralName
){
602 Rank rank
= nonViralName
.getRank();
603 if (rank
.isSpeciesAggregate()){
604 return getSpeciesAggregateTaggedCache(nonViralName
);
608 List
<TaggedText
> tags
= getUninomialTaggedPart(nonViralName
);
611 String infraGenericMarker
= "'unhandled infrageneric rank'";
614 infraGenericMarker
= rank
.getInfraGenericMarker();
615 } catch (UnknownCdmTypeException e
) {
616 infraGenericMarker
= "'unhandled infrageneric rank'";
619 tags
.add(new TaggedText(TagEnum
.rank
, infraGenericMarker
));
622 String infraGenEpi
= CdmUtils
.Nz(nonViralName
.getInfraGenericEpithet()).trim().replace("null", "");
623 if (StringUtils
.isNotBlank(infraGenEpi
)){
624 tags
.add(new TaggedText(TagEnum
.name
, infraGenEpi
));
627 addAppendedTaggedPhrase(tags
, nonViralName
);
632 * Returns the tag list for a species aggregate (or similar) taxon.<BR>
633 * Possible ranks for a <i>species aggregate</i> are "aggr.", "species group", ...
634 * @param nonViralName
637 protected List
<TaggedText
> getSpeciesAggregateTaggedCache(NonViralName
<?
> nonViralName
){
638 List
<TaggedText
> tags
= getGenusAndSpeciesTaggedPart(nonViralName
);
640 addSpeciesAggregateTaggedEpithet(tags
, nonViralName
);
641 addAppendedTaggedPhrase(tags
, nonViralName
);
646 * Adds the aggregate tag to the tag list.
648 * @param nonViralName
650 private void addSpeciesAggregateTaggedEpithet(List
<TaggedText
> tags
, NonViralName
<?
> nonViralName
) {
653 marker
= nonViralName
.getRank().getInfraGenericMarker();
654 } catch (UnknownCdmTypeException e
) {
655 marker
= "'unknown aggregat type'";
657 if (StringUtils
.isNotBlank(marker
)){
658 tags
.add(new TaggedText(TagEnum
.rank
, marker
));
664 * Returns the tag list for a species taxon.
665 * @param nonViralName
668 protected List
<TaggedText
> getSpeciesTaggedNameCache(NonViralName
<?
> nonViralName
){
669 List
<TaggedText
> tags
= getGenusAndSpeciesTaggedPart(nonViralName
);
670 addAppendedTaggedPhrase(tags
, nonViralName
);
675 * Creates the tag list for an infraspecific taxon. In include is true the result will contain
676 * @param nonViralName
679 protected List
<TaggedText
> getInfraSpeciesTaggedNameCache(NonViralName
<?
> nonViralName
){
680 return getInfraSpeciesTaggedNameCache(nonViralName
, true);
684 * Creates the tag list for an infraspecific taxon. In include is true the result will contain
685 * the infraspecific marker (e.g. "var.")
686 * @param nonViralName
687 * @param includeMarker
690 protected List
<TaggedText
> getInfraSpeciesTaggedNameCache(NonViralName
<?
> nonViralName
, boolean includeMarker
){
691 List
<TaggedText
> tags
= getGenusAndSpeciesTaggedPart(nonViralName
);
693 String marker
= (nonViralName
.getRank().getAbbreviation()).trim().replace("null", "");
694 if (StringUtils
.isNotBlank(marker
)){
695 tags
.add(new TaggedText(TagEnum
.rank
, marker
));
698 String infrSpecEpi
= CdmUtils
.Nz(nonViralName
.getInfraSpecificEpithet());
699 if (nonViralName
.isTrinomHybrid()){
700 addHybridPrefix(tags
);
703 infrSpecEpi
= infrSpecEpi
.trim().replace("null", "");
704 if (StringUtils
.isNotBlank(infrSpecEpi
)){
705 tags
.add(new TaggedText(TagEnum
.name
, infrSpecEpi
));
708 addAppendedTaggedPhrase(tags
, nonViralName
);
714 * Adds a tag for the hybrid sign and an empty separator to avoid trailing whitespaces.
717 private void addHybridPrefix(List
<TaggedText
> tags
) {
718 tags
.add(new TaggedText(TagEnum
.hybridSign
, NonViralNameParserImplRegExBase
.hybridSign
));
719 tags
.add(new TaggedText(TagEnum
.separator
, "")); //no whitespace separator
723 * Creates the tag list for the genus and species part.
724 * @param nonViralName
727 private List
<TaggedText
> getGenusAndSpeciesTaggedPart(NonViralName
<?
> nonViralName
) {
729 List
<TaggedText
> tags
= getUninomialTaggedPart(nonViralName
);
732 boolean hasInfraGenericEpi
= StringUtils
.isNotBlank(nonViralName
.getInfraGenericEpithet());
733 if (hasInfraGenericEpi
){
734 String infrGenEpi
= nonViralName
.getInfraGenericEpithet().trim();
735 if (nonViralName
.isBinomHybrid()){
736 // addHybridPrefix(tags); FIXME hybridSign should be tag, but then we need to handle "(" ")" differently.
737 infrGenEpi
= NonViralNameParserImplRegExBase
.hybridSign
+ infrGenEpi
;
739 infrGenEpi
= "(" + infrGenEpi
+ ")";
740 tags
.add(new TaggedText(TagEnum
.name
, infrGenEpi
));
744 String specEpi
= CdmUtils
.Nz(nonViralName
.getSpecificEpithet()).trim().replace("null", "");
745 if (! hasInfraGenericEpi
&& nonViralName
.isBinomHybrid() ||
746 hasInfraGenericEpi
&& nonViralName
.isTrinomHybrid()){
747 addHybridPrefix(tags
);
749 if (StringUtils
.isNotBlank(specEpi
)){
750 tags
.add(new TaggedText(TagEnum
.name
, specEpi
));
756 * Adds the tag for the appended phrase if an appended phrase exists
758 * @param nonViralName
760 protected void addAppendedTaggedPhrase(List
<TaggedText
> tags
, NonViralName
<?
> nonViralName
){
761 String appendedPhrase
= nonViralName
==null ?
null : nonViralName
.getAppendedPhrase();
762 if (StringUtils
.isNotEmpty(appendedPhrase
)){
763 tags
.add(new TaggedText(TagEnum
.name
, appendedPhrase
));
767 public String
getLastEpithet(T taxonNameBase
) {
768 Rank rank
= taxonNameBase
.getRank();
769 if(rank
.isGenus() || rank
.isSupraGeneric()) {
770 return taxonNameBase
.getGenusOrUninomial();
771 } else if(rank
.isInfraGeneric()) {
772 return taxonNameBase
.getInfraGenericEpithet();
773 } else if(rank
.isSpecies()) {
774 return taxonNameBase
.getSpecificEpithet();
776 return taxonNameBase
.getInfraSpecificEpithet();
780 // *************************** DEPRECATED ***************************************************/
783 //Old: may be replaced once getTagged(Full)Title is fully tested
785 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTaggedName(eu.etaxonomy.cdm.model.common.CdmBase)
789 public List
<Object
> getTaggedNameDeprecated(T nonViralName
) {
790 List
<Object
> tags
= new ArrayList
<Object
>();
792 if (nonViralName
.isProtectedNameCache() ||
793 nonViralName
.isProtectedAuthorshipCache() ||
794 nonViralName
.isProtectedFullTitleCache() ||
795 nonViralName
.isProtectedTitleCache()){
796 tags
.add(nonViralName
.getTitleCache());
800 // Why does it make sense to add the nameCache in case of non existing genusOrUninomial?
801 // if (nonViralName.getGenusOrUninomial() == null){
802 // tags.add(nonViralName.getNameCache());
805 if (nonViralName
.getGenusOrUninomial() != null) {
806 tags
.add(nonViralName
.getGenusOrUninomial());
808 if (nonViralName
.isSpecies() || nonViralName
.isInfraSpecific()){
809 tags
.add(nonViralName
.getSpecificEpithet());
813 if (nonViralName
.isInfraSpecific() && ! nonViralName
.getSpecificEpithet().equals(nonViralName
.getInfraSpecificEpithet())){
814 tags
.add(nonViralName
.getRank());
815 tags
.add(nonViralName
.getInfraSpecificEpithet());
818 if (nonViralName
.isInfraGeneric()){
819 //TODO choose right strategy or generic approach?
820 // --- strategy 1 ---
822 if (nonViralName
.getRank().isSpeciesAggregate()){
823 tags
.add(nonViralName
.getSpecificEpithet());
824 tags
.add(getSpeciesAggregateEpithet(nonViralName
));
826 tags
.add(nonViralName
.getRank());
827 tags
.add(nonViralName
.getInfraGenericEpithet());
829 // --- strategy 2 ---
830 // tags.add('('+nvn.getInfraGenericEpithet()+')');
832 Team authorTeam
= Team
.NewInstance();
833 authorTeam
.setProtectedTitleCache(true);
834 authorTeam
.setTitleCache(nonViralName
.getAuthorshipCache(), true);
835 tags
.add(authorTeam
);
837 // Name is an autonym. Rank and infraspecific epitheton follow the author
838 if (nonViralName
.isInfraSpecific() && nonViralName
.getSpecificEpithet().equals(nonViralName
.getInfraSpecificEpithet())){
839 tags
.add(nonViralName
.getRank());
840 tags
.add(nonViralName
.getInfraSpecificEpithet());
843 if(! "".equals(nonViralName
.getAppendedPhrase())&& (nonViralName
.getAppendedPhrase() != null)){
844 tags
.add(nonViralName
.getAppendedPhrase());
852 * @deprecated use only for {@link #getTaggedNameDeprecated(NonViralName)}. Delete when the later
856 private String
getSpeciesAggregateEpithet(NonViralName
<?
> nonViralName
) {
859 marker
= nonViralName
.getRank().getInfraGenericMarker();
860 } catch (UnknownCdmTypeException e
) {
861 marker
= "'unknown aggregat type'";