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