(no commit message)
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / strategy / cache / name / NonViralNameDefaultCacheStrategy.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.log4j.Logger;
18
19 import eu.etaxonomy.cdm.common.CdmUtils;
20 import eu.etaxonomy.cdm.model.agent.INomenclaturalAuthor;
21 import eu.etaxonomy.cdm.model.agent.Team;
22 import eu.etaxonomy.cdm.model.common.Language;
23 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
24 import eu.etaxonomy.cdm.model.name.NonViralName;
25 import eu.etaxonomy.cdm.model.name.Rank;
26 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
27
28
29 /**
30 * This class is a default implementation for the INonViralNameCacheStrategy<T extends NonViralName> interface.
31 * The method actually implements a cache strategy for botanical names so no method has to be overwritten by
32 * a subclass for botanic names.
33 * Where differing from this Default BotanicNameCacheStrategy other subclasses should overwrite the existing methods
34 * e.g. a CacheStrategy for zoological names should overwrite getAuthorAndExAuthor
35 * @author a.mueller
36 */
37 /**
38 * @author AM
39 *
40 * @param <T>
41 */
42 public class NonViralNameDefaultCacheStrategy<T extends NonViralName> extends NameCacheStrategyBase<T> implements INonViralNameCacheStrategy<T> {
43 private static final Logger logger = Logger.getLogger(NonViralNameDefaultCacheStrategy.class);
44
45 final static UUID uuid = UUID.fromString("1cdda0d1-d5bc-480f-bf08-40a510a2f223");
46
47 protected String NameAuthorSeperator = " ";
48 protected String BasionymStart = "(";
49 protected String BasionymEnd = ")";
50 protected String ExAuthorSeperator = " ex ";
51 protected CharSequence BasionymAuthorCombinationAuthorSeperator = " ";
52
53 @Override
54 public UUID getUuid(){
55 return uuid;
56 }
57
58
59 /**
60 * Factory method
61 * @return NonViralNameDefaultCacheStrategy A new instance of NonViralNameDefaultCacheStrategy
62 */
63 public static NonViralNameDefaultCacheStrategy NewInstance(){
64 return new NonViralNameDefaultCacheStrategy();
65 }
66
67 /**
68 * Constructor
69 */
70 protected NonViralNameDefaultCacheStrategy(){
71 super();
72 }
73
74 /* **************** GETTER / SETTER **************************************/
75
76 /**
77 * String that separates the NameCache part from the AuthorCache part
78 * @return
79 */
80 public String getNameAuthorSeperator() {
81 return NameAuthorSeperator;
82 }
83
84
85 public void setNameAuthorSeperator(String nameAuthorSeperator) {
86 NameAuthorSeperator = nameAuthorSeperator;
87 }
88
89
90 /**
91 * String the basionym author part starts with e.g. '('.
92 * This should correspond with the {@link NonViralNameDefaultCacheStrategy#getBasionymEnd() basionymEnd} attribute
93 * @return
94 */
95 public String getBasionymStart() {
96 return BasionymStart;
97 }
98
99
100 public void setBasionymStart(String basionymStart) {
101 BasionymStart = basionymStart;
102 }
103
104
105 /**
106 * String the basionym author part ends with e.g. ')'.
107 * This should correspond with the {@link NonViralNameDefaultCacheStrategy#getBasionymStart() basionymStart} attribute
108 * @return
109 */
110 public String getBasionymEnd() {
111 return BasionymEnd;
112 }
113
114
115 public void setBasionymEnd(String basionymEnd) {
116 BasionymEnd = basionymEnd;
117 }
118
119
120 /**
121 * String to seperate ex author from author.
122 * @return
123 */
124 public String getExAuthorSeperator() {
125 return ExAuthorSeperator;
126 }
127
128
129 public void setExAuthorSeperator(String exAuthorSeperator) {
130 ExAuthorSeperator = exAuthorSeperator;
131 }
132
133
134 /**
135 * String that seperates the basionym/original_combination author part from the combination author part
136 * @return
137 */
138 public CharSequence getBasionymAuthorCombinationAuthorSeperator() {
139 return BasionymAuthorCombinationAuthorSeperator;
140 }
141
142
143 public void setBasionymAuthorCombinationAuthorSeperator(
144 CharSequence basionymAuthorCombinationAuthorSeperator) {
145 BasionymAuthorCombinationAuthorSeperator = basionymAuthorCombinationAuthorSeperator;
146 }
147
148
149 //** *****************************************************************************************/
150
151
152 /* (non-Javadoc)
153 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getNameCache()
154 */
155 @Override
156 public String getTitleCache(T nonViralName) {
157 if (nonViralName == null){
158 return null;
159 }
160 String result = "";
161 if (isAutonym(nonViralName)){
162 String speciesPart = getSpeciesNameCache(nonViralName);
163 //TODO should this include basionym authors and ex authors
164 INomenclaturalAuthor author = nonViralName.getCombinationAuthorTeam();
165 String authorPart = "";
166 if (author != null){
167 authorPart = CdmUtils.Nz(author.getNomenclaturalTitle());
168 }
169 INomenclaturalAuthor basAuthor = nonViralName.getBasionymAuthorTeam();
170 String basAuthorPart = "";
171 if (basAuthor != null){
172 basAuthorPart = CdmUtils.Nz(basAuthor.getNomenclaturalTitle());
173 }
174 if (! "".equals(basAuthorPart)){
175 authorPart = "("+ basAuthorPart +")" + authorPart;
176 }
177 String infraSpeciesPart = (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet()));
178 result = CdmUtils.concat(" ", new String[]{speciesPart, authorPart, infraSpeciesPart});
179 result = result.trim().replace("null", "");
180 }else{
181 String nameCache = CdmUtils.Nz(getNameCache(nonViralName));
182 String authorCache = CdmUtils.Nz(getAuthorshipCache(nonViralName));
183 result = CdmUtils.concat(NameAuthorSeperator, nameCache, authorCache);
184 }
185 return result;
186 }
187
188
189 @Override
190 public String getFullTitleCache(T nonViralName) {
191 //null
192 if (nonViralName == null){
193 return null;
194 }
195 //full title cache
196 if (nonViralName.isProtectedFullTitleCache() == true) {
197 return nonViralName.getFullTitleCache();
198 }
199
200 String result = "";
201 //title cache
202 String titleCache = getTitleCache(nonViralName);
203
204 String microReference = nonViralName.getNomenclaturalMicroReference();
205 INomenclaturalReference<?> ref = nonViralName.getNomenclaturalReference();
206 String referenceBaseCache = null;
207 if (ref != null){
208 referenceBaseCache = ref.getNomenclaturalCitation(microReference);
209 }
210
211 //make nomenclatural status
212 String ncStatusCache = "";
213 Set<NomenclaturalStatus> ncStati = nonViralName.getStatus();
214 Iterator<NomenclaturalStatus> iterator = ncStati.iterator();
215 while (iterator.hasNext()) {
216 NomenclaturalStatus ncStatus = (NomenclaturalStatus)iterator.next();
217 ncStatusCache = ", " + ncStatus.getType().getRepresentation(Language.LATIN()).getAbbreviatedLabel();
218 }
219 String refConcat = " ";
220 if (referenceBaseCache != null && ! referenceBaseCache.trim().startsWith("in ")){
221 refConcat = ", ";
222 }
223 result = CdmUtils.concat(refConcat, titleCache, referenceBaseCache);
224 result = CdmUtils.concat("", result, ncStatusCache);
225 return result;
226 }
227
228
229 /**
230 * Generates and returns the "name cache" (only scientific name without author teams and year).
231 * @see eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy#getNameCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)
232 */
233 public String getNameCache(T nonViralName) {
234 if (nonViralName == null){
235 return null;
236 }
237 String result;
238 Rank rank = nonViralName.getRank();
239
240 if (rank == null){
241 result = getRanklessNameCache(nonViralName);
242 }else if (rank.isInfraSpecific()){
243 result = getInfraSpeciesNameCache(nonViralName);
244 }else if (rank.isSpecies()){
245 result = getSpeciesNameCache(nonViralName);
246 }else if (rank.isInfraGeneric()){
247 result = getInfraGenusNameCache(nonViralName);
248 }else if (rank.isGenus()){
249 result = getGenusOrUninomialNameCache(nonViralName);
250 }else if (rank.isSupraGeneric()){
251 result = getGenusOrUninomialNameCache(nonViralName);
252 }else{
253 logger.warn("Name Strategy for Name (UUID: " + nonViralName.getUuid() + ") not yet implemented");
254 result = "";
255 }
256 return result;
257 }
258
259
260 /* (non-Javadoc)
261 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy#getAuthorCache(eu.etaxonomy.cdm.model.name.NonViralName)
262 */
263 public String getAuthorshipCache(T nonViralName) {
264 if (nonViralName == null){
265 return null;
266 }
267 //cache protected
268 if (nonViralName.isProtectedAuthorshipCache() == true) {
269 return nonViralName.getAuthorshipCache();
270 }
271
272 String result = "";
273 INomenclaturalAuthor combinationAuthor = nonViralName.getCombinationAuthorTeam();
274 INomenclaturalAuthor exCombinationAuthor = nonViralName.getExCombinationAuthorTeam();
275 INomenclaturalAuthor basionymAuthor = nonViralName.getBasionymAuthorTeam();
276 INomenclaturalAuthor exBasionymAuthor = nonViralName.getExBasionymAuthorTeam();
277 String basionymPart = "";
278 String authorPart = "";
279 //basionym
280 if (basionymAuthor != null || exBasionymAuthor != null){
281 basionymPart = BasionymStart + getAuthorAndExAuthor(basionymAuthor, exBasionymAuthor) + BasionymEnd;
282 }
283 if (combinationAuthor != null || exCombinationAuthor != null){
284 authorPart = getAuthorAndExAuthor(combinationAuthor, exCombinationAuthor);
285 }
286 result = CdmUtils.concat(BasionymAuthorCombinationAuthorSeperator, basionymPart, authorPart);
287 return result;
288 }
289
290 /**
291 * Returns the AuthorCache part for a combination of an author and an ex author. This applies on combination authors
292 * as well as on basionym/orginal combination authors.
293 * @param author the author
294 * @param exAuthor the ex-author
295 * @return
296 */
297 protected String getAuthorAndExAuthor(INomenclaturalAuthor author, INomenclaturalAuthor exAuthor){
298 String result = "";
299 String authorString = "";
300 String exAuthorString = "";
301 if (author != null){
302 authorString = CdmUtils.Nz(author.getNomenclaturalTitle());
303 }
304 if (exAuthor != null){
305 exAuthorString = CdmUtils.Nz(exAuthor.getNomenclaturalTitle());
306 }
307 if (exAuthorString.length() > 0 ){
308 exAuthorString = exAuthorString + ExAuthorSeperator;
309 }
310 result = exAuthorString + authorString;
311 return result;
312
313 }
314
315
316 /* (non-Javadoc)
317 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTaggedName(eu.etaxonomy.cdm.model.common.CdmBase)
318 */
319 @Override
320 public List<Object> getTaggedName(T nonViralName) {
321 List<Object> tags = new ArrayList<Object>();
322 tags.add(nonViralName.getGenusOrUninomial());
323 if (nonViralName.isSpecies() || nonViralName.isInfraSpecific()){
324 tags.add(nonViralName.getSpecificEpithet());
325 }
326
327 // No autonym
328 if (nonViralName.isInfraSpecific() && ! nonViralName.getSpecificEpithet().equals(nonViralName.getInfraSpecificEpithet())){
329 tags.add(nonViralName.getRank());
330 tags.add(nonViralName.getInfraSpecificEpithet());
331 }
332
333 if (nonViralName.isInfraGeneric()){
334 //TODO choose right strategy or generic approach?
335 // --- strategy 1 ---
336 tags.add(nonViralName.getRank());
337 tags.add(nonViralName.getInfraGenericEpithet());
338 // --- strategy 2 ---
339 // tags.add('('+nvn.getInfraGenericEpithet()+')');
340 }
341 Team authorTeam = Team.NewInstance();
342 authorTeam.setProtectedTitleCache(true);
343 authorTeam.setTitleCache(nonViralName.getAuthorshipCache());
344 tags.add(authorTeam);
345
346 // Name is an autonym. Rank and infraspecific eitheton follow the author
347 if (nonViralName.isInfraSpecific() && nonViralName.getSpecificEpithet().equals(nonViralName.getInfraSpecificEpithet())){
348 tags.add(nonViralName.getRank());
349 tags.add(nonViralName.getInfraSpecificEpithet());
350 }
351
352 if(! "".equals(nonViralName.getAppendedPhrase())){
353 tags.add(nonViralName.getAppendedPhrase());
354 }
355
356 return tags;
357 }
358
359
360 /************** PRIVATES ****************/
361
362 protected String getRanklessNameCache(NonViralName nonViralName){
363 String result = "";
364 result = (result + (nonViralName.getGenusOrUninomial())).trim().replace("null", "-");
365 result += " " + (CdmUtils.Nz(nonViralName.getSpecificEpithet())).trim();
366 result += " " + (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet())).trim();
367 result = result.trim().replace("null", "-");
368 //result += " (rankless)";
369 result = addAppendedPhrase(result, nonViralName);
370 return result;
371 }
372
373
374 protected String getGenusOrUninomialNameCache(NonViralName nonViralName){
375 String result;
376 result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());
377 result = addAppendedPhrase(result, nonViralName);
378 return result;
379 }
380
381 protected String getInfraGenusNameCache(NonViralName nonViralName){
382 String result;
383 result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());
384 result += " (" + (CdmUtils.Nz(nonViralName.getInfraGenericEpithet()) + ")").trim().replace("null", "");
385 result = addAppendedPhrase(result, nonViralName);
386 return result;
387 }
388
389
390 protected String getSpeciesNameCache(NonViralName nonViralName){
391 String result;
392 result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());
393 result += " " + CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim().replace("null", "");
394 result = addAppendedPhrase(result, nonViralName);
395 return result;
396 }
397
398
399 protected String getInfraSpeciesNameCache(NonViralName nonViralName){
400 String result;
401 result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());
402 result += " " + (CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim()).replace("null", "");
403 if (! isAutonym(nonViralName)){
404 result += " " + (nonViralName.getRank().getAbbreviation()).trim().replace("null", "");
405 }
406 result += " " + (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet())).trim().replace("null", "");
407 result = addAppendedPhrase(result, nonViralName);
408 return result;
409 }
410
411
412 /**
413 * @param name
414 * @return true, if name has Rank, Rank is below species and species epithet equals infraSpeciesEpithtet, else false
415 */
416 protected boolean isAutonym(NonViralName nonViralName){
417 if (nonViralName != null && nonViralName.getRank() != null && nonViralName.getSpecificEpithet() != null && nonViralName.getInfraSpecificEpithet() != null &&
418 nonViralName.getRank().isInfraSpecific() && nonViralName.getSpecificEpithet().trim().equals(nonViralName.getInfraSpecificEpithet().trim())){
419 return true;
420 }else{
421 return false;
422 }
423 }
424
425 protected String addAppendedPhrase(String resultString, NonViralName nonViralName){
426 String appendedPhrase = nonViralName ==null ? null : nonViralName.getAppendedPhrase();
427 if (resultString == null){
428 return appendedPhrase;
429 }else if(appendedPhrase == null || "".equals(appendedPhrase.trim())) {
430 return resultString;
431 }else if ("".equals(resultString)){
432 return resultString + appendedPhrase;
433 }else {
434 return resultString + " " + appendedPhrase;
435 }
436 }
437
438 }