Project

General

Profile

Download (19.5 KB) Statistics
| Branch: | Tag: | Revision:
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.hibernate.HibernateProxyHelper;
21
import eu.etaxonomy.cdm.model.agent.INomenclaturalAuthor;
22
import eu.etaxonomy.cdm.model.agent.Team;
23
import eu.etaxonomy.cdm.model.common.Language;
24
import eu.etaxonomy.cdm.model.common.Representation;
25
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
26
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
27
import eu.etaxonomy.cdm.model.name.NonViralName;
28
import eu.etaxonomy.cdm.model.name.Rank;
29
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
30
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
31

    
32

    
33
/**
34
 * This class is a default implementation for the INonViralNameCacheStrategy<T extends NonViralName> interface.
35
 * The method actually implements a cache strategy for botanical names so no method has to be overwritten by
36
 * a subclass for botanic names.
37
 * Where differing from this Default BotanicNameCacheStrategy other subclasses should overwrite the existing methods
38
 * e.g. a CacheStrategy for zoological names should overwrite getAuthorAndExAuthor
39
 * @author a.mueller
40
 */
41
/**
42
 * @author AM
43
 *
44
 * @param <T>
45
 */
46
public class NonViralNameDefaultCacheStrategy<T extends NonViralName> extends NameCacheStrategyBase<T> implements INonViralNameCacheStrategy<T> {
47
	private static final Logger logger = Logger.getLogger(NonViralNameDefaultCacheStrategy.class);
48
	
49
	final static UUID uuid = UUID.fromString("1cdda0d1-d5bc-480f-bf08-40a510a2f223");
50
	
51
	protected String NameAuthorSeperator = " ";
52
	protected String BasionymStart = "(";
53
	protected String BasionymEnd = ")";
54
	protected String ExAuthorSeperator = " ex ";
55
	protected CharSequence BasionymAuthorCombinationAuthorSeperator = " ";
56
	
57
	@Override
58
	public  UUID getUuid(){
59
		return uuid;
60
	}
61

    
62
	
63
	/**
64
	 * Factory method
65
	 * @return NonViralNameDefaultCacheStrategy A new instance of  NonViralNameDefaultCacheStrategy
66
	 */
67
	public static NonViralNameDefaultCacheStrategy NewInstance(){
68
		return new NonViralNameDefaultCacheStrategy();
69
	}
70
	
71
	/**
72
	 * Constructor
73
	 */
74
	protected NonViralNameDefaultCacheStrategy(){
75
		super();
76
	}
77

    
78
/* **************** GETTER / SETTER **************************************/
79
	
80
	/**
81
	 * String that separates the NameCache part from the AuthorCache part
82
	 * @return
83
	 */
84
	public String getNameAuthorSeperator() {
85
		return NameAuthorSeperator;
86
	}
87

    
88

    
89
	public void setNameAuthorSeperator(String nameAuthorSeperator) {
90
		NameAuthorSeperator = nameAuthorSeperator;
91
	}
92

    
93

    
94
	/**
95
	 * String the basionym author part starts with e.g. '('.
96
	 * This should correspond with the {@link NonViralNameDefaultCacheStrategy#getBasionymEnd() basionymEnd} attribute
97
	 * @return
98
	 */
99
	public String getBasionymStart() {
100
		return BasionymStart;
101
	}
102

    
103

    
104
	public void setBasionymStart(String basionymStart) {
105
		BasionymStart = basionymStart;
106
	}
107

    
108

    
109
	/**
110
	 * String the basionym author part ends with e.g. ')'.
111
	 * This should correspond with the {@link NonViralNameDefaultCacheStrategy#getBasionymStart() basionymStart} attribute
112
	 * @return
113
	 */
114
	public String getBasionymEnd() {
115
		return BasionymEnd;
116
	}
117

    
118

    
119
	public void setBasionymEnd(String basionymEnd) {
120
		BasionymEnd = basionymEnd;
121
	}
122

    
123

    
124
	/**
125
	 * String to seperate ex author from author.
126
	 * @return
127
	 */
128
	public String getExAuthorSeperator() {
129
		return ExAuthorSeperator;
130
	}
131

    
132

    
133
	public void setExAuthorSeperator(String exAuthorSeperator) {
134
		ExAuthorSeperator = exAuthorSeperator;
135
	}
136

    
137

    
138
	/**
139
	 * String that seperates the basionym/original_combination author part from the combination author part
140
	 * @return
141
	 */
142
	public CharSequence getBasionymAuthorCombinationAuthorSeperator() {
143
		return BasionymAuthorCombinationAuthorSeperator;
144
	}
145

    
146

    
147
	public void setBasionymAuthorCombinationAuthorSeperator(
148
			CharSequence basionymAuthorCombinationAuthorSeperator) {
149
		BasionymAuthorCombinationAuthorSeperator = basionymAuthorCombinationAuthorSeperator;
150
	}
151

    
152
	
153
//** *****************************************************************************************/
154
	
155
	
156
	/* (non-Javadoc)
157
	 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getNameCache()
158
	 */
159
	@Override
160
	public String getTitleCache(T nonViralName) {
161
		if (nonViralName == null){
162
			return null;
163
		}
164
		
165
		if (nonViralName.isProtectedTitleCache()){
166
			return nonViralName.getTitleCache();
167
		}
168
		String result = "";
169
		//Autonym
170
		if (isAutonym(nonViralName)){
171
			String speciesPart = getSpeciesNameCache(nonViralName);
172
			//TODO should this include basionym authors and ex authors
173
			INomenclaturalAuthor author = nonViralName.getCombinationAuthorTeam();
174
			String authorPart = "";
175
			if (author != null){
176
				authorPart = CdmUtils.Nz(author.getNomenclaturalTitle());
177
			}
178
			INomenclaturalAuthor basAuthor = nonViralName.getBasionymAuthorTeam();
179
			String basAuthorPart = "";
180
			if (basAuthor != null){
181
				basAuthorPart = CdmUtils.Nz(basAuthor.getNomenclaturalTitle());
182
			}
183
			if (! "".equals(basAuthorPart)){
184
				authorPart = "("+ basAuthorPart +")" + authorPart;
185
			}
186
			String infraSpeciesPart = (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet()));
187

    
188
			String infraSpeciesSeparator = "";
189
			if (nonViralName.getRank() == null || !nonViralName.getRank().isInfraSpecific()){
190
				//TODO handle exception
191
				logger.warn("Rank for autonym does not exist or is not lower than species !!");
192
			}else{
193
				infraSpeciesSeparator = nonViralName.getRank().getAbbreviation();
194
			}
195
			
196
			result = CdmUtils.concat(" ", new String[]{speciesPart, authorPart, infraSpeciesSeparator, infraSpeciesPart});
197
			result = result.trim().replace("null", "");
198
		}else{ //not Autonym
199
			String nameCache = nonViralName.getNameCache();  //OLD: CdmUtils.Nz(getNameCache(nonViralName));
200
			if (nameIncludesAuthorship(nonViralName)){
201
				String authorCache = CdmUtils.Nz(getAuthorshipCache(nonViralName));
202
				result = CdmUtils.concat(NameAuthorSeperator, nameCache, authorCache);
203
			}else{
204
				result = nameCache;
205
			}
206
		}
207
		return result;
208
	}
