Project

General

Profile

« Previous | Next » 

Revision 731fe9ff

Added by Andreas Müller over 12 years ago

Cleaning up name cache strategies and updating javadoc

View differences:

cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/name/BotanicalName.java
314 314

  
315 315
	
316 316
	/**
317
	 * @param name
317
	 * Checks if this name is an autonym.<BR>
318
	 * An autonym is a taxon name that has equal specific and infra specific epithets.<BR>
319
	 * {@link http://ibot.sav.sk/icbn/frameset/0010Ch2Sec1a006.htm#6.8. Vienna Code ?6.8}
318 320
	 * @return true, if name has Rank, Rank is below species and species epithet equals infraSpeciesEpithtet, else false
319 321
	 */
320 322
	@Override
cdmlib-model/src/main/java/eu/etaxonomy/cdm/strategy/cache/name/BacterialNameDefaultCacheStrategy.java
21 21
 *
22 22
 */
23 23
public class BacterialNameDefaultCacheStrategy<NAME extends BacterialName> extends NonViralNameDefaultCacheStrategy<NAME> implements  INonViralNameCacheStrategy<NAME> {
24
	private static final long serialVersionUID = 7369285557176649585L;
24 25
	private static final Logger logger = Logger.getLogger(BacterialNameDefaultCacheStrategy.class);
25
	
26 26
	final static UUID uuid = UUID.fromString("b97cf0af-2f97-487e-8d06-cbe924f3222a");
27 27
	
28 28
	static {
cdmlib-model/src/main/java/eu/etaxonomy/cdm/strategy/cache/name/BotanicNameDefaultCacheStrategy.java
46 46
	 * @param exAuthor the ex-author
47 47
	 * @return
48 48
	 */
49
	@Override
49 50
	protected String getAuthorAndExAuthor(INomenclaturalAuthor author, INomenclaturalAuthor exAuthor){
50 51
		String result = "";
51 52
		String authorString = "";
cdmlib-model/src/main/java/eu/etaxonomy/cdm/strategy/cache/name/NonViralNameDefaultCacheStrategy.java
23 23
import eu.etaxonomy.cdm.model.agent.Team;
24 24
import eu.etaxonomy.cdm.model.common.Language;
25 25
import eu.etaxonomy.cdm.model.common.Representation;
26
import eu.etaxonomy.cdm.model.name.BotanicalName;
26 27
import eu.etaxonomy.cdm.model.name.HybridRelationship;
27 28
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
28 29
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
......
36 37

  
37 38

  
38 39
/**
39
 * This class is a default implementation for the INonViralNameCacheStrategy<T extends NonViralName> interface.
40
 * The method actually implements a cache strategy for botanical names so no method has to be overwritten by
40
 * This class is a default implementation for the INonViralNameCacheStrategy<T extends NonViralName> 
41
 * interface.<BR>
42
 * The method implements a cache strategy for botanical names so no method has to be overwritten by
41 43
 * a subclass for botanic names.
42
 * Where differing from this Default BotanicNameCacheStrategy other subclasses should overwrite the existing methods
43
 * e.g. a CacheStrategy for zoological names should overwrite getAuthorAndExAuthor
44
 * Where differing from this default botanic name strategy other subclasses should overwrite the
45
 * existing methods, e.g. a CacheStrategy for zoological names should overwrite getAuthorAndExAuthor
44 46
 * @author a.mueller
45 47
 */
46 48
/**
......
157 159
	}
158 160

  
159 161

  
160
	public void setBasionymAuthorCombinationAuthorSeperator(
161
			CharSequence basionymAuthorCombinationAuthorSeperator) {
162
	public void setBasionymAuthorCombinationAuthorSeperator( CharSequence basionymAuthorCombinationAuthorSeperator) {
162 163
		BasionymAuthorCombinationAuthorSeperator = basionymAuthorCombinationAuthorSeperator;
163 164
	}
164 165

  
......
179 180
		}
180 181
	}
181 182

  
182
	
183
	
184
	public String getTitleCache_OLD(T nonViralName) {
185
		if (nonViralName == null){
186
			return null;
187
		}
188
		
189
		if (nonViralName.isProtectedTitleCache()){
190
			return nonViralName.getTitleCache();
191
		}
192
		String result = "";
193
		if (nonViralName.isHybridFormula()){
194
			//hybrid formula
195
			result = null;
196
			String hybridSeparator = " " + NonViralNameParserImplRegExBase.hybridSign + " ";
197
			List<HybridRelationship> rels = nonViralName.getOrderedChildRelationships();
198
			for (HybridRelationship rel: rels){
199
				result = CdmUtils.concat(hybridSeparator, result, rel.getParentName().getTitleCache()).trim();
200
			}
201
			return result;
202
		}else if (nonViralName.isAutonym()){
203
			//Autonym
204
			result = handleAutonym(nonViralName);
205
		}else{ //not Autonym
206
			String nameCache = nonViralName.getNameCache();  //OLD: CdmUtils.Nz(getNameCache(nonViralName));
207
			if (nameIncludesAuthorship(nonViralName)){
208
				String authorCache = CdmUtils.Nz(getAuthorshipCache(nonViralName));
209
				result = CdmUtils.concat(NameAuthorSeperator, nameCache, authorCache);
210
			}else{
211
				result = nameCache;
212
			}
213
		}
214
		return result;
215
	}
216

  
217

  
218
	/**
219
	 * Creates a string from tagged text.
220
	 * @param tags
221
	 * @return
222
	 */
223
	private String createString(List<TaggedText> tags) {
224
		StringBuffer result = new StringBuffer();
225
		
226
		boolean isSeparator;
227
		boolean wasSeparator = true;  //true for start tag
228
		for (TaggedText tag: tags){
229
			isSeparator = tag.getType().equals(TagEnum.separator);
230
			if (! wasSeparator && ! isSeparator ){
231
				result.append(" ");
232
			}
233
			result.append(tag.getText());
234
			wasSeparator = isSeparator;
235
		}
236
		return result.toString();
237
	}
238

  
239

  
240
	/**
241
	 * @param nonViralName
242
	 * @param speciesPart
243
	 * @return
244
	 */
245
	private List<TaggedText> handleTaggedAutonym(T nonViralName) {
246
		
247
		//species part
248
		List<TaggedText> tags = getSpeciesTaggedNameCache(nonViralName);
249
		
250
		//author
251
		//TODO should this include basionym authors and ex authors
252
		INomenclaturalAuthor author = nonViralName.getCombinationAuthorTeam();
253
		String authorPart = "";
254
		if (author != null){
255
			authorPart = CdmUtils.Nz(author.getNomenclaturalTitle());
256
		}
257
		INomenclaturalAuthor basAuthor = nonViralName.getBasionymAuthorTeam();
258
		String basAuthorPart = "";
259
		if (basAuthor != null){
260
			basAuthorPart = CdmUtils.Nz(basAuthor.getNomenclaturalTitle());
261
		}
262
		if (! "".equals(basAuthorPart)){
263
			authorPart = "("+ basAuthorPart +") " + authorPart;
264
		}
265
		if (StringUtils.isNotBlank(authorPart)){
266
			tags.add(new TaggedText(TagEnum.authors, authorPart));
267
		}
268
		
269
		
270
		//infra species marker
271
		if (nonViralName.getRank() == null || !nonViralName.getRank().isInfraSpecific()){
272
			//TODO handle exception
273
			logger.warn("Rank for autonym does not exist or is not lower than species !!");
274
		}else{
275
			String infraSpeciesMarker = nonViralName.getRank().getAbbreviation();
276
			if (StringUtils.isNotBlank(infraSpeciesMarker)){
277
				tags.add(new TaggedText(TagEnum.rank, infraSpeciesMarker));
278
			}
279
		}
280
		
281
		//infra species
282
		String infraSpeciesPart = CdmUtils.Nz(nonViralName.getInfraSpecificEpithet()).trim().replace("null", "");
283
		if (StringUtils.isNotBlank(infraSpeciesPart)){
284
			tags.add(new TaggedText(TagEnum.name, infraSpeciesPart));
285
		}
286
		
287
		return tags;
288
	}
289
	
290
	/**
291
	 * @param nonViralName
292
	 * @param speciesPart
293
	 * @return
294
	 */
295
	private String handleAutonym(T nonViralName) {
296
		String result;
297
		String speciesPart = getSpeciesNameCache(nonViralName);
298
		//TODO should this include basionym authors and ex authors
299
		INomenclaturalAuthor author = nonViralName.getCombinationAuthorTeam();
300
		String authorPart = "";
301
		if (author != null){
302
			authorPart = CdmUtils.Nz(author.getNomenclaturalTitle());
303
		}
304
		INomenclaturalAuthor basAuthor = nonViralName.getBasionymAuthorTeam();
305
		String basAuthorPart = "";
306
		if (basAuthor != null){
307
			basAuthorPart = CdmUtils.Nz(basAuthor.getNomenclaturalTitle());
308
		}
309
		if (! "".equals(basAuthorPart)){
310
			authorPart = "("+ basAuthorPart +") " + authorPart;
311
		}
312
		String infraSpeciesPart = (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet()));
313

  
314
		String infraSpeciesSeparator = "";
315
		if (nonViralName.getRank() == null || !nonViralName.getRank().isInfraSpecific()){
316
			//TODO handle exception
317
			logger.warn("Rank for autonym does not exist or is not lower than species !!");
318
		}else{
319
			infraSpeciesSeparator = nonViralName.getRank().getAbbreviation();
320
		}
321
		
322
		result = CdmUtils.concat(" ", new String[]{speciesPart, authorPart, infraSpeciesSeparator, infraSpeciesPart});
323
		result = result.trim().replace("null", "");
324
		return result;
325
	}
326
	
327
	protected boolean nameIncludesAuthorship(NonViralName<?> nonViralName){
328
		Rank rank = nonViralName.getRank();
329
		if (rank != null && rank.isSpeciesAggregate()){
330
			return false;
331
		}else{
332
			return true;
333
		}
334
	}
335
	
336 183
	/* (non-Javadoc)
337 184
	 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getFullTitleCache(eu.etaxonomy.cdm.model.name.TaxonNameBase)
338 185
	 */
......
346 193
			return result;
347 194
		}
348 195
	}
