Merge branch 'release/5.32.0'
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / strategy / cache / name / NameCacheStrategyBase.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9 package eu.etaxonomy.cdm.strategy.cache.name;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Iterator;
14 import java.util.List;
15 import java.util.Set;
16 import java.util.UUID;
17
18 import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
19
20 import eu.etaxonomy.cdm.common.CdmUtils;
21 import eu.etaxonomy.cdm.format.reference.NomenclaturalSourceFormatter;
22 import eu.etaxonomy.cdm.model.common.CdmBase;
23 import eu.etaxonomy.cdm.model.common.Language;
24 import eu.etaxonomy.cdm.model.name.INonViralName;
25 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
26 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
27 import eu.etaxonomy.cdm.model.name.TaxonName;
28 import eu.etaxonomy.cdm.model.term.Representation;
29 import eu.etaxonomy.cdm.ref.TypedEntityReference;
30 import eu.etaxonomy.cdm.strategy.StrategyBase;
31 import eu.etaxonomy.cdm.strategy.cache.HTMLTagRules;
32 import eu.etaxonomy.cdm.strategy.cache.TagEnum;
33 import eu.etaxonomy.cdm.strategy.cache.TaggedCacheHelper;
34 import eu.etaxonomy.cdm.strategy.cache.TaggedText;
35 import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImplRegExBase;
36
37 /**
38 * @author AM
39 */
40 public abstract class NameCacheStrategyBase
41 extends StrategyBase
42 implements INameCacheStrategy {
43 private static final long serialVersionUID = -2322348388258675517L;
44
45 private static final Logger logger = LogManager.getLogger(NameCacheStrategyBase.class);
46
47 final static UUID uuid = UUID.fromString("817ae5b5-3ac2-414b-a134-a9ae86cba040");
48
49 public NameCacheStrategyBase() {
50 super();
51 }
52
53 @Override
54 public String getFullTitleCache(TaxonName taxonName, HTMLTagRules htmlTagRules) {
55 List<TaggedText> tags = getTaggedFullTitle(taxonName);
56 if (tags == null){
57 return null;
58 }else{
59 String result = createString(tags, htmlTagRules);
60 return result;
61 }
62 }
63
64 @Override
65 public String getFullTitleCache(TaxonName taxonName) {
66 return getFullTitleCache(taxonName, null);
67 }
68
69 @Override
70 public List<TaggedText> getNomStatusTags(TaxonName taxonName, boolean includeSeparatorBefore,
71 boolean includeSeparatorAfter) {
72
73 Set<NomenclaturalStatus> ncStati = taxonName.getStatus();
74 Iterator<NomenclaturalStatus> iterator = ncStati.iterator();
75 List<TaggedText> nomStatusTags = new ArrayList<>();
76 while (iterator.hasNext()) {
77 NomenclaturalStatus ncStatus = iterator.next();
78 // since the NewInstance method of nomencatural status allows null as parameter
79 // we have to check for null values here
80 String nomStatusStr = "not defined";
81 if(ncStatus.getType() != null){
82 NomenclaturalStatusType statusType = ncStatus.getType();
83 List<Language> prefLangs = Arrays.asList(new Language[]{Language.LATIN(), Language.DEFAULT()});
84 Representation repr = statusType.getPreferredRepresentation(prefLangs);
85 if (repr != null){
86 if(!Language.LATIN().equals(repr.getLanguage())){
87 String message = "No latin representation available for nom. status. " + statusType.getTitleCache();
88 logger.info(message);
89 }
90 nomStatusStr = repr.getAbbreviatedLabel();
91 }else{
92 String message = "No representation available for nom. status. " + statusType.getTitleCache();
93 logger.warn(message);
94 nomStatusStr = statusType.getTitleCache();
95 }
96 }else if(isNotBlank(ncStatus.getRuleConsidered())){
97 nomStatusStr = ncStatus.getRuleConsidered();
98 }
99 String statusSeparator = ", ";
100 if (includeSeparatorBefore){
101 nomStatusTags.add(new TaggedText(TagEnum.separator, statusSeparator));
102 }
103 nomStatusTags.add(new TaggedText(TagEnum.nomStatus, nomStatusStr, new TypedEntityReference<>(ncStatus.getClass(), ncStatus.getUuid())));
104 if (includeSeparatorAfter){
105 nomStatusTags.add(new TaggedText(TagEnum.postSeparator, ","));
106 }
107 }
108 return nomStatusTags;
109 }
110
111 @Override
112 public String getNameCache(TaxonName nonViralName) {
113 List<TaggedText> tags = getTaggedName(nonViralName);
114 if (tags == null){
115 return null;
116 }else{
117 String result = createString(tags);
118 return result;
119 }
120 }
121
122 @Override
123 public String getNameCache(TaxonName nonViralName, HTMLTagRules htmlTagRules) {
124 List<TaggedText> tags = getTaggedName(nonViralName);
125 if (tags == null){
126 return null;
127 }else{
128 String result = createString(tags, htmlTagRules);
129 return result;
130 }
131 }
132
133 /**
134 * Generates and returns the title cache of the given name.
135 * The title cache in general includes the name and the authorship and year for some types of names.
136 *
137 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTitleCache(eu.etaxonomy.cdm.model.common.CdmBase)
138 * @see eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy#getTitleCache(eu.etaxonomy.cdm.model.common.IdentifiableEntity)
139 */
140 @Override
141 public String getTitleCache(TaxonName taxonName) {
142 return getTitleCache(taxonName, null);
143 }
144
145 @Override
146 public String getTitleCache(TaxonName taxonName, HTMLTagRules htmlTagRules) {
147 List<TaggedText> tags = getTaggedTitle(taxonName);
148 if (tags == null){
149 return null;
150 }else{
151 String result = createString(tags, htmlTagRules);
152 return result;
153 }
154 }
155
156 @Override
157 public List<TaggedText> getTaggedTitle(TaxonName taxonName) {
158 if (taxonName == null){
159 return null;
160 }
161 //TODO how to handle protected fullTitleCache here?
162
163 if (taxonName.isProtectedTitleCache()){
164 //protected title cache
165 List<TaggedText> tags = new ArrayList<>();
166 tags.add(new TaggedText(TagEnum.name, taxonName.getTitleCache()));
167 return tags;
168 }else{
169 return doGetTaggedTitle(taxonName);
170 }
171 }
172
173 protected abstract List<TaggedText> doGetTaggedTitle(TaxonName taxonName);
174
175 @Override
176 public List<TaggedText> getTaggedFullTitle(TaxonName taxonName) {
177 List<TaggedText> tags = new ArrayList<>();
178
179 //null
180 if (taxonName == null){
181 return null;
182 }
183
184 //protected full title cache
185 if (taxonName.isProtectedFullTitleCache()){
186 tags.add(new TaggedText(TagEnum.fullName, taxonName.getFullTitleCache()));
187 return tags;
188 }
189
190 //title cache
191 // String titleCache = nonViralName.getTitleCache();
192 List<TaggedText> titleTags = getTaggedTitle(taxonName);
193 tags.addAll(titleTags);
194
195 //reference
196 String referenceCache = NomenclaturalSourceFormatter.INSTANCE().format(taxonName.getNomenclaturalSource());
197 //add to tags
198 if (isNotBlank(referenceCache)){
199 if (! referenceCache.trim().startsWith("in ")){
200 String refConcat = ", ";
201 tags.add(new TaggedText(TagEnum.separator, refConcat));
202 }
203 tags.add(new TaggedText(TagEnum.reference, referenceCache));
204 }
205
206 addOriginalSpelling(tags, taxonName);
207
208 //nomenclatural status
209 tags.addAll(getNomStatusTags(taxonName, true, false));
210 return tags;
211 }
212
213 protected void addOriginalSpelling(List<TaggedText> tags, TaxonName currentName){
214
215 currentName = CdmBase.deproxy(currentName);
216 //Hibernate.initialize(currentName.getRelationsToThisName());
217 TaxonName originalName = currentName.getOriginalSpelling();
218 if (originalName != null){
219 String originalInfo;
220 tags.add(TaggedText.NewSeparatorInstance(" [as \""));
221 if (!originalName.isNonViral()){
222 originalInfo = originalName.getTitleCache();
223 tags.add(new TaggedText(TagEnum.name, originalInfo));
224 }else{
225 INonViralName originalNvName = CdmBase.deproxy(originalName);
226 originalInfo = makeOriginalInfo(originalNvName, tags);
227 for (String split : originalInfo.split(" ")){
228 if (split.matches(NonViralNameParserImplRegExBase.infraSpeciesMarker)
229 || split.matches(NonViralNameParserImplRegExBase.oldInfraSpeciesMarker)) {
230 tags.add(new TaggedText(TagEnum.rank, split));
231 }else{
232 tags.add(new TaggedText(TagEnum.name, split));
233 }
234 }
235 }
236 tags.add(TaggedText.NewSeparatorInstance("\"]"));
237 }else{
238 return;
239 }
240 }
241
242 private String makeOriginalInfo(INonViralName originalName,
243 List<TaggedText> currentNameTags) {
244 //use cache if necessary
245 String cacheToUse = null;
246 if (originalName.isProtectedNameCache() && isNotBlank(originalName.getNameCache())){
247 cacheToUse = originalName.getNameCache();
248 }else if (originalName.isProtectedTitleCache() && isNotBlank(originalName.getTitleCache())){
249 cacheToUse = originalName.getTitleCache();
250 }else if (originalName.isProtectedFullTitleCache() && isNotBlank(originalName.getFullTitleCache())){
251 cacheToUse = originalName.getFullTitleCache();
252 }
253 if (cacheToUse != null){
254 return cacheToUse;
255 }
256 //use atomized data
257 //get originalNameParts array
258 String originalInfo = originalName.getNameCache();
259 if (originalInfo == null){
260 originalInfo = originalName.getTitleCache();
261 }
262 if (originalInfo == null){ //should not happen
263 originalInfo = originalName.getFullTitleCache();
264 }
265 String[] originalNameSplit = originalInfo.split("\\s+");
266
267 //get current name parts
268 String currentNameString = createString(currentNameTags);
269 String[] currentNameSplit = currentNameString.split("\\s+");
270
271 //compute string
272 String result = originalInfo;
273 Integer firstDiff = null;
274 Integer lastDiff = -1;
275 for (int i = 0; i < Math.min(originalNameSplit.length, currentNameSplit.length); i++){
276 if (!originalNameSplit[i].equals(currentNameSplit[i])){
277 lastDiff = i;
278 firstDiff = (firstDiff == null) ? i : firstDiff;
279 }
280 }
281 if (firstDiff != null){
282 result = CdmUtils.concat(" ", Arrays.asList(originalNameSplit).subList(firstDiff, lastDiff+1).toArray(new String[0]));
283 }
284
285 return result;
286 }
287
288 protected String createString(List<TaggedText> tags) {
289 return TaggedCacheHelper.createString(tags);
290 }
291
292 protected String createString(List<TaggedText> tags, HTMLTagRules htmlTagRules) {
293 return TaggedCacheHelper.createString(tags, htmlTagRules);
294 }
295 }