209
	
210
	protected boolean nameIncludesAuthorship(NonViralName nonViralName){
211
		Rank rank = nonViralName.getRank();
212
		if (rank != null && rank.isSpeciesAggregate()){
213
			return false;
214
		}else{
215
			return true;
216
		}
217
	}
218
	
219
	
220

    
221
	
222
	
223
	@Override
224
	public String getFullTitleCache(T nonViralName) {
225
		//null
226
		if (nonViralName == null){
227
			return null;
228
		}
229
		//full title cache
230
		if (nonViralName.isProtectedFullTitleCache() == true) {
231
			return nonViralName.getFullTitleCache();
232
		}
233
		
234
		String result = "";
235
		//title cache
236
		String titleCache = nonViralName.getTitleCache();   // OLD: getTitleCache(nonViralName);
237
		
238
		String microReference = nonViralName.getNomenclaturalMicroReference();
239
		INomenclaturalReference ref = nonViralName.getNomenclaturalReference();
240
		String referenceBaseCache = null;
241
		if (ref != null){
242
			INomenclaturalReference nomenclaturalReference = HibernateProxyHelper.deproxy(ref, INomenclaturalReference.class);
243
			nomenclaturalReference.setCacheStrategy(nomenclaturalReference.getType().getCacheStrategy());
244
			referenceBaseCache = nomenclaturalReference.getNomenclaturalCitation(microReference);
245
		}
246
		
247
		//make nomenclatural status
248
		String ncStatusCache = "";
249
		Set<NomenclaturalStatus> ncStati = nonViralName.getStatus();
250
		Iterator<NomenclaturalStatus> iterator = ncStati.iterator();
251
		while (iterator.hasNext()) {
252
			NomenclaturalStatus ncStatus = (NomenclaturalStatus)iterator.next();
253
			// since the NewInstance method of nomencatural status allows null as parameter
254
			// we have to check for null values here
255
			String suffix = "not defined";
256
			if(ncStatus.getType() != null){
257
				NomenclaturalStatusType statusType =  ncStatus.getType();
258
				Language lang = Language.LATIN();
259
				Representation repr = statusType.getRepresentation(lang);
260
				if (repr != null){
261
					suffix = repr.getAbbreviatedLabel();
262
				}else{
263
					String message = "No latin representation available for nom. status. " + statusType.getTitleCache();
264
					logger.warn(message);
265
					throw new IllegalStateException(message);
266
				}
267
			}else if(ncStatus.getRuleConsidered() != null && ! ncStatus.getRuleConsidered().equals("")){
268
				suffix = ncStatus.getRuleConsidered();
269
			}
270
			ncStatusCache = ", " + suffix;
271
		}
272
		String refConcat = " ";
273
		if (referenceBaseCache != null && ! referenceBaseCache.trim().startsWith("in ")){
274
			refConcat = ", ";
275
		}
276
		result = CdmUtils.concat(refConcat, titleCache, referenceBaseCache);
277
		result = CdmUtils.concat("", result, ncStatusCache);
278
		return result;
279
	}