349
	
350
	
351
	public String getFullTitleCache_OLD(T nonViralName) {
352
		//null
353
		if (nonViralName == null){
354
			return null;
355
		}
356
		//full title cache
357
		if (nonViralName.isProtectedFullTitleCache() == true) {
358
			return nonViralName.getFullTitleCache();
359
		}
360
		
361
		String result = "";
362
		//title cache
363
		String titleCache = nonViralName.getTitleCache();   // OLD: getTitleCache(nonViralName);
364
		
365
		String microReference = nonViralName.getNomenclaturalMicroReference();
366
		INomenclaturalReference ref = nonViralName.getNomenclaturalReference();
367
		String referenceBaseCache = null;
368
		if (ref != null){
369
			INomenclaturalReference nomenclaturalReference = HibernateProxyHelper.deproxy(ref, INomenclaturalReference.class);
370
			nomenclaturalReference.setCacheStrategy(nomenclaturalReference.getType().getCacheStrategy());
371
			referenceBaseCache = nomenclaturalReference.getNomenclaturalCitation(microReference);
372
		}
373
		
374
		//make nomenclatural status
375
		String ncStatusCache = "";
376
		Set<NomenclaturalStatus> ncStati = nonViralName.getStatus();
377
		Iterator<NomenclaturalStatus> iterator = ncStati.iterator();
378
		while (iterator.hasNext()) {
379
			NomenclaturalStatus ncStatus = (NomenclaturalStatus)iterator.next();
380
			// since the NewInstance method of nomencatural status allows null as parameter
381
			// we have to check for null values here
382
			String suffix = "not defined";
383
			if(ncStatus.getType() != null){
384
				NomenclaturalStatusType statusType =  ncStatus.getType();
385
				Language lang = Language.LATIN();
386
				Representation repr = statusType.getRepresentation(lang);
387
				if (repr != null){
388
					suffix = repr.getAbbreviatedLabel();
389
				}else{
390
					String message = "No latin representation available for nom. status. " + statusType.getTitleCache();
391
					logger.warn(message);
392
					throw new IllegalStateException(message);
393
				}
394
			}else if(ncStatus.getRuleConsidered() != null && ! ncStatus.getRuleConsidered().equals("")){
395
				suffix = ncStatus.getRuleConsidered();
396
			}
397
			ncStatusCache = ", " + suffix;
398
		}
399
		String refConcat = " ";
400
		if (referenceBaseCache != null && ! referenceBaseCache.trim().startsWith("in ")){
401
			refConcat = ", ";
402
		}
403
		result = CdmUtils.concat(refConcat, titleCache, referenceBaseCache);
404
		result = CdmUtils.concat("", result, ncStatusCache);
405
		return result;
406
	}
