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.HashSet;
15
import java.util.List;
16
import java.util.Set;
17

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

    
30
import org.apache.log4j.Logger;
31
import org.hibernate.envers.Audited;
32

    
33
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
34
import eu.etaxonomy.cdm.model.reference.Reference;
35
import eu.etaxonomy.cdm.model.taxon.Synonym;
36
import eu.etaxonomy.cdm.model.taxon.TaxonComparator;
37

    
38

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

    
77
	private static final Logger logger = Logger.getLogger(HomotypicalGroup.class);
78

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

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

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

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

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

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

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