280
	
281
	
282
	/**
283
	 * Generates and returns the "name cache" (only scientific name without author teams and year).
284
	 * @see eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy#getNameCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)
285
	 */
286
	public String getNameCache(T nonViralName) {
287
		if (nonViralName == null){
288
			return null;
289
		}
290
		String result;
291
		Rank rank = nonViralName.getRank();
292
		
293
		if (nonViralName.isProtectedNameCache()){
294
			result = nonViralName.getNameCache();
295
		}else if (rank == null){
296
			result = getRanklessNameCache(nonViralName);
297
		}else if (rank.isInfraSpecific()){
298
			result = getInfraSpeciesNameCache(nonViralName);
299
		}else if (rank.isSpecies()){
300
			result = getSpeciesNameCache(nonViralName);
301
		}else if (rank.isInfraGeneric()){
302
			result = getInfraGenusNameCache(nonViralName);
303
		}else if (rank.isGenus()){
304
			result = getGenusOrUninomialNameCache(nonViralName);
305
		}else if (rank.isSupraGeneric()){
306
			result = getGenusOrUninomialNameCache(nonViralName);
307
		}else{ 
308
			logger.warn("Name Strategy for Name (UUID: " + nonViralName.getUuid() +  ") not yet implemented");
309
			result = "";
310
		}
311
		return result;
312
	}
313
	
314

    
315
	/* (non-Javadoc)
316
	 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy#getAuthorCache(eu.etaxonomy.cdm.model.name.NonViralName)
317
	 */
318
	public String getAuthorshipCache(T nonViralName) {
319
		if (nonViralName == null){
320
			return null;
321
		}
322
		//cache protected
323
		if (nonViralName.isProtectedAuthorshipCache() == true) {
324
			return nonViralName.getAuthorshipCache();
325
		}
326
		return getNonCacheAuthorshipCache(nonViralName);
327

    
328
	}
329
	
330
	/**
331
	 * Returns the authorshipcache string for the atomized authorship fields. Does not use the authorshipfield.
332
	 * @throws NullPointerException if nonViralName is null.
333
	 * @param nonViralName
334
	 * @return
335
	 */
336
	protected String getNonCacheAuthorshipCache(T nonViralName){
337
		String result = "";
338
		INomenclaturalAuthor combinationAuthor = nonViralName.getCombinationAuthorTeam();
339
		INomenclaturalAuthor exCombinationAuthor = nonViralName.getExCombinationAuthorTeam();
340
		INomenclaturalAuthor basionymAuthor = nonViralName.getBasionymAuthorTeam();
341
		INomenclaturalAuthor exBasionymAuthor = nonViralName.getExBasionymAuthorTeam();
342
		String basionymPart = "";
343
		String authorPart = "";
344
		//basionym
345
		if (basionymAuthor != null || exBasionymAuthor != null){
346
			basionymPart = BasionymStart + getAuthorAndExAuthor(basionymAuthor, exBasionymAuthor) + BasionymEnd;
347
		}
348
		if (combinationAuthor != null || exCombinationAuthor != null){
349
			authorPart = getAuthorAndExAuthor(combinationAuthor, exCombinationAuthor);
350
		}
351
		result = CdmUtils.concat(BasionymAuthorCombinationAuthorSeperator, basionymPart, authorPart);
352
		return result;
353
	}
354
	