407
	
408 196

  
409 197
	
410 198
	/**
......
421 209
		}
422 210
	}
423 211
	
424
	public String getNameCache_OLD(T nonViralName) {
425
		if (nonViralName == null){
426
			return null;
427
		}
428
		String result;
429
		Rank rank = nonViralName.getRank();
430
		
431
		if (nonViralName.isProtectedNameCache()){
432
			result = nonViralName.getNameCache();
433
		}else if (rank == null){
434
			result = getRanklessNameCache(nonViralName);
435
//		}else if (nonViralName.isInfragenericUnranked()){
436
//			result = getUnrankedInfragenericNameCache(nonViralName);
437
		}else if (rank.isInfraSpecific()){
438
			result = getInfraSpeciesNameCache(nonViralName);
439
		}else if (rank.isSpecies()){
440
			result = getSpeciesNameCache(nonViralName);
441
		}else if (rank.isInfraGeneric()){
442
			result = getInfraGenusNameCache(nonViralName);
443
		}else if (rank.isGenus()){
444
			result = getGenusOrUninomialNameCache(nonViralName);
445
		}else if (rank.isSupraGeneric()){
446
			result = getGenusOrUninomialNameCache(nonViralName);
447
		}else{ 
448
			logger.warn("Name Strategy for Name (UUID: " + nonViralName.getUuid() +  ") not yet implemented");
449
			result = "";
450
		}
451
		return result;
452
	}
453

  
454 212

  
455
	private String getUnrankedInfragenericNameCache(T nonViralName) {
456
		String result;
457
		Rank rank = nonViralName.getRank();
458
		if (rank.isSpeciesAggregate()){
459
			return getSpeciesAggregateCache(nonViralName);
213
	/**
214
	 * Creates a string from tagged text.
215
	 * @param tags
216
	 * @return
217
	 */
218
	protected String createString(List<TaggedText> tags) {
219
		StringBuffer result = new StringBuffer();
220
		
221
		boolean isSeparator;
222
		boolean wasSeparator = true;  //true for start tag
223
		for (TaggedText tag: tags){
224
			isSeparator = tag.getType().equals(TagEnum.separator);
225
			if (! wasSeparator && ! isSeparator ){
226
				result.append(" ");
227
			}
228
			result.append(tag.getText());
229
			wasSeparator = isSeparator;
460 230
		}
461
		String infraGenericMarker = rank.getAbbreviation();
462
		result = CdmUtils.Nz(nonViralName.getGenusOrUninomial()).trim();
463
		result += " " + infraGenericMarker + " " + (CdmUtils.Nz(nonViralName.getInfraGenericEpithet())).trim().replace("null", "");
464
		result = addAppendedPhrase(result, nonViralName).trim();
465
		return result; 
231
		return result.toString();
466 232
	}
467

  
233
	
234
// ******************* Authorship ******************************/	
235
	
468 236

  
469 237
	/* (non-Javadoc)
470 238
	 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy#getAuthorCache(eu.etaxonomy.cdm.model.name.NonViralName)
......
528 296
		}
529 297
		result = exAuthorString + authorString;
530 298
		return result;
531
 
532 299
	}
533 300
	
534
// ************* TAGGED NAME ***************************************/	
535 301
	
302
	/**
303
	 * Checks if the given name should include the author in it's cached version.<BR>
304
	 * This is usually the case but not for <i>species aggregates</i>.
305
	 * @param nonViralName
306
	 * @return
307
	 */
308
	protected boolean nameIncludesAuthorship(NonViralName<?> nonViralName){
309
		Rank rank = nonViralName.getRank();
310
		if (rank != null && rank.isSpeciesAggregate()){
311
			return false;
312
		}else{
313
			return true;
314
		}
315
	}
316
	
317
// ************* TAGGED NAME ***************************************/	
318

  
536 319
	/* (non-Javadoc)
537
	 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTaggedTitle(eu.etaxonomy.cdm.model.name.TaxonNameBase)
320
	 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTaggedFullTitle(eu.etaxonomy.cdm.model.name.TaxonNameBase)
538 321
	 */
539 322
	@Override
540 323
	public List<TaggedText> getTaggedFullTitle(T nonViralName) {
......
607 390
		
608 391
	}
609 392
		
393
	/* (non-Javadoc)
394
	 * @see eu.etaxonomy.cdm.strategy.cache.name.NameCacheStrategyBase#getTaggedTitle(eu.etaxonomy.cdm.model.name.TaxonNameBase)
395
	 */
