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
.Arrays
;
13 import java
.util
.Collection
;
14 import java
.util
.Iterator
;
15 import java
.util
.List
;
16 import java
.util
.UUID
;
18 import org
.apache
.logging
.log4j
.LogManager
;
19 import org
.apache
.logging
.log4j
.Logger
;
21 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
22 import eu
.etaxonomy
.cdm
.compare
.name
.NomenclaturalStatusComparator
;
23 import eu
.etaxonomy
.cdm
.format
.reference
.NomenclaturalSourceFormatter
;
24 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
25 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
26 import eu
.etaxonomy
.cdm
.model
.name
.INonViralName
;
27 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatus
;
28 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalStatusType
;
29 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
30 import eu
.etaxonomy
.cdm
.model
.term
.Representation
;
31 import eu
.etaxonomy
.cdm
.ref
.TypedEntityReferenceFactory
;
32 import eu
.etaxonomy
.cdm
.strategy
.StrategyBase
;
33 import eu
.etaxonomy
.cdm
.strategy
.cache
.HTMLTagRules
;
34 import eu
.etaxonomy
.cdm
.strategy
.cache
.TagEnum
;
35 import eu
.etaxonomy
.cdm
.strategy
.cache
.TaggedTextFormatter
;
36 import eu
.etaxonomy
.cdm
.strategy
.cache
.TaggedText
;
37 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImplRegExBase
;
42 public abstract class NameCacheStrategyBase
44 implements INameCacheStrategy
{
46 private static final long serialVersionUID
= -2322348388258675517L;
47 private static final Logger logger
= LogManager
.getLogger();
49 final static UUID uuid
= UUID
.fromString("817ae5b5-3ac2-414b-a134-a9ae86cba040");
51 public NameCacheStrategyBase() {
56 public String
getFullTitleCache(TaxonName taxonName
, HTMLTagRules htmlTagRules
) {
57 List
<TaggedText
> tags
= getTaggedFullTitle(taxonName
);
61 String result
= createString(tags
, htmlTagRules
);
67 public String
getFullTitleCache(TaxonName taxonName
) {
68 return getFullTitleCache(taxonName
, null);
72 public List
<TaggedText
> getNomStatusTags(TaxonName taxonName
, boolean includeSeparatorBefore
,
73 boolean includeSeparatorAfter
) {
75 Collection
<NomenclaturalStatus
> ncStati
= taxonName
.getStatus();
76 if (ncStati
.size() > 1) {
77 //order to have defined behavior
78 ncStati
= new ArrayList
<>(ncStati
);
79 ((List
<NomenclaturalStatus
>)ncStati
).sort(NomenclaturalStatusComparator
.SINGLETON());
81 Iterator
<NomenclaturalStatus
> iterator
= ncStati
.iterator();
82 List
<TaggedText
> nomStatusTags
= new ArrayList
<>();
84 String statusSeparator
= ", ";
85 if (includeSeparatorBefore
&& !ncStati
.isEmpty()){
86 nomStatusTags
.add(new TaggedText(TagEnum
.separator
, statusSeparator
));
88 boolean isFirst
= true;
89 while (iterator
.hasNext()) {
90 NomenclaturalStatus ncStatus
= iterator
.next();
91 // since the NewInstance method of nomencatural status allows null as parameter
92 // we have to check for null values here
93 String nomStatusStr
= "not defined";
94 if(ncStatus
.getType() != null){
95 NomenclaturalStatusType statusType
= ncStatus
.getType();
96 List
<Language
> prefLangs
= Arrays
.asList(new Language
[]{Language
.LATIN(), Language
.DEFAULT()});
97 Representation repr
= statusType
.getPreferredRepresentation(prefLangs
);
99 if(!Language
.LATIN().equals(repr
.getLanguage())){
100 String message
= "No latin representation available for nom. status. " + statusType
.getTitleCache();
101 logger
.info(message
);
103 nomStatusStr
= repr
.getAbbreviatedLabel();
105 String message
= "No representation available for nom. status. " + statusType
.getTitleCache();
106 logger
.warn(message
);
107 nomStatusStr
= statusType
.getTitleCache();
109 }else if(isNotBlank(ncStatus
.getRuleConsidered())){
110 nomStatusStr
= ncStatus
.getRuleConsidered();
113 nomStatusTags
.add(new TaggedText(TagEnum
.separator
, statusSeparator
));
115 nomStatusTags
.add(new TaggedText(TagEnum
.nomStatus
, nomStatusStr
, TypedEntityReferenceFactory
.fromTypeAndId(ncStatus
.getClass(), ncStatus
.getUuid())));
118 if (includeSeparatorAfter
&& !isFirst
){
119 nomStatusTags
.add(new TaggedText(TagEnum
.postSeparator
, ","));
121 return nomStatusTags
;
125 public String
getNameCache(TaxonName nonViralName
) {
126 List
<TaggedText
> tags
= getTaggedName(nonViralName
);
130 String result
= createString(tags
);
136 public String
getNameCache(TaxonName nonViralName
, HTMLTagRules htmlTagRules
) {
137 List
<TaggedText
> tags
= getTaggedName(nonViralName
);
141 String result
= createString(tags
, htmlTagRules
);
147 * Generates and returns the title cache of the given name.
148 * The title cache in general includes the name and the authorship and year for some types of names.
150 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTitleCache(eu.etaxonomy.cdm.model.common.CdmBase)
151 * @see eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy#getTitleCache(eu.etaxonomy.cdm.model.common.IdentifiableEntity)
154 public String
getTitleCache(TaxonName taxonName
) {
155 return getTitleCache(taxonName
, null);
159 public String
getTitleCache(TaxonName taxonName
, HTMLTagRules htmlTagRules
) {
160 List
<TaggedText
> tags
= getTaggedTitle(taxonName
);
164 String result
= createString(tags
, htmlTagRules
);
170 public List
<TaggedText
> getTaggedTitle(TaxonName taxonName
) {
171 if (taxonName
== null){
174 //TODO how to handle protected fullTitleCache here?
176 if (taxonName
.isProtectedTitleCache()){
177 //protected title cache
178 List
<TaggedText
> tags
= new ArrayList
<>();
179 tags
.add(new TaggedText(TagEnum
.name
, taxonName
.getTitleCache()));
182 return doGetTaggedTitle(taxonName
);
186 protected abstract List
<TaggedText
> doGetTaggedTitle(TaxonName taxonName
);
189 public List
<TaggedText
> getTaggedFullTitle(TaxonName taxonName
) {
190 List
<TaggedText
> tags
= new ArrayList
<>();
193 if (taxonName
== null){
197 //protected full title cache
198 if (taxonName
.isProtectedFullTitleCache()){
199 tags
.add(new TaggedText(TagEnum
.fullName
, taxonName
.getFullTitleCache()));
204 // String titleCache = nonViralName.getTitleCache();
205 List
<TaggedText
> titleTags
= getTaggedTitle(taxonName
);
206 tags
.addAll(titleTags
);
209 String referenceCache
= NomenclaturalSourceFormatter
.INSTANCE().format(taxonName
.getNomenclaturalSource());
211 if (isNotBlank(referenceCache
)){
212 if (! referenceCache
.trim().startsWith("in ")){
213 String refConcat
= ", ";
214 tags
.add(new TaggedText(TagEnum
.separator
, refConcat
));
216 tags
.add(new TaggedText(TagEnum
.reference
, referenceCache
));
219 addOriginalSpelling(tags
, taxonName
);
221 //nomenclatural status
222 tags
.addAll(getNomStatusTags(taxonName
, true, false));
226 protected void addOriginalSpelling(List
<TaggedText
> tags
, TaxonName currentName
){
228 currentName
= CdmBase
.deproxy(currentName
);
229 //Hibernate.initialize(currentName.getRelationsToThisName());
230 TaxonName originalName
= currentName
.getOriginalSpelling();
231 if (originalName
!= null){
233 tags
.add(new TaggedText(TagEnum
.nameInSourceSeparator
, " [as \""));
234 if (!originalName
.isNonViral()){
235 originalInfo
= originalName
.getTitleCache();
236 tags
.add(new TaggedText(TagEnum
.name
, originalInfo
));
238 INonViralName originalNvName
= CdmBase
.deproxy(originalName
);
239 originalInfo
= makeOriginalInfo(originalNvName
, tags
);
240 for (String split
: originalInfo
.split(" ")){
241 if (split
.matches(NonViralNameParserImplRegExBase
.infraSpeciesMarker
)
242 || split
.matches(NonViralNameParserImplRegExBase
.oldInfraSpeciesMarker
)) {
243 tags
.add(new TaggedText(TagEnum
.rank
, split
));
245 tags
.add(new TaggedText(TagEnum
.name
, split
));
249 tags
.add(new TaggedText(TagEnum
.nameInSourceSeparator
, "\"]"));
255 private String
makeOriginalInfo(INonViralName originalName
,
256 List
<TaggedText
> currentNameTags
) {
257 //use cache if necessary
258 String cacheToUse
= null;
259 if (originalName
.isProtectedNameCache() && isNotBlank(originalName
.getNameCache())){
260 cacheToUse
= originalName
.getNameCache();
261 }else if (originalName
.isProtectedTitleCache() && isNotBlank(originalName
.getTitleCache())){
262 cacheToUse
= originalName
.getTitleCache();
263 }else if (originalName
.isProtectedFullTitleCache() && isNotBlank(originalName
.getFullTitleCache())){
264 cacheToUse
= originalName
.getFullTitleCache();
266 if (cacheToUse
!= null){
270 //get originalNameParts array
271 String originalInfo
= originalName
.getNameCache();
272 if (originalInfo
== null){
273 originalInfo
= originalName
.getTitleCache();
275 if (originalInfo
== null){ //should not happen
276 originalInfo
= originalName
.getFullTitleCache();
278 String
[] originalNameSplit
= originalInfo
.split("\\s+");
280 //get current name parts
281 String currentNameString
= createString(currentNameTags
);
282 String
[] currentNameSplit
= currentNameString
.split("\\s+");
285 String result
= originalInfo
;
286 Integer firstDiff
= null;
287 Integer lastDiff
= -1;
288 for (int i
= 0; i
< Math
.min(originalNameSplit
.length
, currentNameSplit
.length
); i
++){
289 if (!originalNameSplit
[i
].equals(currentNameSplit
[i
])){
291 firstDiff
= (firstDiff
== null) ? i
: firstDiff
;
294 if (firstDiff
!= null){
295 result
= CdmUtils
.concat(" ", Arrays
.asList(originalNameSplit
).subList(firstDiff
, lastDiff
+1).toArray(new String
[0]));
301 protected String
createString(List
<TaggedText
> tags
) {
302 return TaggedTextFormatter
.createString(tags
);
305 protected String
createString(List
<TaggedText
> tags
, HTMLTagRules htmlTagRules
) {
306 return TaggedTextFormatter
.createString(tags
, htmlTagRules
);