355
	/**
356
	 * Returns the AuthorCache part for a combination of an author and an ex author. This applies on combination authors
357
	 * as well as on basionym/orginal combination authors.
358
	 * @param author the author
359
	 * @param exAuthor the ex-author
360
	 * @return
361
	 */
362
	protected String getAuthorAndExAuthor(INomenclaturalAuthor author, INomenclaturalAuthor exAuthor){
363
		String result = "";
364
		String authorString = "";
365
		String exAuthorString = "";
366
		if (author != null){
367
			authorString = CdmUtils.Nz(author.getNomenclaturalTitle());
368
		}
369
		if (exAuthor != null){
370
			exAuthorString = CdmUtils.Nz(exAuthor.getNomenclaturalTitle());
371
		}
372
		if (exAuthorString.length() > 0 ){
373
			exAuthorString = exAuthorString + ExAuthorSeperator;
374
		}
375
		result = exAuthorString + authorString;
376
		return result;
377
 
378
	}
379
	
380
	
381
	/* (non-Javadoc)
382
	 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTaggedName(eu.etaxonomy.cdm.model.common.CdmBase)
383
	 */
384
	@Override
385
	public List<Object> getTaggedName(T nonViralName) {
386
		List<Object> tags = new ArrayList<Object>();
387
		if (nonViralName.getGenusOrUninomial() == null){
388
			tags.add(nonViralName.getNameCache());
389
		}else{
390
			tags.add(nonViralName.getGenusOrUninomial());
391
		}
392
		if (nonViralName.isSpecies() || nonViralName.isInfraSpecific()){
393
			tags.add(nonViralName.getSpecificEpithet());			
394
		}
395
		
396
		// No autonym 
397
		if (nonViralName.isInfraSpecific() && ! nonViralName.getSpecificEpithet().equals(nonViralName.getInfraSpecificEpithet())){
398
			tags.add(nonViralName.getRank());			
399
			tags.add(nonViralName.getInfraSpecificEpithet());			
400
		}
401
		
402
		if (nonViralName.isInfraGeneric()){
403
			//TODO choose right strategy or generic approach?
404
			// --- strategy 1 --- 
405
					
406
			if (nonViralName.getRank().isSpeciesAggregate()){
407
				tags.add(getSpeciesAggregateEpithet(nonViralName));
408
			}else{
409
				tags.add(nonViralName.getRank());	
410
				tags.add(nonViralName.getInfraGenericEpithet());	
411
			}
412
			// --- strategy 2 --- 
413
//			tags.add('('+nvn.getInfraGenericEpithet()+')');	
414
		}
415
		Team authorTeam = Team.NewInstance();
416
		authorTeam.setProtectedTitleCache(true);
417
		authorTeam.setTitleCache(nonViralName.getAuthorshipCache(), true);
418
		tags.add(authorTeam);
419
		
420
		// Name is an autonym. Rank and infraspecific eitheton follow the author
421
		if (nonViralName.isInfraSpecific() && nonViralName.getSpecificEpithet().equals(nonViralName.getInfraSpecificEpithet())){
422
			tags.add(nonViralName.getRank());			
423
			tags.add(nonViralName.getInfraSpecificEpithet());			
424
		}
425
		
426
		if(! "".equals(nonViralName.getAppendedPhrase())&& (nonViralName.getAppendedPhrase() != null)){
427
			tags.add(nonViralName.getAppendedPhrase());
428
		}
429
		
430
		return tags;
431
	}
432
	
433

    
434
//***************************** PRIVATES ***************************************/
435
		
436
		protected String getRanklessNameCache(NonViralName nonViralName){
437
			String result = "";
438
			result = (result + (nonViralName.getGenusOrUninomial())).trim().replace("null", "");
439
			result += " " + (CdmUtils.Nz(nonViralName.getSpecificEpithet())).trim();
440
			result += " " + (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet())).trim();
441
			result = result.trim().replace("null", "");
442
			//result += " (rankless)";
443
			result = addAppendedPhrase(result, nonViralName);
444
			return result;			
445
		}
446
	
447
	
448
		protected String getGenusOrUninomialNameCache(NonViralName nonViralName){
449
			String result;
450
			result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());
451
			result = addAppendedPhrase(result, nonViralName).trim();
452
			return result;
453
		}
454
		
455
		protected String getInfraGenusNameCache(NonViralName nonViralName){
456
			String result;
457
			Rank rank = nonViralName.getRank();
458
			if (rank.isSpeciesAggregate()){
459
				return getSpeciesAggregateCache(nonViralName);
460
			}
461
			String infraGenericMarker = "'unhandled infrageneric rank'";
462
			if (rank != null){
463
				try {
464
					infraGenericMarker = rank.getInfraGenericMarker();
465
				} catch (UnknownCdmTypeException e) {
466
					infraGenericMarker = "'unhandled infrageneric rank'";
467
				}
468
			}
469
			result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());
