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