610 396
	public List<TaggedText> getTaggedTitle(T nonViralName) {
611 397
		if (nonViralName == null){
612 398
			return null;
......
653 439
	
654 440
	
655 441
	/**
656
	 * Returns the name part (without author and reference) of this name in tagged mode.
442
	 * Returns the tag list of the name part (without author and reference).
657 443
	 * @param nonViralName
658 444
	 * @return
659 445
	 */
660
	private List<TaggedText> getTaggedName(T nonViralName) {
446
	public List<TaggedText> getTaggedName(T nonViralName) {
661 447
		if (nonViralName == null){
662 448
			return null;
663 449
		}
......
691 477
	}
692 478

  
693 479

  
694
	//Old: may be replaced once getTagged(Full)Title is fully tested
695
	/* (non-Javadoc)
696
	 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTaggedName(eu.etaxonomy.cdm.model.common.CdmBase)
480
	
481

  
482
//***************************** PRIVATES ***************************************/
483
	
484

  
485
	/**
486
	 * Returns the tag list for an autonym taxon.
487
	 * 
488
	 * @see NonViralName#isAutonym()
489
	 * @see BotanicalName#isAutonym()
490
	 * @param nonViralName
491
	 * @return
697 492
	 */
698
	@Override
699
	@Deprecated
700
	public List<Object> getTaggedNameDeprecated(T nonViralName) {
701
		List<Object> tags = new ArrayList<Object>();
493
	private List<TaggedText> handleTaggedAutonym(T nonViralName) {
702 494
		
703
		if (nonViralName.isProtectedNameCache() ||
704
				nonViralName.isProtectedAuthorshipCache() ||
705
				nonViralName.isProtectedFullTitleCache() ||
706
				nonViralName.isProtectedTitleCache()){
707
			tags.add(nonViralName.getTitleCache());
708
			return tags;
709
		}
710
		
711
		// Why does it make sense to add the nameCache in case of non existing genusOrUninomial?
712
//		if (nonViralName.getGenusOrUninomial() == null){
713
//			tags.add(nonViralName.getNameCache());
714
//		}else{
495
		//species part
496
		List<TaggedText> tags = getSpeciesTaggedNameCache(nonViralName);
715 497
		
716
		if (nonViralName.getGenusOrUninomial() != null) {
717
			tags.add(nonViralName.getGenusOrUninomial());
498
		//author
499
		//TODO should this include basionym authors and ex authors
500
		INomenclaturalAuthor author = nonViralName.getCombinationAuthorTeam();
501
		String authorPart = "";
502
		if (author != null){
503
			authorPart = CdmUtils.Nz(author.getNomenclaturalTitle());
718 504
		}
719
		if (nonViralName.isSpecies() || nonViralName.isInfraSpecific()){
720
			tags.add(nonViralName.getSpecificEpithet());			
505
		INomenclaturalAuthor basAuthor = nonViralName.getBasionymAuthorTeam();
506
		String basAuthorPart = "";
507
		if (basAuthor != null){
508
			basAuthorPart = CdmUtils.Nz(basAuthor.getNomenclaturalTitle());
721 509
		}
722
		
723
		// No autonym 
724
		if (nonViralName.isInfraSpecific() && ! nonViralName.getSpecificEpithet().equals(nonViralName.getInfraSpecificEpithet())){
725
			tags.add(nonViralName.getRank());			
726
			tags.add(nonViralName.getInfraSpecificEpithet());			
510
		if (! "".equals(basAuthorPart)){
511
			authorPart = "("+ basAuthorPart +") " + authorPart;
727 512
		}
728
		
729
		if (nonViralName.isInfraGeneric()){
730
			//TODO choose right strategy or generic approach?
731
			// --- strategy 1 --- 
732
					
733
			if (nonViralName.getRank().isSpeciesAggregate()){
734
				tags.add(nonViralName.getSpecificEpithet());
735
				tags.add(getSpeciesAggregateEpithet(nonViralName));
736
			}else{
737
				tags.add(nonViralName.getRank());	
738
				tags.add(nonViralName.getInfraGenericEpithet());	
739
			}
740
			// --- strategy 2 --- 
741
//			tags.add('('+nvn.getInfraGenericEpithet()+')');	
513
		if (StringUtils.isNotBlank(authorPart)){
514
			tags.add(new TaggedText(TagEnum.authors, authorPart));
742 515
		}
743
		Team authorTeam = Team.NewInstance();
744
		authorTeam.setProtectedTitleCache(true);
745
		authorTeam.setTitleCache(nonViralName.getAuthorshipCache(), true);
746
		tags.add(authorTeam);
747 516
		
748
		// Name is an autonym. Rank and infraspecific epitheton follow the author
749
		if (nonViralName.isInfraSpecific() && nonViralName.getSpecificEpithet().equals(nonViralName.getInfraSpecificEpithet())){
750
			tags.add(nonViralName.getRank());			
751
			tags.add(nonViralName.getInfraSpecificEpithet());			
517
		
518
		//infra species marker
519
		if (nonViralName.getRank() == null || !nonViralName.getRank().isInfraSpecific()){
520
			//TODO handle exception
521
			logger.warn("Rank for autonym does not exist or is not lower than species !!");
522
		}else{
523
			String infraSpeciesMarker = nonViralName.getRank().getAbbreviation();
524
			if (StringUtils.isNotBlank(infraSpeciesMarker)){
525
				tags.add(new TaggedText(TagEnum.rank, infraSpeciesMarker));
526
			}
752 527
		}
753 528
		
754
		if(! "".equals(nonViralName.getAppendedPhrase())&& (nonViralName.getAppendedPhrase() != null)){
755
			tags.add(nonViralName.getAppendedPhrase());
529
		//infra species
530
		String infraSpeciesPart = CdmUtils.Nz(nonViralName.getInfraSpecificEpithet()).trim().replace("null", "");
531
		if (StringUtils.isNotBlank(infraSpeciesPart)){
532
			tags.add(new TaggedText(TagEnum.name, infraSpeciesPart));
756 533
		}
757 534
		
758 535
		return tags;
759 536
	}
760 537
	
761

  
762
//***************************** PRIVATES ***************************************/
763
		
538
	
539
	
540
	/**
541
	 * Returns the tag list for rankless taxa.
542
	 * @param nonViralName
543
	 * @return
544
	 */
764 545
	protected List<TaggedText> getRanklessTaggedNameCache(NonViralName<?> nonViralName){
765 546
		List<TaggedText> tags = getUninomialTaggedPart(nonViralName);
766 547
		String speciesEpi = CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim().replace("null", "");
......
777 558
		addAppendedTaggedPhrase(tags, nonViralName);
778 559
		return tags;			
779 560
	}
780
	
781
	protected String getRanklessNameCache(NonViralName<?> nonViralName){
782
		String result = "";
783
		result = (result + (CdmUtils.Nz(nonViralName.getGenusOrUninomial()))).trim().replace("null", "");
784
		result += " " + (CdmUtils.Nz(nonViralName.getSpecificEpithet())).trim();
785
		result += " " + (CdmUtils.Nz(nonViralName.getInfraSpecificEpithet())).trim();
786
		result = result.trim().replace("null", "");
787
		//result += " (rankless)";
788
		result = addAppendedPhrase(result, nonViralName);
789
		return result;			
790
	}
791

  
792
		
793
	protected List<TaggedText> getGenusOrUninomialTaggedNameCache(NonViralName<?> nonViralName){
794
		List<TaggedText> tags = getUninomialTaggedPart(nonViralName);
795
		addAppendedTaggedPhrase(tags, nonViralName);
796
		return tags;
797
	}
798

  
799
	protected String getGenusOrUninomialNameCache(NonViralName<?> nonViralName){
800
		String result;
801
		result = getUninomialPart(nonViralName);
802
		result = addAppendedPhrase(result, nonViralName).trim();
803
		return result;
804
	}
805

  
806 561

  
562
	/**
563
	 * Returns the tag list for the first epithet (including a hybrid sign if required).
564
	 * @param nonViralName
565
	 * @return
566
	 */
807 567
	private List<TaggedText> getUninomialTaggedPart(NonViralName<?> nonViralName) {
808 568
		List<TaggedText> tags = new ArrayList<TaggedText>();
809 569
		
......
819 579
		return tags;
820 580
	}
821 581
	
822
	private String getUninomialPart(NonViralName<?> nonViralName) {
823
		String result;
824
		result = CdmUtils.Nz(nonViralName.getGenusOrUninomial()).trim();
825
		if (nonViralName.isMonomHybrid()){
826
			result = NonViralNameParserImplRegExBase.hybridSign + result; 
827
		}
828
		return result;
582
	/**
583
	 * Returns the tag list for an genus or higher taxon.
584
	 * 
585
	 * @param nonViralName
586
	 * @return
587
	 */
588
	protected List<TaggedText> getGenusOrUninomialTaggedNameCache(NonViralName<?> nonViralName){
589
		List<TaggedText> tags = getUninomialTaggedPart(nonViralName);
590
		addAppendedTaggedPhrase(tags, nonViralName);
591
		return tags;
829 592
	}
830 593
	
831
	
594
	/**
595
	 * Returns the tag list for an infrageneric taxon (including species aggregates).
596
	 * 
597
	 * @see #getSpeciesAggregateTaggedCache(NonViralName)
598
	 * @param nonViralName
599
	 * @return
600
	 */
832 601
	protected List<TaggedText> getInfraGenusTaggedNameCache(NonViralName<?> nonViralName){
833 602
		Rank rank = nonViralName.getRank();
834 603
		if (rank.isSpeciesAggregate()){
......
859 628
		return tags;
860 629
	}
861 630
	
862
	protected String getInfraGenusNameCache(NonViralName<?> nonViralName){
863
		String result;
864
		Rank rank = nonViralName.getRank();
865
		if (rank.isSpeciesAggregate()){
866
			return getSpeciesAggregateCache(nonViralName);
867
		}
868
		String infraGenericMarker = "'unhandled infrageneric rank'";
869
		if (rank != null){
870
			try {
871
				infraGenericMarker = rank.getInfraGenericMarker();
872
			} catch (UnknownCdmTypeException e) {
873
				infraGenericMarker = "'unhandled infrageneric rank'";
874
			}
875
		}
876
		result = getUninomialPart(nonViralName);
877
		result += " " + infraGenericMarker + " " + (CdmUtils.Nz(nonViralName.getInfraGenericEpithet())).trim().replace("null", "");
878
		result = addAppendedPhrase(result, nonViralName).trim();
879
		return result;
880
	}
881

  
882
//		aggr.|agg.|group
631
	/**
632
	 * Returns the tag list for a species aggregate (or similar) taxon.<BR>
633
	 * Possible ranks for a <i>species aggregate</i> are "aggr.", "species group", ...	
634
	 * @param nonViralName
635
	 * @return
636
	 */
883 637
	protected List<TaggedText> getSpeciesAggregateTaggedCache(NonViralName<?> nonViralName){
884 638
		List<TaggedText> tags = getGenusAndSpeciesTaggedPart(nonViralName);
885 639
		
......
888 642
		return tags;
889 643
	}
890 644
	
645
	/**
646
	 * Adds the aggregate tag to the tag list.
647
	 * @param tags
648
	 * @param nonViralName
649
	 */
891 650
	private void addSpeciesAggregateTaggedEpithet(List<TaggedText> tags, NonViralName<?> nonViralName) {
892 651
		String marker;
893 652
		try {
......
899 658
			tags.add(new TaggedText(TagEnum.rank, marker));
900 659
		}
901 660
	}
902
	
903
//		aggr.|agg.|group
904
	protected String getSpeciesAggregateCache(NonViralName<?> nonViralName){
905
		String result = getGenusAndSpeciesPart(nonViralName);
906
		
907
		result += " " + getSpeciesAggregateEpithet(nonViralName);
908
		result = addAppendedPhrase(result, nonViralName).trim();
909
		return result;
910
	}
911
	
912
	private String getSpeciesAggregateEpithet(NonViralName<?> nonViralName) {
913
		String marker;
914
		try {
915
			marker = nonViralName.getRank().getInfraGenericMarker();
916
		} catch (UnknownCdmTypeException e) {
917
			marker = "'unknown aggregat type'";
918
		}
919
		return marker;
920
	}
921 661

  
922 662
	
663
	/**
664
	 * Returns the tag list for a species taxon.
665
	 * @param nonViralName
666
	 * @return
667
	 */
923 668
	protected List<TaggedText> getSpeciesTaggedNameCache(NonViralName<?> nonViralName){
924 669
		List<TaggedText> tags = getGenusAndSpeciesTaggedPart(nonViralName);
925 670
		addAppendedTaggedPhrase(tags, nonViralName);
926 671
		return tags;
927 672
	}
928
	
929
	protected String getSpeciesNameCache(NonViralName<?> nonViralName){
930
		String result = getGenusAndSpeciesPart(nonViralName);
931
		result = addAppendedPhrase(result, nonViralName).trim();
932
		result = result.replace("\\s\\", " ");
933
		return result;
934
	}
935 673

  
674
	/**
675
	 * Creates the tag list for an infraspecific taxon. In include is true the result will contain
676
	 * @param nonViralName
677
	 * @return
678
	 */
936 679
	protected List<TaggedText> getInfraSpeciesTaggedNameCache(NonViralName<?> nonViralName){
937 680
		return getInfraSpeciesTaggedNameCache(nonViralName, true);
938 681
	}
939 682
	
683
	/**
684
	 * Creates the tag list for an infraspecific taxon. In include is true the result will contain
685
	 * the infraspecific marker (e.g. "var.")
686
	 * @param nonViralName
687
	 * @param includeMarker
688
	 * @return
689
	 */
940 690
	protected List<TaggedText> getInfraSpeciesTaggedNameCache(NonViralName<?> nonViralName, boolean includeMarker){
941 691
		List<TaggedText> tags = getGenusAndSpeciesTaggedPart(nonViralName);
942 692
		if (includeMarker){ 
......
968 718
		tags.add(new TaggedText(TagEnum.hybridSign, NonViralNameParserImplRegExBase.hybridSign));
969 719
		tags.add(new TaggedText(TagEnum.separator, "")); //no whitespace separator
970 720
	}
971
	
972
	protected String getInfraSpeciesNameCache(NonViralName<?> nonViralName){
973
		return getInfraSpeciesNameCache(nonViralName, true);
974
	}
975

  
976
	
977
	protected String getInfraSpeciesNameCache(NonViralName<?> nonViralName, boolean includeMarker){
978
		String result = getGenusAndSpeciesPart(nonViralName);
979
		if (includeMarker){ 
980
			result += " " + (nonViralName.getRank().getAbbreviation()).trim().replace("null", "");
981
		}
982
		String infrSpecEpi = CdmUtils.Nz(nonViralName.getInfraSpecificEpithet());
983
		if (nonViralName.isTrinomHybrid()){
984
			infrSpecEpi = NonViralNameParserImplRegExBase.hybridSign + infrSpecEpi; 
985
		}
986
		result += " " + (infrSpecEpi).trim().replace("null", "");
987
		result = addAppendedPhrase(result, nonViralName).trim();
988
		return result;
989
	}
990

  
991 721

  
722
	/**
723
	 * Creates the tag list for the genus and species part.
724
	 * @param nonViralName
725
	 * @return
726
	 */
992 727
	private List<TaggedText> getGenusAndSpeciesTaggedPart(NonViralName<?> nonViralName) {
993 728
		//Uninomial
994 729
		List<TaggedText> tags = getUninomialTaggedPart(nonViralName);
......
1017 752
		return tags;
1018 753
	}
1019 754
	
1020
	private String getGenusAndSpeciesPart(NonViralName<?> nonViralName) {
1021
		String result;
1022
		//Uninomial
1023
		result = getUninomialPart(nonViralName);
1024
		
1025
		//InfraGenericEpi
1026
		boolean hasInfraGenericEpi = StringUtils.isNotBlank(nonViralName.getInfraGenericEpithet());
1027
		if (hasInfraGenericEpi){
1028
			String infrGenEpi = nonViralName.getInfraGenericEpithet().trim();
1029
			if (nonViralName.isBinomHybrid()){
1030
				infrGenEpi = NonViralNameParserImplRegExBase.hybridSign + infrGenEpi; 
1031
			}
1032
			result += " (" + infrGenEpi + ")";
1033
		}
1034
		//Species Epi
1035
		String specEpi = CdmUtils.Nz(nonViralName.getSpecificEpithet()).trim();
1036
		if (! hasInfraGenericEpi && nonViralName.isBinomHybrid() || 
1037
				hasInfraGenericEpi && nonViralName.isTrinomHybrid()){
1038
			specEpi = NonViralNameParserImplRegExBase.hybridSign +  specEpi; 
1039
		}
1040
		result += " " + (specEpi).replace("null", "");
1041
		return result;
1042
	}
1043

  
1044
	
1045 755
	/**
1046 756
	 * Adds the tag for the appended phrase if an appended phrase exists
1047 757
	 * @param tags
......
1053 763
			tags.add(new TaggedText(TagEnum.name, appendedPhrase));
1054 764
		}
1055 765
	}
1056
	
1057
	protected String addAppendedPhrase(String resultString, NonViralName<?> nonViralName){
1058
		String appendedPhrase = nonViralName ==null ? null : nonViralName.getAppendedPhrase();
1059
		if (resultString == null){
1060
			return appendedPhrase;
1061
		}else if(appendedPhrase == null || "".equals(appendedPhrase.trim())) {
1062
			return resultString;
1063
		}else if ("".equals(resultString)){
1064
			return resultString + appendedPhrase;
1065
		}else {
1066
			return resultString + " " + appendedPhrase;
1067
		}
1068
	}
1069

  
1070 766

  
1071 767
	public String getLastEpithet(T taxonNameBase) {
1072 768
		Rank rank = taxonNameBase.getRank();
......
1080 776
			return taxonNameBase.getInfraSpecificEpithet();
1081 777
		}
1082 778
	}
779
	
780
// *************************** DEPRECATED ***************************************************/
781
	
782

  
783
	//Old: may be replaced once getTagged(Full)Title is fully tested
784
	/* (non-Javadoc)
785
	 * @see eu.etaxonomy.cdm.strategy.INameCacheStrategy#getTaggedName(eu.etaxonomy.cdm.model.common.CdmBase)
786
	 */
787
	@Override
788
	@Deprecated
789
	public List<Object> getTaggedNameDeprecated(T nonViralName) {
790
		List<Object> tags = new ArrayList<Object>();
791
		
792
		if (nonViralName.isProtectedNameCache() ||
793
				nonViralName.isProtectedAuthorshipCache() ||
794
				nonViralName.isProtectedFullTitleCache() ||
795
				nonViralName.isProtectedTitleCache()){
796
			tags.add(nonViralName.getTitleCache());
797
			return tags;
798
		}
799
		
800
		// Why does it make sense to add the nameCache in case of non existing genusOrUninomial?
801
//		if (nonViralName.getGenusOrUninomial() == null){
802
//			tags.add(nonViralName.getNameCache());
803
//		}else{
804
		
805
		if (nonViralName.getGenusOrUninomial() != null) {
806
			tags.add(nonViralName.getGenusOrUninomial());
807
		}
808
		if (nonViralName.isSpecies() || nonViralName.isInfraSpecific()){
809
			tags.add(nonViralName.getSpecificEpithet());			
810
		}
811
		
812
		// No autonym 
813
		if (nonViralName.isInfraSpecific() && ! nonViralName.getSpecificEpithet().equals(nonViralName.getInfraSpecificEpithet())){
814
			tags.add(nonViralName.getRank());			
815
			tags.add(nonViralName.getInfraSpecificEpithet());			
816
		}
817
		
818
		if (nonViralName.isInfraGeneric()){
819
			//TODO choose right strategy or generic approach?
820
			// --- strategy 1 --- 
821
					
822
			if (nonViralName.getRank().isSpeciesAggregate()){
823
				tags.add(nonViralName.getSpecificEpithet());
824
				tags.add(getSpeciesAggregateEpithet(nonViralName));
825
			}else{
826
				tags.add(nonViralName.getRank());	
827
				tags.add(nonViralName.getInfraGenericEpithet());	
828
			}
829
			// --- strategy 2 --- 
830
//			tags.add('('+nvn.getInfraGenericEpithet()+')');	
831
		}
832
		Team authorTeam = Team.NewInstance();
833
		authorTeam.setProtectedTitleCache(true);
834
		authorTeam.setTitleCache(nonViralName.getAuthorshipCache(), true);
835
		tags.add(authorTeam);
836
		
837
		// Name is an autonym. Rank and infraspecific epitheton follow the author
838
		if (nonViralName.isInfraSpecific() && nonViralName.getSpecificEpithet().equals(nonViralName.getInfraSpecificEpithet())){
839
			tags.add(nonViralName.getRank());			
840
			tags.add(nonViralName.getInfraSpecificEpithet());			
841
		}
842
		
843
		if(! "".equals(nonViralName.getAppendedPhrase())&& (nonViralName.getAppendedPhrase() != null)){
844
			tags.add(nonViralName.getAppendedPhrase());
845
		}
846
		
847
		return tags;
848
	}
849
	
850
	
851
	/**
852
	 * @deprecated use only for {@link #getTaggedNameDeprecated(NonViralName)}. Delete when the later 
853
	 * is deleted.
854
	 */
855
	@Deprecated 
856
	private String getSpeciesAggregateEpithet(NonViralName<?> nonViralName) {
857
		String marker;
858
		try {
859
			marker = nonViralName.getRank().getInfraGenericMarker();
860
		} catch (UnknownCdmTypeException e) {
861
			marker = "'unknown aggregat type'";
862
		}
863
		return marker;
864
	}
865

  
866
	
1083 867
}
cdmlib-model/src/main/java/eu/etaxonomy/cdm/strategy/cache/name/ZooNameDefaultCacheStrategy.java
9 9

  
10 10
package eu.etaxonomy.cdm.strategy.cache.name;
11 11

  
12
import java.util.List;
12 13
import java.util.UUID;
13 14

  
14 15
import org.apache.log4j.Logger;
......
17 18
import eu.etaxonomy.cdm.model.agent.INomenclaturalAuthor;
18 19
import eu.etaxonomy.cdm.model.name.NonViralName;
19 20
import eu.etaxonomy.cdm.model.name.ZoologicalName;
21
import eu.etaxonomy.cdm.strategy.TaggedText;
20 22

  
21 23
public class ZooNameDefaultCacheStrategy <T extends ZoologicalName> extends NonViralNameDefaultCacheStrategy<T> implements  INonViralNameCacheStrategy<T> {
22 24
	@SuppressWarnings("unused")
......
47 49
		super();
48 50
	}
49 51

  
50
	
51 52

  
53

  
54
	/**
55
	 * @return Strings that separates the author part and the year part
56
	 * @return
57
	 */
58
	public String getAuthorYearSeperator() {
59
		return AuthorYearSeperator;
60
	}
61

  
62

  
63
	public void setAuthorYearSeperator(String authorYearSeperator) {
64
		AuthorYearSeperator = authorYearSeperator;
65
	}
66
	
52 67
	/* (non-Javadoc)
53 68
	 * @see eu.etaxonomy.cdm.strategy.cache.name.NonViralNameDefaultCacheStrategy#getNonCacheAuthorshipCache(eu.etaxonomy.cdm.model.name.NonViralName)
54 69
	 */
......
71 86
		if (basionymAuthor != null || exBasionymAuthor != null || originalPublicationYear != null ){
72 87
			String authorAndEx = getAuthorAndExAuthor(basionymAuthor, exBasionymAuthor);
73 88
			String originalPublicationYearString = originalPublicationYear == null ? null : String.valueOf(originalPublicationYear);
74
			String authorAndExAndYear = CdmUtils.concat(", ", authorAndEx, originalPublicationYearString );
89
			String authorAndExAndYear = CdmUtils.concat(AuthorYearSeperator, authorAndEx, originalPublicationYearString );
75 90
			basionymPart = BasionymStart + authorAndExAndYear +BasionymEnd;
76 91
		}
77 92
		if (combinationAuthor != null || exCombinationAuthor != null){
78 93
			String authorAndEx = getAuthorAndExAuthor(combinationAuthor, exCombinationAuthor);
79 94
			String publicationYearString = publicationYear == null ? null : String.valueOf(publicationYear);
80
			authorPart = CdmUtils.concat(", ", authorAndEx, publicationYearString);
95
			authorPart = CdmUtils.concat(AuthorYearSeperator, authorAndEx, publicationYearString);
81 96
		}
82 97
		result = CdmUtils.concat(BasionymAuthorCombinationAuthorSeperator, basionymPart, authorPart);
83 98
		return result;
84 99
	}
85 100
	
86 101

  
87
	/**
88
	 * @return Strings that separates the author part and the year part
89
	 * @return
90
	 */
91
	public String getAuthorYearSeperator() {
92
		return AuthorYearSeperator;
93
	}
94

  
95

  
96
	public void setAuthorYearSeperator(String authorYearSeperator) {
97
		AuthorYearSeperator = authorYearSeperator;
98
	}
99
	
100
	protected String getInfraSpeciesNameCache(NonViralName nonViralName){
102
	@Override
103
	protected List<TaggedText> getInfraSpeciesTaggedNameCache(NonViralName nonViralName){
101 104
		boolean includeMarker = ! (nonViralName.isAutonym());
102
		return getInfraSpeciesNameCache(nonViralName, includeMarker);
105
		return getInfraSpeciesTaggedNameCache(nonViralName, includeMarker);
103 106
	}
104 107

  
105 108
}
cdmlib-model/src/test/java/eu/etaxonomy/cdm/strategy/cache/name/NonViralNameDefaultCacheStrategyTest.java
31 31
import eu.etaxonomy.cdm.model.name.ZoologicalName;
32 32
import eu.etaxonomy.cdm.model.reference.Reference;
33 33
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
34
import eu.etaxonomy.cdm.strategy.TaggedText;
34 35

  
35 36
/**
36 37
 * @author a.mueller
......
461 462
	@Test
462 463
	public void testGetInfraGenericNames(){
463 464
		String author = "Anyauthor";
464
		NonViralName nonViralName = NonViralName.NewInstance(Rank.SUBGENUS());
465
		NonViralName<?> nonViralName = NonViralName.NewInstance(Rank.SUBGENUS());
465 466
		nonViralName.setGenusOrUninomial("Genus");
466 467
		nonViralName.setInfraGenericEpithet("subgenus");
467 468
		nonViralName.setAuthorshipCache(author);
468 469
		
469 470
		//test ordinary infrageneric
470
		String subGenusNameCache = strategy.getInfraGenusNameCache(nonViralName);
471
		List<TaggedText> subGenusNameCacheTagged = strategy.getInfraGenusTaggedNameCache(nonViralName);
472
		String subGenusNameCache = strategy.createString(subGenusNameCacheTagged);
471 473
		assertEquals("Subgenus name should be 'Genus subg. subgenus'.", "Genus subg. subgenus", subGenusNameCache);
472 474
		String subGenusTitle = strategy.getTitleCache(nonViralName);
473 475
		assertEquals("Subgenus name should be 'Genus subg. subgenus Anyauthor'.", "Genus subg. subgenus Anyauthor", subGenusTitle);
......
476 478
		nonViralName.setRank(Rank.SPECIESAGGREGATE());
477 479
		nonViralName.setSpecificEpithet("myspecies");
478 480
		nonViralName.setInfraGenericEpithet(null);
479
		String aggrNameCache = strategy.getInfraGenusNameCache(nonViralName);
481
		
482
		List<TaggedText> aggrNameCacheTagged = strategy.getInfraGenusTaggedNameCache(nonViralName);
483
		
484
		String aggrNameCache = strategy.createString(aggrNameCacheTagged);
480 485
		assertEquals("Species aggregate name should be 'Genus myspecies aggr.'.", "Genus myspecies aggr.", aggrNameCache);
481 486
		String aggrNameTitle = strategy.getTitleCache(nonViralName);
482 487
		Assert.assertTrue("Species aggregate should not include author information.", aggrNameTitle.indexOf(author) == -1);
......
490 495
		nonViralName.setRank(Rank.SPECIESAGGREGATE());
491 496
		nonViralName.setSpecificEpithet("myspecies");
492 497
		nonViralName.setInfraGenericEpithet("Infragenus");
493
		aggrNameCache = strategy.getInfraGenusNameCache(nonViralName);
498
		
499
		
500
		aggrNameCacheTagged = strategy.getInfraGenusTaggedNameCache(nonViralName);
501
		aggrNameCache = strategy.createString(aggrNameCacheTagged);
494 502
		assertEquals("Species aggregate name should be 'Genus (Infragenus) myspecies aggr.'.", "Genus (Infragenus) myspecies aggr.", aggrNameCache);
495 503
		
496 504
		aggrNameTitle = strategy.getTitleCache(nonViralName);

Also available in: Unified diff