ref #6630 unified all taxon name cache strategies except for ViralNameDefaultCacheStr...
[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.Iterator;
13 import java.util.List;
14 import java.util.Set;
15 import java.util.UUID;
16
17 import org.apache.commons.lang.StringUtils;
18 import org.apache.log4j.Logger;
19
20 import eu.etaxonomy.cdm.common.CdmUtils;
21 import eu.etaxonomy.cdm.common.UTF8;
22 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
23 import eu.etaxonomy.cdm.model.common.CdmBase;
24 import eu.etaxonomy.cdm.model.common.Language;
25 import eu.etaxonomy.cdm.model.common.Representation;
26 import eu.etaxonomy.cdm.model.name.INonViralName;
27 import eu.etaxonomy.cdm.model.name.ITaxonNameBase;
28 import eu.etaxonomy.cdm.model.name.NameRelationship;
29 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
30 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
31 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
32 import eu.etaxonomy.cdm.model.name.TaxonName;
33 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
34 import eu.etaxonomy.cdm.model.reference.Reference;
35 import eu.etaxonomy.cdm.strategy.StrategyBase;
36 import eu.etaxonomy.cdm.strategy.cache.HTMLTagRules;
37 import eu.etaxonomy.cdm.strategy.cache.TagEnum;
38 import eu.etaxonomy.cdm.strategy.cache.TaggedCacheHelper;
39 import eu.etaxonomy.cdm.strategy.cache.TaggedText;
40
41 /**
42 * @author AM
43 */
44 public abstract class NameCacheStrategyBase
45 extends StrategyBase
46 implements INameCacheStrategy {
47 private static final long serialVersionUID = -2322348388258675517L;
48
49 private static final Logger logger = Logger.getLogger(NameCacheStrategyBase.class);
50
51 final static UUID uuid = UUID.fromString("817ae5b5-3ac2-414b-a134-a9ae86cba040");
52
53 /**
54 * Constructor
55 */
56 public NameCacheStrategyBase() {
57 super();
58 }
59
60
61 @Override
62 public String getFullTitleCache(TaxonName taxonName, HTMLTagRules htmlTagRules) {
63 List<TaggedText> tags = getTaggedFullTitle(taxonName);
64 if (tags == null){
65 return null;
66 }else{
67 String result = createString(tags, htmlTagRules);
68 return result;
69 }
70 }
71
72 @Override
73 public String getFullTitleCache(TaxonName taxonName) {
74 return getFullTitleCache(taxonName, null);
75 }
76
77
78 /**
79 * @param nonViralName
80 * @param tags
81 * @return
82 */
83 @Override
84 public List<TaggedText> getNomStatusTags(TaxonName nonViralName, boolean includeSeparatorBefore,
85 boolean includeSeparatorAfter) {
86
87 Set<NomenclaturalStatus> ncStati = nonViralName.getStatus();
88 Iterator<NomenclaturalStatus> iterator = ncStati.iterator();
89 List<TaggedText> nomStatusTags = new ArrayList<>();
90 while (iterator.hasNext()) {
91 NomenclaturalStatus ncStatus = iterator.next();
92 // since the NewInstance method of nomencatural status allows null as parameter
93 // we have to check for null values here
94 String nomStatusStr = "not defined";
95 if(ncStatus.getType() != null){
96 NomenclaturalStatusType statusType = ncStatus.getType();
97 Language lang = Language.LATIN();
98 Representation repr = statusType.getRepresentation(lang);
99 if (repr != null){
100 nomStatusStr = repr.getAbbreviatedLabel();
101 }else{
102 String message = "No latin representation available for nom. status. " + statusType.getTitleCache();
103 logger.warn(message);
104 throw new IllegalStateException(message);
105 }
106 }else if(StringUtils.isNotBlank(ncStatus.getRuleConsidered())){
107 nomStatusStr = ncStatus.getRuleConsidered();
108 }
109 String statusSeparator = ", ";
110 if (includeSeparatorBefore){
111 nomStatusTags.add(new TaggedText(TagEnum.separator, statusSeparator));
112 }
113 nomStatusTags.add(new TaggedText(TagEnum.nomStatus, nomStatusStr));
114 if (includeSeparatorAfter){
115 nomStatusTags.add(new TaggedText(TagEnum.postSeparator, ","));
116 }
117 }
118 return nomStatusTags;
119 }
120
121
122 /**
123 * Generates and returns the "name cache" (only scientific name without author teams and year).
124 * @see eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy#getNameCache(eu.etaxonomy.cdm.model.name.TaxonName)
125 */
126 @Override
127 public String getNameCache(TaxonName nonViralName) {
128 List<TaggedText> tags = getTaggedName(nonViralName);
129 if (tags == null){
130 return null;
131 }else{
132 String result = createString(tags);
133 return result;
134 }
135 }
136
137
138 /**
139 * Generates and returns the title cache of the given name.
140 * The title cache in general includes the name and the authorship and year for some types of names.
141 *
142 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTitleCache(eu.etaxonomy.cdm.model.common.CdmBase)
143 * @see eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy#getTitleCache(eu.etaxonomy.cdm.model.common.IdentifiableEntity)
144 */
145 @Override
146 public String getTitleCache(TaxonName nonViralName) {
147 return getTitleCache(nonViralName, null);
148 }
149
150 @Override
151 public String getTitleCache(TaxonName nonViralName, HTMLTagRules htmlTagRules) {
152 List<TaggedText> tags = getTaggedTitle(nonViralName);
153 if (tags == null){
154 return null;
155 }else{
156 String result = createString(tags, htmlTagRules);
157 return result;
158 }
159 }
160
161 @Override
162 public List<TaggedText> getTaggedTitle(TaxonName taxonName) {
163 if (taxonName == null){
164 return null;
165 }
166 //TODO how to handle protected fullTitleCache here?
167
168 if (taxonName.isProtectedTitleCache()){
169 //protected title cache
170 List<TaggedText> tags = new ArrayList<>();
171 tags.add(new TaggedText(TagEnum.name, taxonName.getTitleCache()));
172 return tags;
173 }else{
174 return doGetTaggedTitle(taxonName);
175 }
176
177 }
178
179 protected abstract List<TaggedText> doGetTaggedTitle(TaxonName taxonName);
180
181 @Override
182 public List<TaggedText> getTaggedFullTitle(TaxonName nonViralName) {
183 List<TaggedText> tags = new ArrayList<>();
184
185 //null
186 if (nonViralName == null){
187 return null;
188 }
189
190 //protected full title cache
191 if (nonViralName.isProtectedFullTitleCache()){
192 tags.add(new TaggedText(TagEnum.fullName, nonViralName.getFullTitleCache()));
193 return tags;
194 }
195
196 //title cache
197 // String titleCache = nonViralName.getTitleCache();
198 List<TaggedText> titleTags = getTaggedTitle(nonViralName);
199 tags.addAll(titleTags);
200
201 //reference
202 String microReference = nonViralName.getNomenclaturalMicroReference();
203 INomenclaturalReference ref = nonViralName.getNomenclaturalReference();
204 String referenceCache = null;
205 if (ref != null){
206 Reference reference = HibernateProxyHelper.deproxy(ref, Reference.class);
207 referenceCache = reference.getNomenclaturalCitation(microReference);
208 }
209 //add to tags
210 if (StringUtils.isNotBlank(referenceCache)){
211 if (! referenceCache.trim().startsWith("in ")){
212 String refConcat = ", ";
213 tags.add(new TaggedText(TagEnum.separator, refConcat));
214 }
215 tags.add(new TaggedText(TagEnum.reference, referenceCache));
216 }
217
218 addOriginalSpelling(tags, nonViralName);
219
220 //nomenclatural status
221 tags.addAll(getNomStatusTags(nonViralName, true, false));
222 return tags;
223
224 }
225
226 protected void addOriginalSpelling(List<TaggedText> tags, ITaxonNameBase name){
227 String originalName = getOriginalNameString(name, tags);
228 if (StringUtils.isNotBlank(originalName)){
229 tags.add(new TaggedText(TagEnum.name, originalName));
230 }
231 }
232
233 private String getOriginalNameString(ITaxonNameBase currentName, List<TaggedText> originalNameTaggs) {
234 List<String> originalNameStrings = new ArrayList<>(1);
235 currentName = CdmBase.deproxy(currentName);
236 //Hibernate.initialize(currentName.getRelationsToThisName());
237 for (NameRelationship nameRel : currentName.getRelationsToThisName()){ //handle list, just in case we have strange data; this may result in strange looking results
238 NameRelationshipType type = nameRel.getType();
239 if(type != null && type.equals(NameRelationshipType.ORIGINAL_SPELLING())){
240 String originalNameString;
241 TaxonName originalName = nameRel.getFromName();
242 if (!originalName.isNonViral()){
243 originalNameString = originalName.getTitleCache();
244 }else{
245 INonViralName originalNvName = CdmBase.deproxy(originalName);
246 originalNameString = makeOriginalNameString(currentName, originalNvName, originalNameTaggs);
247 }
248 originalNameStrings.add("[as " + UTF8.QUOT_DBL_LOW9 + originalNameString + UTF8.QUOT_DBL_LEFT + "]");
249 }
250 }
251 if (originalNameStrings.size() > 0){
252 String result = CdmUtils.concat("", originalNameStrings.toArray(new String[originalNameStrings.size()])) ;
253 return result;
254 }else{
255 return null;
256 }
257 }
258
259 private String makeOriginalNameString(ITaxonNameBase currentName, INonViralName originalName,
260 List<TaggedText> currentNameTags) {
261 //use cache if necessary
262 String cacheToUse = null;
263 if (originalName.isProtectedNameCache() && StringUtils.isNotBlank(originalName.getNameCache())){
264 cacheToUse = originalName.getNameCache();
265 }else if (originalName.isProtectedTitleCache() && StringUtils.isNotBlank(originalName.getTitleCache())){
266 cacheToUse = originalName.getTitleCache();
267 }else if (originalName.isProtectedFullTitleCache() && StringUtils.isNotBlank(originalName.getFullTitleCache())){
268 cacheToUse = originalName.getFullTitleCache();
269 }
270 if (cacheToUse != null){
271 return cacheToUse;
272 }
273 //use atomized data
274 //get originalNameParts array
275 String originalNameString = originalName.getNameCache();
276 if (originalNameString == null){
277 originalNameString = originalName.getTitleCache();
278 }
279 if (originalNameString == null){ //should not happen
280 originalNameString = originalName.getFullTitleCache();
281 }
282 String[] originalNameSplit = originalNameString.split("\\s+");
283
284 //get current name parts
285 String currentNameString = createString(currentNameTags);
286 String[] currentNameSplit = currentNameString.split("\\s+");
287
288 //compute string
289 String result = originalNameString;
290 for (int i = 0; i < Math.min(originalNameSplit.length, currentNameSplit.length); i++){
291 if (originalNameSplit[i].equals(currentNameSplit[i])){
292 result = result.replaceFirst(originalNameSplit[i], "").trim();
293 }
294 }
295 //old
296 // if (originalName.getGenusOrUninomial() != null && originalName.getGenusOrUninomial().equals(currentName.getGenusOrUninomial())){
297 //
298 // }
299 return result;
300 }
301
302 /**
303 * @param tags
304 * @return
305 */
306 protected String createString(List<TaggedText> tags) {
307 return TaggedCacheHelper.createString(tags);
308 }
309
310 /**
311 * @param tags
312 * @param htmlTagRules
313 * @return
314 */
315 protected String createString(List<TaggedText> tags, HTMLTagRules htmlTagRules) {
316 return TaggedCacheHelper.createString(tags, htmlTagRules);
317 }
318
319 }