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
.HybridRelationship
;
27 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
28 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
29 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
30 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
31 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
32 import eu
.etaxonomy
.cdm
.strategy
.TagEnum
;
33 import eu
.etaxonomy
.cdm
.strategy
.TaggedText
;
34 import eu
.etaxonomy
.cdm
.strategy
.exceptions
.UnknownCdmTypeException
;
35 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImplRegExBase
;
39 * This class is a default implementation for the INonViralNameCacheStrategy<T extends NonViralName> interface.
40 * The method actually implements a cache strategy for botanical names so no method has to be overwritten by
41 * a subclass for botanic names.
42 * Where differing from this Default BotanicNameCacheStrategy other subclasses should overwrite the existing methods
43 * e.g. a CacheStrategy for zoological names should overwrite getAuthorAndExAuthor
51 public class NonViralNameDefaultCacheStrategy
<T
extends NonViralName
> extends NameCacheStrategyBase
<T
> implements INonViralNameCacheStrategy
<T
> {
52 private static final Logger logger
= Logger
.getLogger(NonViralNameDefaultCacheStrategy
.class);
54 final static UUID uuid
= UUID
.fromString("1cdda0d1-d5bc-480f-bf08-40a510a2f223");
56 protected String NameAuthorSeperator
= " ";
57 protected String BasionymStart
= "(";
58 protected String BasionymEnd
= ")";
59 protected String ExAuthorSeperator
= " ex ";
60 protected CharSequence BasionymAuthorCombinationAuthorSeperator
= " ";
63 public UUID
getUuid(){
70 * @return NonViralNameDefaultCacheStrategy A new instance of NonViralNameDefaultCacheStrategy
72 public static NonViralNameDefaultCacheStrategy
NewInstance(){
73 return new NonViralNameDefaultCacheStrategy();
78 * @return NonViralNameDefaultCacheStrategy A new instance of NonViralNameDefaultCacheStrategy
80 public static <T
extends NonViralName
<?
>> NonViralNameDefaultCacheStrategy
<T
> NewInstance(Class
<T
> clazz
){
81 return new NonViralNameDefaultCacheStrategy
<T
>();
87 protected NonViralNameDefaultCacheStrategy(){
91 /* **************** GETTER / SETTER **************************************/
94 * String that separates the NameCache part from the AuthorCache part
97 public String
getNameAuthorSeperator() {
98 return NameAuthorSeperator
;
102 public void setNameAuthorSeperator(String nameAuthorSeperator
) {
103 NameAuthorSeperator
= nameAuthorSeperator
;
108 * String the basionym author part starts with e.g. '('.
109 * This should correspond with the {@link NonViralNameDefaultCacheStrategy#getBasionymEnd() basionymEnd} attribute
112 public String
getBasionymStart() {
113 return BasionymStart
;
117 public void setBasionymStart(String basionymStart
) {
118 BasionymStart
= basionymStart
;
123 * String the basionym author part ends with e.g. ')'.
124 * This should correspond with the {@link NonViralNameDefaultCacheStrategy#getBasionymStart() basionymStart} attribute
127 public String
getBasionymEnd() {
132 public void setBasionymEnd(String basionymEnd
) {
133 BasionymEnd
= basionymEnd
;
138 * String to seperate ex author from author.
141 public String
getExAuthorSeperator() {
142 return ExAuthorSeperator
;
146 public void setExAuthorSeperator(String exAuthorSeperator
) {
147 ExAuthorSeperator
= exAuthorSeperator
;
152 * String that seperates the basionym/original_combination author part from the combination author part
155 public CharSequence
getBasionymAuthorCombinationAuthorSeperator() {
156 return BasionymAuthorCombinationAuthorSeperator
;
160 public void setBasionymAuthorCombinationAuthorSeperator(
161 CharSequence basionymAuthorCombinationAuthorSeperator
) {
162 BasionymAuthorCombinationAuthorSeperator
= basionymAuthorCombinationAuthorSeperator
;
166 //** *****************************************************************************************/
169 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTitleCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)
172 public String
getTitleCache(T nonViralName
) {
173 List
<TaggedText
> tags
= getTaggedTitle(nonViralName
);
177 String result
= createString(tags
);
184 public String
getTitleCache_OLD(T nonViralName
) {
185 if (nonViralName
== null){
189 if (nonViralName
.isProtectedTitleCache()){
190 return nonViralName
.getTitleCache();
193 if (nonViralName
.isHybridFormula()){
196 String hybridSeparator
= " " + NonViralNameParserImplRegExBase
.hybridSign
+ " ";
197 List
<HybridRelationship
> rels
= nonViralName
.getOrderedChildRelationships();
198 for (HybridRelationship rel
: rels
){
199 result
= CdmUtils
.concat(hybridSeparator
, result
, rel
.getParentName().getTitleCache()).trim();
202 }else if (nonViralName
.isAutonym()){
204 result
= handleAutonym(nonViralName
);
206 String nameCache
= nonViralName
.getNameCache(); //OLD: CdmUtils.Nz(getNameCache(nonViralName));
207 if (nameIncludesAuthorship(nonViralName
)){
208 String authorCache
= CdmUtils
.Nz(getAuthorshipCache(nonViralName
));
209 result
= CdmUtils
.concat(NameAuthorSeperator
, nameCache
, authorCache
);
219 * Creates a string from tagged text.
223 private String
createString(List
<TaggedText
> tags
) {
224 StringBuffer result
= new StringBuffer();
227 boolean wasSeparator
= true; //true for start tag
228 for (TaggedText tag
: tags
){
229 isSeparator
= tag
.getType().equals(TagEnum
.separator
);
230 if (! wasSeparator
&& ! isSeparator
){
233 result
.append(tag
.getText());
234 wasSeparator
= isSeparator
;
236 return result
.toString();
241 * @param nonViralName
245 private List
<TaggedText
> handleTaggedAutonym(T nonViralName
) {
248 List
<TaggedText
> tags
= getSpeciesTaggedNameCache(nonViralName
);
251 //TODO should this include basionym authors and ex authors
252 INomenclaturalAuthor author
= nonViralName
.getCombinationAuthorTeam();
253 String authorPart
= "";
255 authorPart
= CdmUtils
.Nz(author
.getNomenclaturalTitle());
257 INomenclaturalAuthor basAuthor
= nonViralName
.getBasionymAuthorTeam();
258 String basAuthorPart
= "";
259 if (basAuthor
!= null){
260 basAuthorPart
= CdmUtils
.Nz(basAuthor
.getNomenclaturalTitle());
262 if (! "".equals(basAuthorPart
)){
263 authorPart
= "("+ basAuthorPart
+") " + authorPart
;
265 if (StringUtils
.isNotBlank(authorPart
)){
266 tags
.add(new TaggedText(TagEnum
.authors
, authorPart
));
270 //infra species marker
271 if (nonViralName
.getRank() == null || !nonViralName
.getRank().isInfraSpecific()){
272 //TODO handle exception
273 logger
.warn("Rank for autonym does not exist or is not lower than species !!");
275 String infraSpeciesMarker
= nonViralName
.getRank().getAbbreviation();
276 if (StringUtils
.isNotBlank(infraSpeciesMarker
)){
277 tags
.add(new TaggedText(TagEnum
.rank
, infraSpeciesMarker
));
282 String infraSpeciesPart
= CdmUtils
.Nz(nonViralName
.getInfraSpecificEpithet()).trim().replace("null", "");
283 if (StringUtils
.isNotBlank(infraSpeciesPart
)){
284 tags
.add(new TaggedText(TagEnum
.name
, infraSpeciesPart
));
291 * @param nonViralName
295 private String
handleAutonym(T nonViralName
) {
297 String speciesPart
= getSpeciesNameCache(nonViralName
);
298 //TODO should this include basionym authors and ex authors
299 INomenclaturalAuthor author
= nonViralName
.getCombinationAuthorTeam();
300 String authorPart
= "";
302 authorPart
= CdmUtils
.Nz(author
.getNomenclaturalTitle());
304 INomenclaturalAuthor basAuthor
= nonViralName
.getBasionymAuthorTeam();
305 String basAuthorPart
= "";
306 if (basAuthor
!= null){
307 basAuthorPart
= CdmUtils
.Nz(basAuthor
.getNomenclaturalTitle());
309 if (! "".equals(basAuthorPart
)){
310 authorPart
= "("+ basAuthorPart
+") " + authorPart
;
312 String infraSpeciesPart
= (CdmUtils
.Nz(nonViralName
.getInfraSpecificEpithet()));
314 String infraSpeciesSeparator
= "";
315 if (nonViralName
.getRank() == null || !nonViralName
.getRank().isInfraSpecific()){
316 //TODO handle exception
317 logger
.warn("Rank for autonym does not exist or is not lower than species !!");
319 infraSpeciesSeparator
= nonViralName
.getRank().getAbbreviation();
322 result
= CdmUtils
.concat(" ", new String
[]{speciesPart
, authorPart
, infraSpeciesSeparator
, infraSpeciesPart
});
323 result
= result
.trim().replace("null", "");
327 protected boolean nameIncludesAuthorship(NonViralName
<?
> nonViralName
){
328 Rank rank
= nonViralName
.getRank();
329 if (rank
!= null && rank
.isSpeciesAggregate()){
337 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getFullTitleCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)
340 public String
getFullTitleCache(T nonViralName
) {
341 List
<TaggedText
> tags
= getTaggedFullTitle(nonViralName
);
345 String result
= createString(tags
);
351 public String
getFullTitleCache_OLD(T nonViralName
) {
353 if (nonViralName
== null){
357 if (nonViralName
.isProtectedFullTitleCache() == true) {
358 return nonViralName
.getFullTitleCache();
363 String titleCache
= nonViralName
.getTitleCache(); // OLD: getTitleCache(nonViralName);
365 String microReference
= nonViralName
.getNomenclaturalMicroReference();
366 INomenclaturalReference ref
= nonViralName
.getNomenclaturalReference();
367 String referenceBaseCache
= null;
369 INomenclaturalReference nomenclaturalReference
= HibernateProxyHelper
.deproxy(ref
, INomenclaturalReference
.class);
370 nomenclaturalReference
.setCacheStrategy(nomenclaturalReference
.getType().getCacheStrategy());
371 referenceBaseCache
= nomenclaturalReference
.getNomenclaturalCitation(microReference
);
374 //make nomenclatural status
375 String ncStatusCache
= "";
376 Set
<NomenclaturalStatus
> ncStati
= nonViralName
.getStatus();
377 Iterator
<NomenclaturalStatus
> iterator
= ncStati
.iterator();
378 while (iterator
.hasNext()) {
379 NomenclaturalStatus ncStatus
= (NomenclaturalStatus
)iterator
.next();
380 // since the NewInstance method of nomencatural status allows null as parameter
381 // we have to check for null values here
382 String suffix
= "not defined";
383 if(ncStatus
.getType() != null){
384 NomenclaturalStatusType statusType
= ncStatus
.getType();
385 Language lang
= Language
.LATIN();
386 Representation repr
= statusType
.getRepresentation(lang
);
388 suffix
= repr
.getAbbreviatedLabel();
390 String message
= "No latin representation available for nom. status. " + statusType
.getTitleCache();
391 logger
.warn(message
);
392 throw new IllegalStateException(message
);
394 }else if(ncStatus
.getRuleConsidered() != null && ! ncStatus
.getRuleConsidered().equals("")){
395 suffix
= ncStatus
.getRuleConsidered();
397 ncStatusCache
= ", " + suffix
;
399 String refConcat
= " ";
400 if (referenceBaseCache
!= null && ! referenceBaseCache
.trim().startsWith("in ")){
403 result
= CdmUtils
.concat(refConcat
, titleCache
, referenceBaseCache
);
404 result
= CdmUtils
.concat("", result
, ncStatusCache
);
411 * Generates and returns the "name cache" (only scientific name without author teams and year).
412 * @see eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy#getNameCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)
414 public String
getNameCache(T nonViralName
) {
415 List
<TaggedText
> tags
= getNameTags(nonViralName
);
419 String result
= createString(tags
);
424 public String
getNameCache_OLD(T nonViralName
) {
425 if (nonViralName
== null){
429 Rank rank
= nonViralName
.getRank();
431 if (nonViralName
.isProtectedNameCache()){
432 result
= nonViralName
.getNameCache();
433 }else if (rank
== null){
434 result
= getRanklessNameCache(nonViralName
);
435 // }else if (nonViralName.isInfragenericUnranked()){
436 // result = getUnrankedInfragenericNameCache(nonViralName);
437 }else if (rank
.isInfraSpecific()){
438 result
= getInfraSpeciesNameCache(nonViralName
);
439 }else if (rank
.isSpecies()){
440 result
= getSpeciesNameCache(nonViralName
);
441 }else if (rank
.isInfraGeneric()){
442 result
= getInfraGenusNameCache(nonViralName
);
443 }else if (rank
.isGenus()){
444 result
= getGenusOrUninomialNameCache(nonViralName
);
445 }else if (rank
.isSupraGeneric()){
446 result
= getGenusOrUninomialNameCache(nonViralName
);
448 logger
.warn("Name Strategy for Name (UUID: " + nonViralName
.getUuid() + ") not yet implemented");
455 private String
getUnrankedInfragenericNameCache(T nonViralName
) {
457 Rank rank
= nonViralName
.getRank();
458 if (rank
.isSpeciesAggregate()){
459 return getSpeciesAggregateCache(nonViralName
);
461 String infraGenericMarker
= rank
.getAbbreviation();
462 result
= CdmUtils
.Nz(nonViralName
.getGenusOrUninomial()).trim();
463 result
+= " " + infraGenericMarker
+ " " + (CdmUtils
.Nz(nonViralName
.getInfraGenericEpithet())).trim().replace("null", "");
464 result
= addAppendedPhrase(result
, nonViralName
).trim();
470 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy#getAuthorCache(eu.etaxonomy.cdm.model.name.NonViralName)
472 public String
getAuthorshipCache(T nonViralName
) {
473 if (nonViralName
== null){
477 if (nonViralName
.isProtectedAuthorshipCache() == true) {
478 return nonViralName
.getAuthorshipCache();
480 return getNonCacheAuthorshipCache(nonViralName
);
485 * Returns the authorshipcache string for the atomized authorship fields. Does not use the authorshipfield.
486 * @throws NullPointerException if nonViralName is null.
487 * @param nonViralName
490 protected String
getNonCacheAuthorshipCache(T nonViralName
){
492 INomenclaturalAuthor combinationAuthor
= nonViralName
.getCombinationAuthorTeam();
493 INomenclaturalAuthor exCombinationAuthor
= nonViralName
.getExCombinationAuthorTeam();
494 INomenclaturalAuthor basionymAuthor
= nonViralName
.getBasionymAuthorTeam();
495 INomenclaturalAuthor exBasionymAuthor
= nonViralName
.getExBasionymAuthorTeam();
496 String basionymPart
= "";
497 String authorPart
= "";
499 if (basionymAuthor
!= null || exBasionymAuthor
!= null){
500 basionymPart
= BasionymStart
+ getAuthorAndExAuthor(basionymAuthor
, exBasionymAuthor
) + BasionymEnd
;
502 if (combinationAuthor
!= null || exCombinationAuthor
!= null){
503 authorPart
= getAuthorAndExAuthor(combinationAuthor
, exCombinationAuthor
);
505 result
= CdmUtils
.concat(BasionymAuthorCombinationAuthorSeperator
, basionymPart
, authorPart
);
510 * Returns the AuthorCache part for a combination of an author and an ex author. This applies on combination authors
511 * as well as on basionym/orginal combination authors.
512 * @param author the author
513 * @param exAuthor the ex-author
516 protected String
getAuthorAndExAuthor(INomenclaturalAuthor author
, INomenclaturalAuthor exAuthor
){
518 String authorString
= "";
519 String exAuthorString
= "";
521 authorString
= CdmUtils
.Nz(author
.getNomenclaturalTitle());
523 if (exAuthor
!= null){
524 exAuthorString
= CdmUtils
.Nz(exAuthor
.getNomenclaturalTitle());
526 if (exAuthorString
.length() > 0 ){
527 exAuthorString
= exAuthorString
+ ExAuthorSeperator
;
529 result
= exAuthorString
+ authorString
;
534 // ************* TAGGED NAME ***************************************/
537 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTaggedTitle(eu.etaxonomy.cdm.model.name.TaxonNameBase)
540 public List
<TaggedText
> getTaggedFullTitle(T nonViralName
) {
541 List
<TaggedText
> tags
= new ArrayList
<TaggedText
>();
544 if (nonViralName
== null){
548 //protected full title cache
549 if (nonViralName
.isProtectedFullTitleCache()){
550 tags
.add(new TaggedText(TagEnum
.fullName
, nonViralName
.getFullTitleCache()));
555 // String titleCache = nonViralName.getTitleCache();
556 List
<TaggedText
> titleTags
= getTaggedTitle(nonViralName
);
557 tags
.addAll(titleTags
);
561 String microReference
= nonViralName
.getNomenclaturalMicroReference();
562 INomenclaturalReference ref
= nonViralName
.getNomenclaturalReference();
563 String referenceBaseCache
= null;
565 INomenclaturalReference nomenclaturalReference
= HibernateProxyHelper
.deproxy(ref
, INomenclaturalReference
.class);
566 nomenclaturalReference
.setCacheStrategy(nomenclaturalReference
.getType().getCacheStrategy());
567 referenceBaseCache
= nomenclaturalReference
.getNomenclaturalCitation(microReference
);
570 if (StringUtils
.isNotBlank(referenceBaseCache
)){
571 if (! referenceBaseCache
.trim().startsWith("in ")){
572 String refConcat
= ", ";
573 tags
.add(new TaggedText(TagEnum
.separator
, refConcat
));
575 tags
.add(new TaggedText(TagEnum
.reference
, referenceBaseCache
));
578 //nomenclatural status
579 Set
<NomenclaturalStatus
> ncStati
= nonViralName
.getStatus();
580 Iterator
<NomenclaturalStatus
> iterator
= ncStati
.iterator();
581 List
<TaggedText
> nomStatusTags
= new ArrayList
<TaggedText
>();
582 while (iterator
.hasNext()) {
583 NomenclaturalStatus ncStatus
= (NomenclaturalStatus
)iterator
.next();
584 // since the NewInstance method of nomencatural status allows null as parameter
585 // we have to check for null values here
586 String suffix
= "not defined";
587 if(ncStatus
.getType() != null){
588 NomenclaturalStatusType statusType
= ncStatus
.getType();
589 Language lang
= Language
.LATIN();
590 Representation repr
= statusType
.getRepresentation(lang
);
592 suffix
= repr
.getAbbreviatedLabel();
594 String message
= "No latin representation available for nom. status. " + statusType
.getTitleCache();
595 logger
.warn(message
);
596 throw new IllegalStateException(message
);
598 }else if(ncStatus
.getRuleConsidered() != null && ! ncStatus
.getRuleConsidered().equals("")){
599 suffix
= ncStatus
.getRuleConsidered();
601 String statusSeparator
= ", ";
602 nomStatusTags
.add(new TaggedText(TagEnum
.separator
, statusSeparator
));
603 nomStatusTags
.add(new TaggedText(TagEnum
.nomStatus
, suffix
));
605 tags
.addAll(nomStatusTags
);
610 public List
<TaggedText
> getTaggedTitle(T nonViralName
) {
611 if (nonViralName
== null){
615 List
<TaggedText
> tags
= new ArrayList
<TaggedText
>();
617 //TODO how to handle protected fullTitleCache here?
619 if (nonViralName
.isProtectedTitleCache()){
620 //protected title cache
621 tags
.add(new TaggedText(TagEnum
.name
, nonViralName
.getTitleCache()));
623 }else if (nonViralName
.isHybridFormula()){
625 String hybridSeparator
= NonViralNameParserImplRegExBase
.hybridSign
;
626 boolean isFirst
= true;
627 List
<HybridRelationship
> rels
= nonViralName
.getOrderedChildRelationships();
628 for (HybridRelationship rel
: rels
){
630 tags
.add(new TaggedText(TagEnum
.separator
, hybridSeparator
));
632 tags
.add(new TaggedText(TagEnum
.name
, hybridSeparator
));
634 tags
.addAll(getTaggedTitle((T
)rel
.getParentName()));
637 }else if (nonViralName
.isAutonym()){
639 tags
.addAll(handleTaggedAutonym(nonViralName
));
641 // String nameCache = nonViralName.getNameCache(); //OLD: CdmUtils.Nz(getNameCache(nonViralName));
642 List
<TaggedText
> nameTags
= getNameTags(nonViralName
);
643 tags
.addAll(nameTags
);
644 if (nameIncludesAuthorship(nonViralName
)){
645 String authorCache
= getAuthorshipCache(nonViralName
);
646 if (StringUtils
.isNotBlank(authorCache
)){
647 tags
.add(new TaggedText(TagEnum
.authors
, authorCache
));
657 * @param nonViralName
660 private List
<TaggedText
> getNameTags(T nonViralName
) {
661 if (nonViralName
== null){
664 List
<TaggedText
> tags
= new ArrayList
<TaggedText
>();
665 Rank rank
= nonViralName
.getRank();
667 if (nonViralName
.isProtectedNameCache()){
668 tags
.add(new TaggedText(TagEnum
.name
, nonViralName
.getNameCache()));
669 }else if (rank
== null){
670 tags
= getRanklessTaggedNameCache(nonViralName
);
671 // }else if (nonViralName.isInfragenericUnranked()){
672 // result = getUnrankedInfragenericNameCache(nonViralName);
673 }else if (rank
.isInfraSpecific()){
674 tags
= getInfraSpeciesTaggedNameCache(nonViralName
);
675 }else if (rank
.isSpecies()){
676 tags
= getSpeciesTaggedNameCache(nonViralName
);
677 }else if (rank
.isInfraGeneric()){
678 tags
= getInfraGenusTaggedNameCache(nonViralName
);
679 }else if (rank
.isGenus()){
680 tags
= getGenusOrUninomialTaggedNameCache(nonViralName
);
681 }else if (rank
.isSupraGeneric()){
682 tags
= getGenusOrUninomialTaggedNameCache(nonViralName
);
684 logger
.warn("Name Strategy for Name (UUID: " + nonViralName
.getUuid() + ") not yet implemented");
686 //TODO handle appended phrase here instead of different places, check first if this is true for all
694 //Old: may be replaced once getTagged(Full)Title is fully tested
696 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTaggedName(eu.etaxonomy.cdm.model.common.CdmBase)
699 public List
<Object
> getTaggedName(T nonViralName
) {
700 List
<Object
> tags
= new ArrayList
<Object
>();
702 if (nonViralName
.isProtectedNameCache() ||
703 nonViralName
.isProtectedAuthorshipCache() ||
704 nonViralName
.isProtectedFullTitleCache() ||
705 nonViralName
.isProtectedTitleCache()){
706 tags
.add(nonViralName
.getTitleCache());
710 // Why does it make sense to add the nameCache in case of non existing genusOrUninomial?
711 // if (nonViralName.getGenusOrUninomial() == null){
712 // tags.add(nonViralName.getNameCache());
715 if (nonViralName
.getGenusOrUninomial() != null) {
716 tags
.add(nonViralName
.getGenusOrUninomial());
718 if (nonViralName
.isSpecies() || nonViralName
.isInfraSpecific()){
719 tags
.add(nonViralName
.getSpecificEpithet());
723 if (nonViralName
.isInfraSpecific() && ! nonViralName
.getSpecificEpithet().equals(nonViralName
.getInfraSpecificEpithet())){
724 tags
.add(nonViralName
.getRank());
725 tags
.add(nonViralName
.getInfraSpecificEpithet());
728 if (nonViralName
.isInfraGeneric()){
729 //TODO choose right strategy or generic approach?
730 // --- strategy 1 ---
732 if (nonViralName
.getRank().isSpeciesAggregate()){
733 tags
.add(nonViralName
.getSpecificEpithet());
734 tags
.add(getSpeciesAggregateEpithet(nonViralName
));
736 tags
.add(nonViralName
.getRank());
737 tags
.add(nonViralName
.getInfraGenericEpithet());
739 // --- strategy 2 ---
740 // tags.add('('+nvn.getInfraGenericEpithet()+')');
742 Team authorTeam
= Team
.NewInstance();
743 authorTeam
.setProtectedTitleCache(true);
744 authorTeam
.setTitleCache(nonViralName
.getAuthorshipCache(), true);
745 tags
.add(authorTeam
);
747 // Name is an autonym. Rank and infraspecific epitheton follow the author
748 if (nonViralName
.isInfraSpecific() && nonViralName
.getSpecificEpithet().equals(nonViralName
.getInfraSpecificEpithet())){
749 tags
.add(nonViralName
.getRank());
750 tags
.add(nonViralName
.getInfraSpecificEpithet());
753 if(! "".equals(nonViralName
.getAppendedPhrase())&& (nonViralName
.getAppendedPhrase() != null)){
754 tags
.add(nonViralName
.getAppendedPhrase());
761 //***************************** PRIVATES ***************************************/
763 protected List
<TaggedText
> getRanklessTaggedNameCache(NonViralName
<?
> nonViralName
){
764 List
<TaggedText
> tags
= getUninomialTaggedPart(nonViralName
);
765 String speciesEpi
= CdmUtils
.Nz(nonViralName
.getSpecificEpithet()).trim().replace("null", "");
766 if (StringUtils
.isNotBlank(speciesEpi
)){
767 tags
.add(new TaggedText(TagEnum
.name
, speciesEpi
));
770 String infraSpeciesEpi
= CdmUtils
.Nz(nonViralName
.getInfraSpecificEpithet()).trim().replace("null", "");
771 if (StringUtils
.isNotBlank(infraSpeciesEpi
)){
772 tags
.add(new TaggedText(TagEnum
.name
, infraSpeciesEpi
));
775 //result += " (rankless)";
776 addAppendedTaggedPhrase(tags
, nonViralName
);
780 protected String
getRanklessNameCache(NonViralName
<?
> nonViralName
){
782 result
= (result
+ (CdmUtils
.Nz(nonViralName
.getGenusOrUninomial()))).trim().replace("null", "");
783 result
+= " " + (CdmUtils
.Nz(nonViralName
.getSpecificEpithet())).trim();
784 result
+= " " + (CdmUtils
.Nz(nonViralName
.getInfraSpecificEpithet())).trim();
785 result
= result
.trim().replace("null", "");
786 //result += " (rankless)";
787 result
= addAppendedPhrase(result
, nonViralName
);
792 protected List
<TaggedText
> getGenusOrUninomialTaggedNameCache(NonViralName
<?
> nonViralName
){
793 List
<TaggedText
> tags
= getUninomialTaggedPart(nonViralName
);
794 addAppendedTaggedPhrase(tags
, nonViralName
);
798 protected String
getGenusOrUninomialNameCache(NonViralName
<?
> nonViralName
){
800 result
= getUninomialPart(nonViralName
);
801 result
= addAppendedPhrase(result
, nonViralName
).trim();
806 private List
<TaggedText
> getUninomialTaggedPart(NonViralName
<?
> nonViralName
) {
807 List
<TaggedText
> tags
= new ArrayList
<TaggedText
>();
809 if (nonViralName
.isMonomHybrid()){
810 addHybridPrefix(tags
);
813 String uninomial
= CdmUtils
.Nz(nonViralName
.getGenusOrUninomial()).trim().replace("null", "");
814 if (StringUtils
.isNotBlank(uninomial
)){
815 tags
.add(new TaggedText(TagEnum
.name
, uninomial
));
821 private String
getUninomialPart(NonViralName
<?
> nonViralName
) {
823 result
= CdmUtils
.Nz(nonViralName
.getGenusOrUninomial()).trim();
824 if (nonViralName
.isMonomHybrid()){
825 result
= NonViralNameParserImplRegExBase
.hybridSign
+ result
;
831 protected List
<TaggedText
> getInfraGenusTaggedNameCache(NonViralName
<?
> nonViralName
){
832 Rank rank
= nonViralName
.getRank();
833 if (rank
.isSpeciesAggregate()){
834 return getSpeciesAggregateTaggedCache(nonViralName
);
838 List
<TaggedText
> tags
= getUninomialTaggedPart(nonViralName
);
841 String infraGenericMarker
= "'unhandled infrageneric rank'";
844 infraGenericMarker
= rank
.getInfraGenericMarker();
845 } catch (UnknownCdmTypeException e
) {
846 infraGenericMarker
= "'unhandled infrageneric rank'";
849 tags
.add(new TaggedText(TagEnum
.rank
, infraGenericMarker
));
852 String infraGenEpi
= CdmUtils
.Nz(nonViralName
.getInfraGenericEpithet()).trim().replace("null", "");
853 if (StringUtils
.isNotBlank(infraGenEpi
)){
854 tags
.add(new TaggedText(TagEnum
.name
, infraGenEpi
));
857 addAppendedTaggedPhrase(tags
, nonViralName
);
861 protected String
getInfraGenusNameCache(NonViralName
<?
> nonViralName
){
863 Rank rank
= nonViralName
.getRank();
864 if (rank
.isSpeciesAggregate()){
865 return getSpeciesAggregateCache(nonViralName
);
867 String infraGenericMarker
= "'unhandled infrageneric rank'";
870 infraGenericMarker
= rank
.getInfraGenericMarker();
871 } catch (UnknownCdmTypeException e
) {
872 infraGenericMarker
= "'unhandled infrageneric rank'";
875 result
= getUninomialPart(nonViralName
);
876 result
+= " " + infraGenericMarker
+ " " + (CdmUtils
.Nz(nonViralName
.getInfraGenericEpithet())).trim().replace("null", "");
877 result
= addAppendedPhrase(result
, nonViralName
).trim();
882 protected List
<TaggedText
> getSpeciesAggregateTaggedCache(NonViralName
<?
> nonViralName
){
883 List
<TaggedText
> tags
= getGenusAndSpeciesTaggedPart(nonViralName
);
885 addSpeciesAggregateTaggedEpithet(tags
, nonViralName
);
886 addAppendedTaggedPhrase(tags
, nonViralName
);
890 private void addSpeciesAggregateTaggedEpithet(List
<TaggedText
> tags
, NonViralName
<?
> nonViralName
) {
893 marker
= nonViralName
.getRank().getInfraGenericMarker();
894 } catch (UnknownCdmTypeException e
) {
895 marker
= "'unknown aggregat type'";
897 if (StringUtils
.isNotBlank(marker
)){
898 tags
.add(new TaggedText(TagEnum
.rank
, marker
));
903 protected String
getSpeciesAggregateCache(NonViralName
<?
> nonViralName
){
904 String result
= getGenusAndSpeciesPart(nonViralName
);
906 result
+= " " + getSpeciesAggregateEpithet(nonViralName
);
907 result
= addAppendedPhrase(result
, nonViralName
).trim();
911 private String
getSpeciesAggregateEpithet(NonViralName
<?
> nonViralName
) {
914 marker
= nonViralName
.getRank().getInfraGenericMarker();
915 } catch (UnknownCdmTypeException e
) {
916 marker
= "'unknown aggregat type'";
922 protected List
<TaggedText
> getSpeciesTaggedNameCache(NonViralName
<?
> nonViralName
){
923 List
<TaggedText
> tags
= getGenusAndSpeciesTaggedPart(nonViralName
);
924 addAppendedTaggedPhrase(tags
, nonViralName
);
928 protected String
getSpeciesNameCache(NonViralName
<?
> nonViralName
){
929 String result
= getGenusAndSpeciesPart(nonViralName
);
930 result
= addAppendedPhrase(result
, nonViralName
).trim();
931 result
= result
.replace("\\s\\", " ");
935 protected List
<TaggedText
> getInfraSpeciesTaggedNameCache(NonViralName
<?
> nonViralName
){
936 return getInfraSpeciesTaggedNameCache(nonViralName
, true);
939 protected List
<TaggedText
> getInfraSpeciesTaggedNameCache(NonViralName
<?
> nonViralName
, boolean includeMarker
){
940 List
<TaggedText
> tags
= getGenusAndSpeciesTaggedPart(nonViralName
);
942 String marker
= (nonViralName
.getRank().getAbbreviation()).trim().replace("null", "");
943 if (StringUtils
.isNotBlank(marker
)){
944 tags
.add(new TaggedText(TagEnum
.rank
, marker
));
947 String infrSpecEpi
= CdmUtils
.Nz(nonViralName
.getInfraSpecificEpithet());
948 if (nonViralName
.isTrinomHybrid()){
949 addHybridPrefix(tags
);
952 infrSpecEpi
= infrSpecEpi
.trim().replace("null", "");
953 if (StringUtils
.isNotBlank(infrSpecEpi
)){
954 tags
.add(new TaggedText(TagEnum
.name
, infrSpecEpi
));
957 addAppendedTaggedPhrase(tags
, nonViralName
);
963 * Adds a tag for the hybrid sign and an empty separator to avoid trailing whitespaces.
966 private void addHybridPrefix(List
<TaggedText
> tags
) {
967 tags
.add(new TaggedText(TagEnum
.hybridSign
, NonViralNameParserImplRegExBase
.hybridSign
));
968 tags
.add(new TaggedText(TagEnum
.separator
, "")); //no whitespace separator
971 protected String
getInfraSpeciesNameCache(NonViralName
<?
> nonViralName
){
972 return getInfraSpeciesNameCache(nonViralName
, true);
976 protected String
getInfraSpeciesNameCache(NonViralName
<?
> nonViralName
, boolean includeMarker
){
977 String result
= getGenusAndSpeciesPart(nonViralName
);
979 result
+= " " + (nonViralName
.getRank().getAbbreviation()).trim().replace("null", "");
981 String infrSpecEpi
= CdmUtils
.Nz(nonViralName
.getInfraSpecificEpithet());
982 if (nonViralName
.isTrinomHybrid()){
983 infrSpecEpi
= NonViralNameParserImplRegExBase
.hybridSign
+ infrSpecEpi
;
985 result
+= " " + (infrSpecEpi
).trim().replace("null", "");
986 result
= addAppendedPhrase(result
, nonViralName
).trim();
991 private List
<TaggedText
> getGenusAndSpeciesTaggedPart(NonViralName
<?
> nonViralName
) {
993 List
<TaggedText
> tags
= getUninomialTaggedPart(nonViralName
);
996 boolean hasInfraGenericEpi
= StringUtils
.isNotBlank(nonViralName
.getInfraGenericEpithet());
997 if (hasInfraGenericEpi
){
998 String infrGenEpi
= nonViralName
.getInfraGenericEpithet().trim();
999 if (nonViralName
.isBinomHybrid()){
1000 // addHybridPrefix(tags); FIXME hybridSign should be tag, but then we need to handle "(" ")" differently.
1001 infrGenEpi
= NonViralNameParserImplRegExBase
.hybridSign
+ infrGenEpi
;
1003 infrGenEpi
= "(" + infrGenEpi
+ ")";
1004 tags
.add(new TaggedText(TagEnum
.name
, infrGenEpi
));
1008 String specEpi
= CdmUtils
.Nz(nonViralName
.getSpecificEpithet()).trim().replace("null", "");
1009 if (! hasInfraGenericEpi
&& nonViralName
.isBinomHybrid() ||
1010 hasInfraGenericEpi
&& nonViralName
.isTrinomHybrid()){
1011 addHybridPrefix(tags
);
1013 if (StringUtils
.isNotBlank(specEpi
)){
1014 tags
.add(new TaggedText(TagEnum
.name
, specEpi
));
1019 private String
getGenusAndSpeciesPart(NonViralName
<?
> nonViralName
) {
1022 result
= getUninomialPart(nonViralName
);
1025 boolean hasInfraGenericEpi
= StringUtils
.isNotBlank(nonViralName
.getInfraGenericEpithet());
1026 if (hasInfraGenericEpi
){
1027 String infrGenEpi
= nonViralName
.getInfraGenericEpithet().trim();
1028 if (nonViralName
.isBinomHybrid()){
1029 infrGenEpi
= NonViralNameParserImplRegExBase
.hybridSign
+ infrGenEpi
;
1031 result
+= " (" + infrGenEpi
+ ")";
1034 String specEpi
= CdmUtils
.Nz(nonViralName
.getSpecificEpithet()).trim();
1035 if (! hasInfraGenericEpi
&& nonViralName
.isBinomHybrid() ||
1036 hasInfraGenericEpi
&& nonViralName
.isTrinomHybrid()){
1037 specEpi
= NonViralNameParserImplRegExBase
.hybridSign
+ specEpi
;
1039 result
+= " " + (specEpi
).replace("null", "");
1045 * Adds the tag for the appended phrase if an appended phrase exists
1047 * @param nonViralName
1049 protected void addAppendedTaggedPhrase(List
<TaggedText
> tags
, NonViralName
<?
> nonViralName
){
1050 String appendedPhrase
= nonViralName
==null ?
null : nonViralName
.getAppendedPhrase();
1051 if (StringUtils
.isNotEmpty(appendedPhrase
)){
1052 tags
.add(new TaggedText(TagEnum
.name
, appendedPhrase
));
1056 protected String
addAppendedPhrase(String resultString
, NonViralName
<?
> nonViralName
){
1057 String appendedPhrase
= nonViralName
==null ?
null : nonViralName
.getAppendedPhrase();
1058 if (resultString
== null){
1059 return appendedPhrase
;
1060 }else if(appendedPhrase
== null || "".equals(appendedPhrase
.trim())) {
1061 return resultString
;
1062 }else if ("".equals(resultString
)){
1063 return resultString
+ appendedPhrase
;
1065 return resultString
+ " " + appendedPhrase
;
1070 public String
getLastEpithet(T taxonNameBase
) {
1071 Rank rank
= taxonNameBase
.getRank();
1072 if(rank
.isGenus() || rank
.isSupraGeneric()) {
1073 return taxonNameBase
.getGenusOrUninomial();
1074 } else if(rank
.isInfraGeneric()) {
1075 return taxonNameBase
.getInfraGenericEpithet();
1076 } else if(rank
.isSpecies()) {
1077 return taxonNameBase
.getSpecificEpithet();
1079 return taxonNameBase
.getInfraSpecificEpithet();