Project

General

Profile

Download (22.1 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

    
10
package eu.etaxonomy.cdm.model.name;
11

    
12
import java.util.ArrayList;
13
import java.util.Collections;
14
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import javax.persistence.Entity;
21
import javax.persistence.FetchType;
22
import javax.persistence.OneToMany;
23
import javax.persistence.Transient;
24
import javax.xml.bind.annotation.XmlAccessType;
25
import javax.xml.bind.annotation.XmlAccessorType;
26
import javax.xml.bind.annotation.XmlElement;
27
import javax.xml.bind.annotation.XmlElementWrapper;
28
import javax.xml.bind.annotation.XmlIDREF;
29
import javax.xml.bind.annotation.XmlSchemaType;
30
import javax.xml.bind.annotation.XmlType;
31

    
32
import org.apache.log4j.Logger;
33
import org.hibernate.envers.Audited;
34

    
35
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
36
import eu.etaxonomy.cdm.model.reference.Reference;
37
import eu.etaxonomy.cdm.model.taxon.Synonym;
38
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
39
import eu.etaxonomy.cdm.model.taxon.Taxon;
40
import eu.etaxonomy.cdm.model.taxon.TaxonComparator;
41

    
42

    
43
/**
44
 * The homotypical group class represents a set of {@link TaxonNameBase taxon names} associated
45
 * on the base of their typifications. Since it can be asserted that two taxon
46
 * names are typified by the same type without mentioning the type itself, even
47
 * taxon names without explicit {@link TypeDesignationBase type designation} can belong
48
 * to an homotypical group.<BR>
49
 * Taxon names belonging to an homotypical group and the taxon names or
50
 * {@link eu.etaxonomy.cdm.model.occurrence.DerivedUnitBase specimens} used as types for their
51
 * {@link TypeDesignationBase type designations} have the following properties: <ul>
52
 * <li>	A taxon name belongs exactly to one homotypical group
53
 * <li>	A type specimen or a type name can be used as a type only for taxon
54
 * 		names belonging to the same homotypical group<BR>
55
 * 		- therefore an homotypical group circumscribes a set of types<BR>
56
 * 		- each taxon name shares a subset of these types<BR>
57
 * 		- each type is used by a subset of these taxon names
58
 * 			within the homotypical group
59
 * <li>	Names that share at least one common type must belong to the same
60
 * 		homotypical group
61
 * <li>	Names that share the same basionym or replaced synonym must belong to
62
 * 		the same homotypical group
63
 * </ul>
64
 * 
65
 * @see		TypeDesignationBase
66
 * @see		NameTypeDesignation
67
 * @see		SpecimenTypeDesignation
68
 * @author  m.doering
69
 * @version 1.0
70
 * @created 08-Nov-2007
71
 */
72
@XmlAccessorType(XmlAccessType.FIELD)
73
@XmlType(name = "HomotypicalGroup", propOrder = {
74
    "typifiedNames"
75
})
76
@Entity
77
@Audited
78
public class HomotypicalGroup extends AnnotatableEntity {
79
	private static final Logger logger = Logger.getLogger(HomotypicalGroup.class);
80

    
81
	@XmlElementWrapper(name = "TypifiedNames")
82
	@XmlElement(name = "TypifiedName")
83
	@XmlIDREF
84
	@XmlSchemaType(name = "IDREF")
85
	@OneToMany(mappedBy="homotypicalGroup", fetch=FetchType.LAZY)
86
	protected Set<TaxonNameBase> typifiedNames = new HashSet<TaxonNameBase>();
87

    
88
// ******************** static methods **************************************/
89
	/** 
90
	 * Creates a new homotypical group instance with an empty set of typified
91
	 * {@link TaxonNameBase taxon names}.
92
	 * 
93
	 * @see #HomotypicalGroup()
94
	 */
95
	public static HomotypicalGroup NewInstance(){
96
		return new HomotypicalGroup();
97
	}
98
	
99
	
100
//********************** CONSTRUCTOR ********************************************/
101
	
102
	/** 
103
	 * Class constructor: creates a new homotypical group instance with an
104
	 * empty set of typified {@link TaxonNameBase taxon names}.
105
	 */
106
	public HomotypicalGroup() {
107
		super();
108
	}
109

    
110
// ********************** GETTER/SETTER/ADDER/REMOVER ********************************/
111
		
112
	/** 
113
	 * Returns the set of {@link TaxonNameBase taxon names} that belong to <i>this</i> homotypical group.
114
	 *
115
	 * @see	#getSpecimenTypeDesignations()
116
	 */
117
	public Set<TaxonNameBase> getTypifiedNames() {
118
		return typifiedNames;
119
	}
120
	
121
	/** 
122
	 * Adds a new {@link TaxonNameBase taxon name} to the set of taxon names that belong
123
	 * to <i>this</i> homotypical group.
124
	 *
125
	 * @param  typifiedName  the taxon name to be added to <i>this</i> group
126
	 * @see 			  	 #getTypifiedNames()
127
	 * @see 			  	 #removeTypifiedName(TaxonNameBase)
128
	 */
129
	public void addTypifiedName(TaxonNameBase typifiedName) {
130
		if (typifiedName != null){
131
			typifiedNames.add(typifiedName);
132
			typifiedName.setHomotypicalGroup(this);
133
		}
134
	}
135
	/** 
136
	 * Removes one element from the set of {@link TaxonNameBase taxon names}
137
	 * that belong to <i>this</i> homotypical group.
138
	 *
139
	 * @param  taxonBase	the taxon name which should be removed from the corresponding set
140
	 * @see    				#addTypifiedName(TaxonNameBase)
141
	 */
142
	public void removeTypifiedName(TaxonNameBase typifiedName) {
143
		HomotypicalGroup newHomotypicalGroup = HomotypicalGroup.NewInstance();
144
		typifiedName.setHomotypicalGroup(newHomotypicalGroup);
145
		typifiedNames.remove(typifiedName);	
146
	}
147

    
148
	/**
149
	 * Merges the typified {@link TaxonNameBase taxon names} from one homotypical group into
150
	 * the set of typified taxon names of <i>this</i> homotypical group.
151
	 *  
152
	 * @param	homotypicalGroupToMerge the homotypical group the typified names of which
153
	 * 									are to be transferred to <i>this</i> homotypical group
154
	 */
155
	public void merge(HomotypicalGroup homotypicalGroupToMerge){
156
		if (homotypicalGroupToMerge != null){
157
			Set<TaxonNameBase> typifiedNames = new HashSet<TaxonNameBase>();
158
			typifiedNames.addAll(homotypicalGroupToMerge.getTypifiedNames());
159
			for (TaxonNameBase typifiedName: typifiedNames){
160
				this.addTypifiedName(typifiedName);
161
			}
162
		}
163
	}
164
	
165
	
166
	/** 
167
	 * Returns the set of {@link SpecimenTypeDesignation specimen type designations} that
168
	 * typify the {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group
169
	 * including the status of these designations.
170
	 *
171
	 * @see	#getTypifiedNames()
172
	 * @see	#getNameTypeDesignations()
173
	 * @see	#getTypeDesignations()
174
	 * @see	TaxonNameBase#getSpecimenTypeDesignations()
175
	 */
176
	@Transient
177
	public Set<SpecimenTypeDesignation> getSpecimenTypeDesignations(){
178
		Set<SpecimenTypeDesignation> result = new HashSet<SpecimenTypeDesignation>();
179
		for (TaxonNameBase taxonName : typifiedNames){
180
			result.addAll(taxonName.getSpecimenTypeDesignations());
181
		}
182
		return result;
183
	}
184
	
185
	/** 
186
	 * Returns the set of {@link NameTypeDesignation name type designations} that
187
	 * typify the {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group
188
	 * including the status of these designations.
189
	 *
190
	 * @see	#getTypifiedNames()
191
	 * @see	#getSpecimenTypeDesignations()
192
	 * @see	#getTypeDesignations()
193
	 * @see	TaxonNameBase#getNameTypeDesignations()
194
	 */
195
	@Transient
196
	public Set<NameTypeDesignation> getNameTypeDesignations(){
197
		Set<NameTypeDesignation> result = new HashSet<NameTypeDesignation>();
198
		for (TaxonNameBase taxonName : typifiedNames){
199
			result.addAll(taxonName.getNameTypeDesignations());
200
		}
201
		return result;
202
	}
203
	
204
	
205
	/** 
206
	 * Returns the set of all {@link TypeDesignationBase type designations} that
207
	 * typify the {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group
208
	 * (this includes either {@link NameTypeDesignation name type designations} or
209
	 * {@link SpecimenTypeDesignation specimen type designations}).
210
	 *
211
	 * @see	#getTypifiedNames()
212
	 * @see	#getNameTypeDesignations()
213
	 * @see	#getSpecimenTypeDesignations()
214
	 * @see	TaxonNameBase#getTypeDesignations()
215
	 */
216
	@Transient
217
	public Set<TypeDesignationBase> getTypeDesignations(){
218
		Set<TypeDesignationBase> result = new HashSet<TypeDesignationBase>();
219
		for (TaxonNameBase taxonName : typifiedNames){
220
			result.addAll(taxonName.getTypeDesignations());
221
		}
222
		return result;
223
	}
224
	
225
//	/** 
226
//	 * Returns the set of {@link SpecimenTypeDesignation specimen type designations} that
227
//	 * typify <i>this</i> homotypical group including the status of these designations.
228
//	 *
229
//	 * @see	#getTypifiedNames()
230
//	 */
231
//	@OneToMany
232
//	@Cascade({CascadeType.SAVE_UPDATE})
233
//	public Set<SpecimenTypeDesignation> getSpecimenTypeDesignations() {
234
//		return specimenTypeDesignations;
235
//	}
236
//	/** 
237
//	 * @see #getSpecimenTypeDesignations()
238
//	 */
239
//	protected void setSpecimenTypeDesignations(Set<SpecimenTypeDesignation> specimenTypeDesignations) {
240
//		this.specimenTypeDesignations = specimenTypeDesignations;
241
//	}	
242
//	/** 
243
//	 * Adds a new {@link SpecimenTypeDesignation specimen type designation} to the set
244
//	 * of specimen type designations assigned to <i>this</i> homotypical group and eventually
245
//	 * (with a boolean parameter) also to the corresponding set of each of the
246
//	 * {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group.
247
//	 *
248
//	 * @param  specimenTypeDesignation	the specimen type designation to be added
249
//	 * @param  addToAllNames	the boolean flag indicating whether the addition will also
250
//	 * 							carried out for each taxon name
251
//	 * 
252
//	 * @see 			  		TaxonNameBase#getSpecimenTypeDesignations()
253
//	 * @see 			  		SpecimenTypeDesignation
254
//	 */
255
//	public void addSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation, boolean addToAllNames) {
256
//		if (specimenTypeDesignation != null){
257
//			specimenTypeDesignation.setHomotypicalGroup(this);
258
//			specimenTypeDesignations.add(specimenTypeDesignation);
259
//		}
260
//		if (addToAllNames){
261
//			for (TaxonNameBase taxonNameBase : this.typifiedNames){
262
//				taxonNameBase.addSpecimenTypeDesignation(specimenTypeDesignation);
263
//			}
264
//		}
265
//	}	
266
//	/** 
267
//	 * Removes one element from the set of {@link SpecimenTypeDesignation specimen type designations} assigned to the
268
//	 * {@link HomotypicalGroup homotypical group} to which this {@link TaxonNameBase taxon name} belongs.
269
//	 * The same element will be removed from the corresponding set of each of
270
//	 * the taxon names belonging to <i>this</i> homotypical group. Furthermore the
271
//	 * homotypical group attribute of the specimen type designation will be
272
//	 * nullified.
273
//	 *
274
//	 * @param  specimenTypeDesignation  the specimen type designation which should be deleted
275
//	 * @see     		  		#getSpecimenTypeDesignations()
276
//	 * @see    					#addSpecimenTypeDesignation(SpecimenTypeDesignation, boolean)
277
//	 * @see     		  		TaxonNameBase#removeSpecimenTypeDesignation(SpecimenTypeDesignation)
278
//	 * @see     		  		SpecimenTypeDesignation#getHomotypicalGroup()
279
//	 */
280
//	public void removeSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation) {
281
//		if (specimenTypeDesignation != null){
282
//			specimenTypeDesignation.setHomotypicalGroup(null);
283
//			specimenTypeDesignations.remove(specimenTypeDesignation);
284
//		}
285
//		for (TaxonNameBase taxonNameBase : this.typifiedNames){
286
//			taxonNameBase.removeSpecimenTypeDesignation(specimenTypeDesignation);
287
//		}
288
//	}	
289

    
290
	
291
//	/** 
292
//	 * Returns the set of {@link NameTypeDesignation name type designations} that
293
//	 * typify <i>this</i> homotypical group including the status of these designations.
294
//	 *
295
//	 * @see	#getTypifiedNames()
296
//	 */
297
//	@OneToMany
298
//	@Cascade({CascadeType.SAVE_UPDATE})
299
//	public Set<NameTypeDesignation> getNameTypeDesignations() {
300
//		return nameTypeDesignations;
301
//	}
302
//	/** 
303
//	 * @see #getNameTypeDesignations()
304
//	 */
305
//	protected void setNameTypeDesignations(Set<NameTypeDesignation> nameTypeDesignations) {
306
//		this.nameTypeDesignations = nameTypeDesignations;
307
//	}	
308
//	/** 
309
//	 * Adds a new {@link NameTypeDesignation name type designation} to the set
310
//	 * of name type designations assigned to <i>this</i> homotypical group and eventually
311
//	 * (with a boolean parameter) also to the corresponding set of each of the
312
//	 * {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group.
313
//	 *
314
//	 * @param  nameTypeDesignation	the name type designation to be added
315
//	 * @param  addToAllNames	the boolean flag indicating whether the addition will also
316
//	 * 							carried out for each taxon name
317
//	 * 
318
//	 * @see 			  		TaxonNameBase#getNameTypeDesignations()
319
//	 * @see 			  		NameTypeDesignation
320
//	 */
321
//	public void addNameTypeDesignation(NameTypeDesignation nameTypeDesignation, boolean addToAllNames) {
322
//		if (nameTypeDesignation != null){
323
//			nameTypeDesignation.setHomotypicalGroup(this);
324
//			nameTypeDesignations.add(nameTypeDesignation);
325
//		}
326
//		if (addToAllNames){
327
//			for (TaxonNameBase taxonNameBase : this.typifiedNames){
328
//				taxonNameBase.addNameTypeDesignation(nameTypeDesignation);
329
//			}
330
//		}
331
//	}	
332
//	/** 
333
//	 * Removes one element from the set of {@link NameTypeDesignation name type designations} assigned to the
334
//	 * {@link HomotypicalGroup homotypical group} to which this {@link TaxonNameBase taxon name} belongs.
335
//	 * The same element will be removed from the corresponding set of each of
336
//	 * the taxon names belonging to <i>this</i> homotypical group. Furthermore the
337
//	 * homotypical group attribute of the name type designation will be
338
//	 * nullified.
339
//	 *
340
//	 * @param  nameTypeDesignation  the name type designation which should be deleted
341
//	 * @see     		  		#getNameTypeDesignations()
342
//	 * @see    					#addNameTypeDesignation(NameTypeDesignation, boolean)
343
//	 * @see     		  		TaxonNameBase#removeNameTypeDesignation(NameTypeDesignation)
344
//	 * @see     		  		NameTypeDesignation#getHomotypicalGroup()
345
//	 */
346
//	public void removeNameTypeDesignation(NameTypeDesignation nameTypeDesignation) {
347
//		if (nameTypeDesignation != null){
348
//			nameTypeDesignation.setHomotypicalGroup(null);
349
//			nameTypeDesignations.remove(nameTypeDesignation);
350
//		}
351
//		for (TaxonNameBase taxonNameBase : this.typifiedNames){
352
//			taxonNameBase.removeNameTypeDesignation(nameTypeDesignation);
353
//		}
354
//	}	
355
	
356
	
357
	/**
358
	 * Retrieves the ordered list (depending on the date of publication) of
359
	 * {@link taxon.Synonym synonyms} (according to a given reference)
360
	 * the {@link TaxonNameBase taxon names} of which belong to <i>this</i> homotypical group.
361
	 * If other names are part of <i>this</i> group that are not considered synonyms
362
	 * according to the respective reference, then they will not be included in
363
	 * the result set.
364
	 * 
365
	 * @deprecated synonyms should not depend on the sec. Therefore this method will be removed in 
366
	 * version 3.1 or higher. Use {@link Taxon#getSynonymsInGroup(HomotypicalGroup)} instead. But be
367
	 * aware that the semantics is slightly different.
368
	 * @param  sec	the reference whose treatment is to be considered
369
	 * @return		the ordered list of synonyms
370
	 * @see			TaxonNameBase#getSynonyms()
371
	 * @see			TaxonNameBase#getTaxa()
372
	 * @see			taxon.Synonym
373
	 */
374
	@Deprecated
375
	public List<Synonym> getSynonymsInGroup(Reference sec){
376
		List<Synonym> result = new ArrayList<Synonym>();
377
		for (TaxonNameBase<?, ?>name : this.getTypifiedNames()){
378
			for (Synonym synonym : name.getSynonyms()){
379
				if ( (synonym.getSec() == null && sec == null) ||
380
						synonym.getSec() != null && synonym.getSec().equals(sec)){
381
					result.add(synonym);
382
				}
383
			}
384
		}
385
		Collections.sort(result, new TaxonComparator());
386
		return result;
387
	}
388
	
389
    /**
390
     * Creates a basionym relationship to all other names in this names homotypical
391
     * group. 
392
     * 
393
     * @see HomotypicalGroup.setGroupBasionym(TaxonNameBase basionymName)
394
     *
395
     * @param basionymName
396
     * @throws IllegalArgumentException if basionymName is not member in this homotypical group
397
     */
398
	public void setGroupBasionym(TaxonNameBase basionymName) throws IllegalArgumentException{
399
    	setGroupBasionym(basionymName, null, null, null);
400
    }	
401
    
402
	public void setGroupBasionym(TaxonNameBase basionymName, Reference citation, String microCitation, String ruleConsidered) 
403
    			throws IllegalArgumentException {
404
    	if (! typifiedNames.contains(basionymName)){
405
        	throw new IllegalArgumentException("Name to be set as basionym/original combination must be part of the homotypical group but is not");
406
        }
407
        if (typifiedNames.size() < 2){return;}
408
//        
409
    	//Add new relations
410
        for (TaxonNameBase name : typifiedNames) {
411
    		if (!name.equals(basionymName)) {
412
		    	name.addRelationshipFromName(basionymName, NameRelationshipType.BASIONYM(), citation, microCitation, ruleConsidered);
413
			}
414
    	}
415
    }
416
    
417
    /**
418
     * Removes all basionym relationships between basionymName and any other name 
419
     * in its homotypic group
420
     *
421
     * @param basionymName
422
     */
423
     public static void removeGroupBasionym(TaxonNameBase basionymName) {
424
    	 HomotypicalGroup homotypicalGroup = basionymName.getHomotypicalGroup();
425
         Set<NameRelationship> relations = basionymName.getRelationsFromThisName();
426
         Set<NameRelationship> removeRelations = new HashSet<NameRelationship>();
427
        
428
         for (NameRelationship relation : relations) {
429
                
430
                 // If this is a basionym relation, and toName is in the homotypical group,
431
                 //      remove the relationship.
432
                 if (relation.getType().isBasionymRelation() &&
433
                                 relation.getToName().getHomotypicalGroup().equals(homotypicalGroup)) {
434
                         removeRelations.add(relation);
435
                 }
436
         }
437
         
438
          // Removing relations from a set through which we are iterating causes a
439
          //      ConcurrentModificationException. Therefore, we delete the targeted
440
          //      relations in a second step.
441
          for (NameRelationship relation : removeRelations) {
442
                  basionymName.removeNameRelationship(relation);
443
          }
444
     }
445
	
446
	
447
	/**
448
	 * Returns all taxon names in the homotypical group that do not have an 'is_basionym_for' (zool.: 'is_original_combination_for') 
449
	 * or a replaced synonym relationship.
450
	 * @return
451
	 */
452
	@Transient
453
	public Set<TaxonNameBase> getUnrelatedNames(){
454
		Set<NameRelationship> set = getBasionymOrReplacedSynonymRelations(true, true);
455
		Set<TaxonNameBase> result = new HashSet<TaxonNameBase>();
456
		result.addAll(this.getTypifiedNames());
457
		for (NameRelationship nameRelationship : set){
458
			result.remove(nameRelationship.getFromName());
459
			result.remove(nameRelationship.getToName());
460
		}
461
		return result;
462
	}	
463
	
464
	/**
465
	 * Returns all taxon names in the homotypical group that are new combinations (have a basionym/original combination 
466
	 * or a replaced synonym).
467
	 * @return
468
	 */
469
	@Transient
470
	public Set<TaxonNameBase> getNewCombinations(){
471
		Set<NameRelationship> set = getBasionymOrReplacedSynonymRelations(true, true);
472
		Set<TaxonNameBase> result = new HashSet<TaxonNameBase>();
473
		for (NameRelationship nameRelationship : set){
474
			result.add(nameRelationship.getToName());
475
		}
476
		return result;
477
	}	
478

    
479
	
480
	
481
	/**
482
	 * Returns all taxon names in the homotypical group that have an 'is_basionym_for' (zool.: 'is_original_combination_for') 
483
	 * or a replaced synonym relationship.
484
	 * @return
485
	 */
486
	@Transient
487
	public Set<TaxonNameBase> getBasionymsOrReplacedSynonyms(){
488
		Set<NameRelationship> set = getBasionymOrReplacedSynonymRelations(true, true);
489
		Set<TaxonNameBase> result = new HashSet<TaxonNameBase>();
490
		for (NameRelationship nameRelationship : set){
491
			result.add(nameRelationship.getFromName());
492
		}
493
		return result;
494
	}	
495
	
496
	/**
497
	 * Returns all taxon names in the homotypical group that have a 'is_basionym_for' (zool.: 'is_original_combination_for') relationship.
498
	 * @return
499
	 */
500
	@Transient
501
	public Set<TaxonNameBase> getBasionyms(){
502
		Set<NameRelationship> set = getBasionymOrReplacedSynonymRelations(true, false);
503
		Set<TaxonNameBase> result = new HashSet<TaxonNameBase>();
504
		for (NameRelationship nameRelationship : set){
505
			result.add(nameRelationship.getFromName());
506
		}
507
		return result;
508
	}
509

    
510
	/**
511
	 * Returns all taxon names in the homotypical group that have a 'is_replaced_synonym_for' relationship.
512
	 * @return
513
	 */
514
	@Transient
515
	public Set<TaxonNameBase> getReplacedSynonym(){
516
		Set<NameRelationship> set = getBasionymOrReplacedSynonymRelations(false, true);
517
		Set<TaxonNameBase> result = new HashSet<TaxonNameBase>();
518
		for (NameRelationship nameRelationship : set){
519
			result.add(nameRelationship.getFromName());
520
		}
521
		return result;
522
	}
523
	
524
	/**
525
	 * Returns the name relationships that represent either a basionym (original combination) relationship or
526
	 * a replaced synonym relationship.  
527
	 * @return
528
	 */
529
	@Transient
530
	public Set<NameRelationship> getBasionymAndReplacedSynonymRelations(){
531
		return getBasionymOrReplacedSynonymRelations(true, true);
532
	}
533
	
534
	/**
535
	 * Computes all basionym and replaced synonym relationships between names in this group.
536
	 * If <code>doBasionym</code> is <code>false</code> basionym relationships are excluded.
537
	 * If <code>doReplacedSynonym</code> is <code>false</code> replaced synonym relationships are excluded.
538
	 * @param doBasionym
539
	 * @param doReplacedSynonym
540
	 * @return
541
	 */
542
	@Transient
543
	private Set<NameRelationship> getBasionymOrReplacedSynonymRelations(boolean doBasionym, boolean doReplacedSynonym){
544
		Set<NameRelationship> result = new HashSet<NameRelationship>(); 
545
		Set<TaxonNameBase> names = this.getTypifiedNames();
546
		if (names.size() > 1){
547
			for (TaxonNameBase name : names){
548
				Set nameRels = name.getNameRelations();
549
				//TODO make getNameRelations generic
550
				for (Object obj : nameRels){
551
					NameRelationship nameRel = (NameRelationship)obj;
552
					NameRelationshipType type = nameRel.getType();
553
					if ( type.isBasionymRelation() && doBasionym){
554
						if (testRelatedNameInThisGroup(nameRel)){
555
							result.add(nameRel);
556
						}else{
557
							logger.warn("Name has basionym relation to a name that is not in the same homotypical group");
558
						}
559
					}else if (type.isReplacedSynonymRelation() && doReplacedSynonym)  {
560
						if (testRelatedNameInThisGroup(nameRel)){
561
							result.add(nameRel);
562
						}else{
563
							logger.warn("Name has replaced synonym relation to a name that is not in the same homotypical group");
564
						}
565
					}
566
				}
567
			}
568
		}
569
		return result;
570
	}
571
	
572
	private boolean testRelatedNameInThisGroup(NameRelationship nameRel){
573
		TaxonNameBase toName = nameRel.getToName();
574
		return (this.getTypifiedNames().contains(toName));
575
	}
576
	
577
	private boolean isBasionymOrRepSynRel(NameRelationshipType relType){
578
		if (relType == null){
579
			throw new IllegalArgumentException("NameRelationshipType should never be null");
580
		}else if (relType.equals(NameRelationshipType.BASIONYM())) {
581
			return true;
582
		}else if (relType.equals(NameRelationshipType.REPLACED_SYNONYM())){
583
			return true;
584
		}else{
585
			return false;
586
		}
587
	}
588
	
589
	
590
}
(4-4/26)