470
			result += " " + infraGenericMarker + " " + (CdmUtils.Nz(nonViralName.getInfraGenericEpithet())).trim().replace("null", "");
471
			result = addAppendedPhrase(result, nonViralName).trim();
472
			return result;
473
		}
474

    
475
//		aggr.|agg.|group
476
		protected String getSpeciesAggregateCache(NonViralName nonViralName){
477
			String result;
478
			result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());
479
			
480
			result += " "+getSpeciesAggregateEpithet(nonViralName);
481
			/*result += " " + CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim().replace("null", "");
482
			String marker;
483
			try {
484
				marker = nonViralName.getRank().getInfraGenericMarker();
485
			} catch (UnknownCdmTypeException e) {
486
				marker = "'unknown aggregat type'";
487
			}
488
			result += " " + marker;*/
489
			result = addAppendedPhrase(result, nonViralName).trim();
490
			return result;
491
		}
492
		
493
		private String getSpeciesAggregateEpithet(NonViralName nonViralName) {
494
			String result;
495
			
496
			result = CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim().replace("null", "");
497
			String marker;
498
			try {
499
				marker = nonViralName.getRank().getInfraGenericMarker();
500
			} catch (UnknownCdmTypeException e) {
501
				marker = "'unknown aggregat type'";
502
			}
503
			result += " " + marker;
504
			
505
			return result;
506
		}
507
		
508
		protected String getSpeciesNameCache(NonViralName nonViralName){
509
			String result;
510
			result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());
511
			result += " " + CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim().replace("null", "");
512
			result = addAppendedPhrase(result, nonViralName).trim();
513
			result = result.replace("\\s\\", " ");
514
			return result;
515
		}
516
		
517
		
518
		protected String getInfraSpeciesNameCache(NonViralName nonViralName){
519
			return getInfraSpeciesNameCache(nonViralName, true);
520
		}
521
		
522
		protected String getInfraSpeciesNameCache(NonViralName nonViralName, boolean includeMarker){
523
			String result;
524
			result = CdmUtils.Nz(nonViralName.getGenusOrUninomial());
525
			result += " " + (CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim()).replace("null", "");
526
			if (includeMarker){ 
527
				result += " " + (nonViralName.getRank().getAbbreviation()).trim().replace("null", "");
528
			}
529
			result += " " + (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet())).trim().replace("null", "");
530
			result = addAppendedPhrase(result, nonViralName).trim();
531
			return result;
532
		}
533

    
534
		
535
		
536
		/**
537
		 * @param name
538
		 * @return true, if name has Rank, Rank is below species and species epithet equals infraSpeciesEpithtet, else false
539
		 */
540
		protected boolean isAutonym(NonViralName nonViralName){
541
			if (nonViralName != null && nonViralName.getRank() != null && nonViralName.getSpecificEpithet() != null && nonViralName.getInfraSpecificEpithet() != null && 
542
					nonViralName.getRank().isInfraSpecific() && nonViralName.getSpecificEpithet().trim().equals(nonViralName.getInfraSpecificEpithet().trim())){
543
				return true;
544
			}else{
545
				return false;
546
			}
547
		}
548
		
549
		protected String addAppendedPhrase(String resultString, NonViralName nonViralName){
550
			String appendedPhrase = nonViralName ==null ? null : nonViralName.getAppendedPhrase();
551
			if (resultString == null){
552
				return appendedPhrase;
553
			}else if(appendedPhrase == null || "".equals(appendedPhrase.trim())) {
554
				return resultString;
555
			}else if ("".equals(resultString)){
556
				return resultString + appendedPhrase;
557
			}else {
558
				return resultString + " " + appendedPhrase;
559
			}
560
		}
561

    
562

    
563
		public String getLastEpithet(T taxonNameBase) {
564
			Rank rank = taxonNameBase.getRank();
565
			if(rank.isGenus() || rank.isSupraGeneric()) {
566
				return taxonNameBase.getGenusOrUninomial();
567
			} else if(rank.isInfraGeneric()) {
568
				return taxonNameBase.getInfraGenericEpithet();
569
			} else if(rank.isSpecies()) {
570
				return taxonNameBase.getSpecificEpithet();
571
			} else {
572
				return taxonNameBase.getInfraSpecificEpithet();
573
			}
574
		}
575
}
(7-7/8)