Project

General

Profile

Download (47.8 KB) Statistics
| Branch: | Tag: | Revision:
1 9479da48 Andreas Müller
/**
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 1cfc54ab Andreas Müller
import java.lang.reflect.Method;
13 396aee74 Andreas Müller
import java.util.HashSet;
14
import java.util.Set;
15
16 33508d06 a.babadshanjan
import javax.persistence.Column;
17 396aee74 Andreas Müller
import javax.persistence.Entity;
18
import javax.persistence.FetchType;
19
import javax.persistence.Inheritance;
20
import javax.persistence.InheritanceType;
21
import javax.persistence.ManyToMany;
22
import javax.persistence.ManyToOne;
23
import javax.persistence.OneToMany;
24 b70a7f94 Andreas Kohlbecker
import javax.persistence.Transient;
25 827f3b3c a.babadshanjan
import javax.xml.bind.annotation.XmlAccessType;
26
import javax.xml.bind.annotation.XmlAccessorType;
27
import javax.xml.bind.annotation.XmlAttribute;
28
import javax.xml.bind.annotation.XmlElement;
29
import javax.xml.bind.annotation.XmlElementWrapper;
30 76b4a40f a.babadshanjan
import javax.xml.bind.annotation.XmlIDREF;
31 9d0d8d15 a.babadshanjan
import javax.xml.bind.annotation.XmlRootElement;
32 76b4a40f a.babadshanjan
import javax.xml.bind.annotation.XmlSchemaType;
33 827f3b3c a.babadshanjan
import javax.xml.bind.annotation.XmlType;
34 9479da48 Andreas Müller
35 396aee74 Andreas Müller
import org.apache.log4j.Logger;
36
import org.hibernate.annotations.Cascade;
37
import org.hibernate.annotations.CascadeType;
38
import org.hibernate.annotations.Index;
39
import org.hibernate.annotations.Table;
40 ee91bcd9 ben.clark
import org.hibernate.envers.Audited;
41 fd7ee7b1 ben.clark
import org.hibernate.search.annotations.Field;
42 ee91bcd9 ben.clark
import org.springframework.util.ReflectionUtils;
43 396aee74 Andreas Müller
44
import eu.etaxonomy.cdm.model.common.IParsable;
45
import eu.etaxonomy.cdm.model.common.IReferencedEntity;
46
import eu.etaxonomy.cdm.model.common.IRelated;
47
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
48
import eu.etaxonomy.cdm.model.common.RelationshipBase;
49
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
50
import eu.etaxonomy.cdm.model.occurrence.Specimen;
51
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
52
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
53
import eu.etaxonomy.cdm.model.reference.StrictReferenceBase;
54
import eu.etaxonomy.cdm.model.taxon.Synonym;
55
import eu.etaxonomy.cdm.model.taxon.Taxon;
56
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
57
import eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy;
58
59 9479da48 Andreas Müller
/**
60 975192f9 m.geoffroy
 * The upmost (abstract) class for scientific taxon names regardless of any
61 c3440568 m.geoffroy
 * particular {@link NomenclaturalCode nomenclature code}. The scientific taxon name does not depend
62 85629348 m.geoffroy
 * on the use made of it in a publication or a treatment
63 09887ea6 m.geoffroy
 * ({@link eu.etaxonomy.cdm.model.taxon.TaxonBase taxon concept respectively potential taxon})
64
 * as an {@link eu.etaxonomy.cdm.model.taxon.Taxon "accepted" respectively "correct" (taxon) name}
65
 * or as a {@link eu.etaxonomy.cdm.model.taxon.Synonym synonym}.
66 9e86cd74 m.geoffroy
 * <P>
67
 * This class corresponds partially to: <ul>
68
 * <li> TaxonName according to the TDWG ontology
69
 * <li> ScientificName and CanonicalName according to the TCS
70
 * <li> ScientificName according to the ABCD schema
71
 * </ul>
72 19e7a39e m.geoffroy
 * 
73 9479da48 Andreas Müller
 * @author m.doering
74
 * @version 1.0
75
 * @created 08-Nov-2007 13:06:57
76
 */
77 827f3b3c a.babadshanjan
@XmlAccessorType(XmlAccessType.FIELD)
78 76b4a40f a.babadshanjan
@XmlType(name = "TaxonNameBase", propOrder = {
79 827f3b3c a.babadshanjan
    "appendedPhrase",
80
    "nomenclaturalMicroReference",
81 64c4a14d a.babadshanjan
    "nomenclaturalReference",
82 827f3b3c a.babadshanjan
    "rank",
83 33508d06 a.babadshanjan
    "fullTitleCache",
84
    "protectedFullTitleCache",
85 827f3b3c a.babadshanjan
    "homotypicalGroup",
86 ddae61ce a.babadshanjan
    "typeDesignations",
87 827f3b3c a.babadshanjan
    "relationsFromThisName",
88
    "relationsToThisName",
89 7baa835b a.babadshanjan
    "status",
90 ee91bcd9 ben.clark
    "descriptions",
91
    "taxonBases"
92 827f3b3c a.babadshanjan
})
93 9d0d8d15 a.babadshanjan
@XmlRootElement(name = "TaxonNameBase")
94 9479da48 Andreas Müller
@Entity
95 ee91bcd9 ben.clark
@Audited
96 9479da48 Andreas Müller
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
97 c281e68e Andreas Müller
@Table(appliesTo="TaxonNameBase", indexes = { @Index(name = "taxonNameBaseTitleCacheIndex", columnNames = { "titleCache" }) })
98 f6765014 ben.clark
public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INameCacheStrategy> extends IdentifiableEntity implements IReferencedEntity, IParsable, IRelated {
99 168723a2 a.babadshanjan
100 961ee94b Andreas Müller
	private static final long serialVersionUID = -4530368639601532116L;
101 b70a7f94 Andreas Kohlbecker
	private static final Logger logger = Logger.getLogger(TaxonNameBase.class);
102 827f3b3c a.babadshanjan
103 33508d06 a.babadshanjan
	@XmlElement(name = "FullTitleCache")
104 ee91bcd9 ben.clark
	@Column(length=330, name="fullTitleCache")
105 33508d06 a.babadshanjan
	private String fullTitleCache;
106
	
107
	//if true titleCache will not be automatically generated/updated
108
	@XmlElement(name = "ProtectedFullTitleCache")
109
	private boolean protectedFullTitleCache;
110
	
111 2595daef a.babadshanjan
    @XmlElementWrapper(name = "Descriptions")
112
    @XmlElement(name = "Description")
113 ee91bcd9 ben.clark
    @OneToMany(mappedBy="taxonName", fetch= FetchType.LAZY) 
114
	@Cascade({CascadeType.SAVE_UPDATE})
115 2595daef a.babadshanjan
	private Set<TaxonNameDescription> descriptions = new HashSet<TaxonNameDescription>();
116 71dcc146 Andreas Müller
	
117 76b4a40f a.babadshanjan
    @XmlElement(name = "AppendedPhrase")
118 fd7ee7b1 ben.clark
    @Field(index= org.hibernate.search.annotations.Index.TOKENIZED)
119 9479da48 Andreas Müller
	private String appendedPhrase;
120 827f3b3c a.babadshanjan
	
121 76b4a40f a.babadshanjan
    @XmlElement(name = "NomenclaturalMicroReference")
122 fd7ee7b1 ben.clark
    @Field(index= org.hibernate.search.annotations.Index.TOKENIZED)
123 9479da48 Andreas Müller
	private String nomenclaturalMicroReference;
124 827f3b3c a.babadshanjan
	
125
    @XmlAttribute
126 9479da48 Andreas Müller
	private boolean hasProblem = false;
127 827f3b3c a.babadshanjan
	
128 6680df00 Andreas Müller
    @XmlAttribute
129
    private int problemStarts = -1;
130
    
131
    @XmlAttribute
132
    private int problemEnds = -1;
133
    
134 dce4c9cb Andreas Müller
    @XmlElementWrapper(name = "TypeDesignations")
135
    @XmlElement(name = "TypeDesignation")
136 a2312bea a.babadshanjan
    @XmlIDREF
137
    @XmlSchemaType(name = "IDREF")
138 ee91bcd9 ben.clark
    @ManyToMany(fetch = FetchType.LAZY)
139
	//TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
140
	@Cascade(CascadeType.SAVE_UPDATE)
141 dce4c9cb Andreas Müller
	private Set<TypeDesignationBase> typeDesignations = new HashSet<TypeDesignationBase>();
142 827f3b3c a.babadshanjan
143 76b4a40f a.babadshanjan
    @XmlElement(name = "HomotypicalGroup")
144 dbff59db a.babadshanjan
    @XmlIDREF
145
    @XmlSchemaType(name = "IDREF")
146 ee91bcd9 ben.clark
    @ManyToOne(fetch = FetchType.LAZY)
147
	@Cascade({CascadeType.SAVE_UPDATE})
148
	private HomotypicalGroup homotypicalGroup;
149 827f3b3c a.babadshanjan
150
    @XmlElementWrapper(name = "RelationsFromThisName")
151
    @XmlElement(name = "RelationFromThisName")
152 ee91bcd9 ben.clark
    @OneToMany(mappedBy="relatedFrom", fetch= FetchType.LAZY)
153 ec1f7873 Andreas Müller
	//TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN}) => DELETE_ORPHAN does not work ( org.hibernate.HibernateException: Don't change the reference to a collection with cascade="all-delete-orphan": eu.etaxonomy.cdm.model.name.TaxonNameBase.relationsFromThisName)
154
	@Cascade(CascadeType.SAVE_UPDATE)
155 608eada2 Andreas Müller
	private Set<NameRelationship> relationsFromThisName = new HashSet<NameRelationship>();
156 827f3b3c a.babadshanjan
157
    @XmlElementWrapper(name = "RelationsToThisName")
158
    @XmlElement(name = "RelationToThisName")
159 76b4a40f a.babadshanjan
    @XmlIDREF
160 64c4a14d a.babadshanjan
    @XmlSchemaType(name = "IDREF")
161 ee91bcd9 ben.clark
    @OneToMany(mappedBy="relatedTo", fetch= FetchType.LAZY)
162 ec1f7873 Andreas Müller
	//@Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
163
	@Cascade(CascadeType.SAVE_UPDATE)
164 608eada2 Andreas Müller
	private Set<NameRelationship> relationsToThisName = new HashSet<NameRelationship>();
165 827f3b3c a.babadshanjan
166 ee91bcd9 ben.clark
    @XmlElementWrapper(name = "NomenclaturalStatuses")
167 64c4a14d a.babadshanjan
    @XmlElement(name = "NomenclaturalStatus")
168 ee91bcd9 ben.clark
    @OneToMany(fetch= FetchType.LAZY)
169
	@Cascade({CascadeType.SAVE_UPDATE})
170 608eada2 Andreas Müller
	private Set<NomenclaturalStatus> status = new HashSet<NomenclaturalStatus>();
171 827f3b3c a.babadshanjan
172 ee91bcd9 ben.clark
    @XmlElementWrapper(name = "TaxonBases")
173
    @XmlElement(name = "TaxonBase")
174
    @XmlIDREF
175
    @XmlSchemaType(name = "IDREF")
176
    @OneToMany(mappedBy="name", fetch= FetchType.LAZY)
177 608eada2 Andreas Müller
	private Set<TaxonBase> taxonBases = new HashSet<TaxonBase>();
178 33508d06 a.babadshanjan
    
179 76b4a40f a.babadshanjan
    @XmlElement(name = "Rank")
180
	@XmlIDREF
181
	@XmlSchemaType(name = "IDREF")
182 ee91bcd9 ben.clark
	@ManyToOne(fetch = FetchType.LAZY)
183 9479da48 Andreas Müller
	private Rank rank;
184 827f3b3c a.babadshanjan
185 ee91bcd9 ben.clark
186
	@XmlElement(name = "NomenclaturalReference")
187 64c4a14d a.babadshanjan
    @XmlIDREF
188
    @XmlSchemaType(name = "IDREF")
189 ee91bcd9 ben.clark
    @ManyToOne(fetch = FetchType.LAZY)
190
	@Cascade({CascadeType.SAVE_UPDATE})
191
	private ReferenceBase nomenclaturalReference;
192 1cfc54ab Andreas Müller
	
193 2a486d28 Andreas Müller
// ************* CONSTRUCTORS *************/	
194 12655d36 m.geoffroy
	/** 
195 85629348 m.geoffroy
	 * Class constructor: creates a new empty taxon name.
196 12655d36 m.geoffroy
	 * 
197
	 * @see #TaxonNameBase(Rank)
198
	 * @see #TaxonNameBase(HomotypicalGroup)
199
	 * @see #TaxonNameBase(Rank, HomotypicalGroup)
200
	 */
201 9479da48 Andreas Müller
	public TaxonNameBase() {
202 ee91bcd9 ben.clark
		super();
203 9479da48 Andreas Müller
	}
204 12655d36 m.geoffroy
	/** 
205 85629348 m.geoffroy
	 * Class constructor: creates a new taxon name
206 09887ea6 m.geoffroy
	 * only containing its {@link Rank rank}.
207 12655d36 m.geoffroy
	 * 
208 b9d0e8d2 m.geoffroy
	 * @param  rank  the rank to be assigned to <i>this</i> taxon name
209 6a9737e8 m.geoffroy
	 * @see    		 #TaxonNameBase()
210
	 * @see    		 #TaxonNameBase(HomotypicalGroup)
211
	 * @see    		 #TaxonNameBase(Rank, HomotypicalGroup)
212 12655d36 m.geoffroy
	 */
213 9479da48 Andreas Müller
	public TaxonNameBase(Rank rank) {
214 b18c6379 Andreas Müller
		this(rank, null);
215
	}
216 12655d36 m.geoffroy
	/** 
217 85629348 m.geoffroy
	 * Class constructor: creates a new taxon name
218 9dac7f49 m.geoffroy
	 * only containing its {@link HomotypicalGroup homotypical group}.
219 85629348 m.geoffroy
	 * The new taxon name will be also added to the set of taxon names
220 740cb3b5 m.geoffroy
	 * belonging to this homotypical group.
221 12655d36 m.geoffroy
	 * 
222 b9d0e8d2 m.geoffroy
	 * @param  homotypicalGroup  the homotypical group to which <i>this</i> taxon name belongs
223 6a9737e8 m.geoffroy
	 * @see    					 #TaxonNameBase()
224
	 * @see    					 #TaxonNameBase(Rank)
225
	 * @see    					 #TaxonNameBase(Rank, HomotypicalGroup)
226 12655d36 m.geoffroy
	 */
227 b18c6379 Andreas Müller
	public TaxonNameBase(HomotypicalGroup homotypicalGroup) {
228
		this(null, homotypicalGroup);
229
	}
230 12655d36 m.geoffroy
	/** 
231 85629348 m.geoffroy
	 * Class constructor: creates a new taxon name
232 09887ea6 m.geoffroy
	 * only containing its {@link Rank rank} and
233 9dac7f49 m.geoffroy
	 * its {@link HomotypicalGroup homotypical group}.
234 740cb3b5 m.geoffroy
	 * The new taxon name will be also added to the set of taxon names
235
	 * belonging to this homotypical group.
236 12655d36 m.geoffroy
	 * 
237 6a9737e8 m.geoffroy
	 * @param  rank  			 the rank to be assigned to <i>this</i> taxon name
238 b9d0e8d2 m.geoffroy
	 * @param  homotypicalGroup  the homotypical group to which <i>this</i> taxon name belongs
239 6a9737e8 m.geoffroy
	 * @see    					 #TaxonNameBase()
240
	 * @see    					 #TaxonNameBase(Rank)
241
	 * @see    					 #TaxonNameBase(HomotypicalGroup)
242 12655d36 m.geoffroy
	 */
243 b18c6379 Andreas Müller
	public TaxonNameBase(Rank rank, HomotypicalGroup homotypicalGroup) {
244 9479da48 Andreas Müller
		super();
245
		this.setRank(rank);
246 b18c6379 Andreas Müller
		if (homotypicalGroup == null){
247
			homotypicalGroup = new HomotypicalGroup();
248
		}
249
		homotypicalGroup.addTypifiedName(this);
250 9479da48 Andreas Müller
	}
251 2a486d28 Andreas Müller
	
252
//********* METHODS **************************************/
253 9017e2de Andreas Müller
	
254 12655d36 m.geoffroy
	/**
255 b9d0e8d2 m.geoffroy
	 * Returns the boolean value "false" since the components of <i>this</i> taxon name
256 eb7e638a m.geoffroy
	 * cannot follow the rules of a corresponding {@link NomenclaturalCode nomenclatural code}
257
	 * which is not defined for this class. The nomenclature code depends on
258 12655d36 m.geoffroy
	 * the concrete name subclass ({@link BacterialName BacterialName},
259
	 * {@link BotanicalName BotanicalName}, {@link CultivarPlantName CultivarPlantName},
260
	 * {@link ZoologicalName ZoologicalName} or {@link ViralName ViralName}) 
261 eb7e638a m.geoffroy
	 * to which a taxon name belongs.
262 12655d36 m.geoffroy
	 *  
263 eb7e638a m.geoffroy
	 * @return  false
264 12655d36 m.geoffroy
	 */
265 b70a7f94 Andreas Kohlbecker
	@Transient
266 9479da48 Andreas Müller
	public abstract boolean isCodeCompliant();
267
	
268 33508d06 a.babadshanjan
	public abstract String generateFullTitle();
269 9479da48 Andreas Müller
270 b70a7f94 Andreas Kohlbecker
	@Transient
271 33508d06 a.babadshanjan
	public String getFullTitleCache(){
272
		if (protectedFullTitleCache){
273
			return this.fullTitleCache;			
274
		}
275
		if (fullTitleCache == null){
276 e3a02794 a.babadshanjan
			this.setFullTitleCache(generateFullTitle(), protectedFullTitleCache);
277 33508d06 a.babadshanjan
		}
278
		return fullTitleCache;
279
	}
280
281
    public void setFullTitleCache(String fullTitleCache){
282
		setFullTitleCache(fullTitleCache, PROTECTED);
283
	}
284
	
285
	public void setFullTitleCache(String fullTitleCache, boolean protectCache){
286
		//TODO truncation of full title cache
287 c0bd32ce a.babadshanjan
		if (fullTitleCache != null && fullTitleCache.length() > 329){
288
			logger.warn("Truncation of full title cache: " + this.toString() + "/" + fullTitleCache);
289
			fullTitleCache = fullTitleCache.substring(0, 329) + "...";
290
		}
291 33508d06 a.babadshanjan
		this.fullTitleCache = fullTitleCache;
292
		this.setProtectedFullTitleCache(protectCache);
293
	}
294
	
295
	public boolean isProtectedFullTitleCache() {
296
		return protectedFullTitleCache;
297
	}
298
299
	public void setProtectedFullTitleCache(boolean protectedFullTitleCache) {
300
		this.protectedFullTitleCache = protectedFullTitleCache;
301
	}
302
	
303 12655d36 m.geoffroy
	/** 
304
	 * Returns the set of all {@link NameRelationship name relationships}
305 b9d0e8d2 m.geoffroy
	 * in which <i>this</i> taxon name is involved. A taxon name can be both source
306 12655d36 m.geoffroy
	 * in some name relationships or target in some others.
307
	 *  
308 09487e73 m.geoffroy
	 * @see    #getRelationsToThisName()
309
	 * @see    #getRelationsFromThisName()
310
	 * @see    #addNameRelationship(NameRelationship)
311 12655d36 m.geoffroy
	 * @see    #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
312
	 * @see    #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
313
	 */
314 b70a7f94 Andreas Kohlbecker
	@Transient
315 9479da48 Andreas Müller
	public Set<NameRelationship> getNameRelations() {
316 6ecda5d2 m.doering
		Set<NameRelationship> rels = new HashSet<NameRelationship>();
317
		rels.addAll(getRelationsFromThisName());
318
		rels.addAll(getRelationsToThisName());
319
		return rels;
320
	}
321 b92a6173 a.babadshanjan
	
322 6ecda5d2 m.doering
	/**
323 b9d0e8d2 m.geoffroy
	 * Creates a new {@link NameRelationship#NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, String) name relationship} from <i>this</i> taxon name to another taxon name
324
	 * and adds it both to the set of {@link #getRelationsFromThisName() relations from <i>this</i> taxon name} and
325 12655d36 m.geoffroy
	 * to the set of {@link #getRelationsToThisName() relations to the other taxon name}.
326
	 * 
327
	 * @param toName		  the taxon name of the target for this new name relationship
328
	 * @param type			  the type of this new name relationship
329
	 * @param ruleConsidered  the string which specifies the rule on which this name relationship is based
330 09487e73 m.geoffroy
	 * @see    				  #getRelationsToThisName()
331
	 * @see    				  #getNameRelations()
332 12655d36 m.geoffroy
	 * @see    				  #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
333
	 * @see    				  #addNameRelationship(NameRelationship)
334 6ecda5d2 m.doering
	 */
335
	public void addRelationshipToName(TaxonNameBase toName, NameRelationshipType type, String ruleConsidered){
336
		NameRelationship rel = new NameRelationship(toName, this, type, ruleConsidered);
337
	}
338 12655d36 m.geoffroy
	/**
339 b9d0e8d2 m.geoffroy
	 * Creates a new {@link NameRelationship#NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, String) name relationship} from another taxon name to <i>this</i> taxon name
340
	 * and adds it both to the set of {@link #getRelationsToThisName() relations to <i>this</i> taxon name} and
341 12655d36 m.geoffroy
	 * to the set of {@link #getRelationsFromThisName() relations from the other taxon name}.
342
	 * 
343
	 * @param fromName		  the taxon name of the source for this new name relationship
344
	 * @param type			  the type of this new name relationship
345
	 * @param ruleConsidered  the string which specifies the rule on which this name relationship is based
346 09487e73 m.geoffroy
	 * @see    				  #getRelationsFromThisName()
347
	 * @see    				  #getNameRelations()
348 12655d36 m.geoffroy
	 * @see    				  #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
349
	 * @see    				  #addNameRelationship(NameRelationship)
350
	 */
351 4dd3e141 m.doering
	public void addRelationshipFromName(TaxonNameBase fromName, NameRelationshipType type, String ruleConsidered){
352
		NameRelationship rel = new NameRelationship(this, fromName, type, ruleConsidered);
353
	}
354 12655d36 m.geoffroy
	/**
355
	 * Adds an existing {@link NameRelationship name relationship} either to the set of
356 b9d0e8d2 m.geoffroy
	 * {@link #getRelationsToThisName() relations to <i>this</i> taxon name} or to the set of
357
	 * {@link #getRelationsFromThisName() relations from <i>this</i> taxon name}. If neither the
358
	 * source nor the target of the name relationship match with <i>this</i> taxon name
359 12655d36 m.geoffroy
	 * no addition will be carried out.
360
	 * 
361 b9d0e8d2 m.geoffroy
	 * @param rel  the name relationship to be added to one of <i>this</i> taxon name's name relationships sets
362 09487e73 m.geoffroy
	 * @see    	   #getNameRelations()
363 12655d36 m.geoffroy
	 * @see    	   #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
364
	 * @see    	   #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
365
	 */
366 6ecda5d2 m.doering
	protected void addNameRelationship(NameRelationship rel) {
367
		if (rel!=null && rel.getToName().equals(this)){
368
			this.relationsToThisName.add(rel);
369
		}else if(rel!=null && rel.getFromName().equals(this)){
370
			this.relationsFromThisName.add(rel);			
371
		}else{
372
			//TODO: raise error???
373
		}
374 9479da48 Andreas Müller
	}
375 12655d36 m.geoffroy
	/** 
376
	 * Removes one {@link NameRelationship name relationship} from one of both sets of
377 b9d0e8d2 m.geoffroy
	 * {@link #getNameRelations() name relationships} in which <i>this</i> taxon name is involved.
378 09487e73 m.geoffroy
	 * The name relationship will also be removed from one of both sets belonging
379
	 * to the second taxon name involved. Furthermore the fromName and toName
380
	 * attributes of the name relationship object will be nullified. 
381 12655d36 m.geoffroy
	 *
382
	 * @param  nameRelation  the name relationship which should be deleted from one of both sets
383 6a9737e8 m.geoffroy
	 * @see    				 #getNameRelations()
384 12655d36 m.geoffroy
	 */
385 6ecda5d2 m.doering
	public void removeNameRelationship(NameRelationship nameRelation) {
386 b92a6173 a.babadshanjan
		
387
		TaxonNameBase fromName = nameRelation.getFromName();
388
		TaxonNameBase toName = nameRelation.getToName();
389
390
		if (nameRelation != null) {
391
			nameRelation.setToName(null);
392
			nameRelation.setFromName(null);
393
		}
394
		
395
		if (fromName != null) {
396
			fromName.removeNameRelationship(nameRelation);
397
		}
398
		
399
		if (toName != null) {
400
			toName.removeNameRelationship(nameRelation);
401
		}
402
		
403
		this.relationsToThisName.remove(nameRelation);
404
		this.relationsFromThisName.remove(nameRelation);
405
	}
406
		
407
	public void removeTaxonName(TaxonNameBase taxonName) {
408
		Set<NameRelationship> nameRelationships = new HashSet<NameRelationship>();
409
//		nameRelationships.addAll(this.getNameRelations());
410
		nameRelationships.addAll(this.getRelationsFromThisName());
411
		nameRelationships.addAll(this.getRelationsToThisName());
412
		for(NameRelationship nameRelationship : nameRelationships) {
413
			// remove name relationship from this side 
414
			if (nameRelationship.getFromName().equals(this) && nameRelationship.getToName().equals(taxonName)) {
415
				this.removeNameRelation(nameRelationship);
416
			}
417
		}
418
	}
419
	
420
	public void removeNameRelation(NameRelationship nameRelation) {
421
		nameRelation.setToName(null);
422
	
423
		TaxonNameBase name = nameRelation.getFromName();
424
		if (name != null){
425
			nameRelation.setFromName(null);
426
			name.removeNameRelation(nameRelation);
427
		}
428 6ecda5d2 m.doering
		this.relationsToThisName.remove(nameRelation);
429
		this.relationsFromThisName.remove(nameRelation);
430 9479da48 Andreas Müller
	}
431 6ecda5d2 m.doering
	
432
	
433 b3262b1b m.geoffroy
	/**
434
	 * Does exactly the same as the addNameRelationship method provided that
435
	 * the given relationship is a name relationship.
436
	 * 
437 b9d0e8d2 m.geoffroy
	 * @param relation  the relationship to be added to one of <i>this</i> taxon name's name relationships sets
438 b3262b1b m.geoffroy
	 * @see    	   		#addNameRelationship(NameRelationship)
439
	 * @see    	   		#getNameRelations()
440
	 * @see    	   		NameRelationship
441 09887ea6 m.geoffroy
	 * @see    	   		eu.etaxonomy.cdm.model.common.RelationshipBase
442 b3262b1b m.geoffroy
	 */
443 705e0850 Andreas Müller
	public void addRelationship(RelationshipBase relation) {
444
		if (relation instanceof NameRelationship){
445
			addNameRelationship((NameRelationship)relation);
446 d27ee9b1 Andreas Müller
			if (relation.getType() != null && 
447 bef42c31 Andreas Müller
						( relation.getType().equals(NameRelationshipType.BASIONYM()) ||
448
						  relation.getType().equals(NameRelationshipType.REPLACED_SYNONYM()) 
449
						 )){
450 d27ee9b1 Andreas Müller
				TaxonNameBase fromName = ((NameRelationship)relation).getFromName();
451
				TaxonNameBase toName = ((NameRelationship)relation).getToName();
452
				fromName.getHomotypicalGroup().merge(toName.getHomotypicalGroup());
453
			}		
454 705e0850 Andreas Müller
		}else{
455 d27ee9b1 Andreas Müller
			logger.warn("Relationship not of type NameRelationship!");
456 705e0850 Andreas Müller
			//TODO exception handling
457
		}
458 7ebeb288 Andreas Müller
	}
459
460
	
461 09487e73 m.geoffroy
	/** 
462
	 * Returns the set of all {@link NameRelationship name relationships}
463 b9d0e8d2 m.geoffroy
	 * in which <i>this</i> taxon name is involved as a source.
464 09487e73 m.geoffroy
	 *  
465
	 * @see    #getNameRelations()
466
	 * @see    #getRelationsToThisName()
467
	 * @see    #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
468
	 */
469 6ecda5d2 m.doering
	public Set<NameRelationship> getRelationsFromThisName() {
470
		return relationsFromThisName;
471 9479da48 Andreas Müller
	}
472 ee91bcd9 ben.clark
473 09487e73 m.geoffroy
	/** 
474
	 * Returns the set of all {@link NameRelationship name relationships}
475 b9d0e8d2 m.geoffroy
	 * in which <i>this</i> taxon name is involved as a target.
476 09487e73 m.geoffroy
	 *  
477
	 * @see    #getNameRelations()
478
	 * @see    #getRelationsFromThisName()
479
	 * @see    #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
480
	 */
481 6ecda5d2 m.doering
	public Set<NameRelationship> getRelationsToThisName() {
482
		return relationsToThisName;
483 9479da48 Andreas Müller
	}
484
	
485 09487e73 m.geoffroy
	/** 
486
	 * Returns the set of {@link NomenclaturalStatus nomenclatural status} assigned
487 b9d0e8d2 m.geoffroy
	 * to <i>this</i> taxon name according to its corresponding nomenclature code.
488 09487e73 m.geoffroy
	 * This includes the {@link NomenclaturalStatusType type} of the nomenclatural status
489
	 * and the nomenclatural code rule considered.
490
	 *
491
	 * @see     NomenclaturalStatus
492
	 * @see     NomenclaturalStatusType
493
	 */
494 9479da48 Andreas Müller
	public Set<NomenclaturalStatus> getStatus() {
495
		return status;
496
	}
497 ee91bcd9 ben.clark
498 09487e73 m.geoffroy
	/** 
499
	 * Adds a new {@link NomenclaturalStatus nomenclatural status}
500 b9d0e8d2 m.geoffroy
	 * to <i>this</i> taxon name's set of nomenclatural status.
501 09487e73 m.geoffroy
	 *
502
	 * @param  nomStatus  the nomenclatural status to be added
503
	 * @see 			  #getStatus()
504
	 */
505 025f3199 Andreas Müller
	public void addStatus(NomenclaturalStatus nomStatus) {
506
		this.status.add(nomStatus);
507 9479da48 Andreas Müller
	}
508 ee91bcd9 ben.clark
	
509 09487e73 m.geoffroy
	/** 
510 b9d0e8d2 m.geoffroy
	 * Removes one element from the set of nomenclatural status of <i>this</i> taxon name.
511 09487e73 m.geoffroy
	 * Type and ruleConsidered attributes of the nomenclatural status object
512
	 * will be nullified.
513
	 *
514 b9d0e8d2 m.geoffroy
	 * @param  nomStatus  the nomenclatural status of <i>this</i> taxon name which should be deleted
515 09487e73 m.geoffroy
	 * @see     		  #getStatus()
516
	 */
517 025f3199 Andreas Müller
	public void removeStatus(NomenclaturalStatus nomStatus) {
518 09487e73 m.geoffroy
		//TODO to be implemented?
519
		logger.warn("not yet fully implemented?");
520 025f3199 Andreas Müller
		this.status.remove(nomStatus);
521 9479da48 Andreas Müller
	}
522
523 5c19d7f0 Andreas Müller
	
524
	/**
525 09887ea6 m.geoffroy
	 * Indicates whether <i>this</i> taxon name is a {@link NameRelationshipType#BASIONYM() basionym}
526
	 * or a {@link NameRelationshipType#REPLACED_SYNONYM() replaced synonym}
527 abc6aceb m.geoffroy
	 * of any other taxon name. Returns "true", if a basionym or a replaced 
528 09887ea6 m.geoffroy
	 * synonym {@link NameRelationship relationship} from <i>this</i> taxon name to another taxon name exists,
529 b9d0e8d2 m.geoffroy
	 * false otherwise (also in case <i>this</i> taxon name is the only one in the
530 09487e73 m.geoffroy
	 * homotypical group).
531 5c19d7f0 Andreas Müller
	 */
532 b70a7f94 Andreas Kohlbecker
	@Transient
533 5c19d7f0 Andreas Müller
	public boolean isOriginalCombination(){
534
		Set<NameRelationship> relationsFromThisName = this.getRelationsFromThisName();
535
		for (NameRelationship relation : relationsFromThisName) {
536
			if (relation.getType().equals(NameRelationshipType.BASIONYM()) ||
537
					relation.getType().equals(NameRelationshipType.REPLACED_SYNONYM())) {
538
				return true;
539
			}
540
		}
541
		return false;
542
	}
543
	
544 09487e73 m.geoffroy
	/**
545 09887ea6 m.geoffroy
	 * Returns the taxon name which is the {@link NameRelationshipType#BASIONYM() basionym} of <i>this</i> taxon name.
546 09487e73 m.geoffroy
	 * The basionym of a taxon name is its epithet-bringing synonym.
547 09887ea6 m.geoffroy
	 * For instance <i>Pinus abies</i> L. was published by Linnaeus and the botanist
548 b9d0e8d2 m.geoffroy
	 * Karsten transferred later <i>this</i> taxon to the genus Picea. Therefore,
549 09887ea6 m.geoffroy
	 * <i>Pinus abies</i> L. is the basionym of the new combination <i>Picea abies</i> (L.) H. Karst.
550 09487e73 m.geoffroy
	 */
551 b70a7f94 Andreas Kohlbecker
	@Transient
552 2a486d28 Andreas Müller
	public T getBasionym(){
553 6ecda5d2 m.doering
		//TODO: pick the right name relationships...
554 d27ee9b1 Andreas Müller
		logger.warn("get Basionym not yet implemented");
555 6ecda5d2 m.doering
		return null;
556 9479da48 Andreas Müller
	}
557 09487e73 m.geoffroy
	/**
558 09887ea6 m.geoffroy
	 * Assigns a taxon name as {@link NameRelationshipType#BASIONYM() basionym} of <i>this</i> taxon name.
559
	 * The basionym {@link NameRelationship relationship} will be added to <i>this</i> taxon name
560 09487e73 m.geoffroy
	 * and to the basionym. The basionym cannot have itself a basionym.
561 09887ea6 m.geoffroy
	 * The {@link HomotypicalGroup homotypical groups} of <i>this</i> taxon name and of the basionym
562
	 * will be {@link HomotypicalGroup#merge(HomotypicalGroup) merged}.
563
	 * 
564
	 * @param  basionym		the taxon name to be set as the basionym of <i>this</i> taxon name
565
	 * @see  				#getBasionym()
566
	 * @see  				#addBasionym(TaxonNameBase, String)
567 09487e73 m.geoffroy
	 */
568 d27ee9b1 Andreas Müller
	public void addBasionym(T basionym){
569
		addBasionym(basionym, null);
570 6ecda5d2 m.doering
	}
571 09487e73 m.geoffroy
	/**
572 09887ea6 m.geoffroy
	 * Assigns a taxon name as {@link NameRelationshipType#BASIONYM() basionym} of <i>this</i> taxon name
573 09487e73 m.geoffroy
	 * and keeps the nomenclatural rule considered for it. The basionym
574 09887ea6 m.geoffroy
	 * {@link NameRelationship relationship} will be added to <i>this</i> taxon name and to the basionym.
575
	 * The basionym cannot have itself a basionym.
576
	 * The {@link HomotypicalGroup homotypical groups} of <i>this</i> taxon name and of the basionym
577
	 * will be {@link HomotypicalGroup#merge(HomotypicalGroup) merged}.
578
	 * 
579
	 * @param  basionym			the taxon name to be set as the basionym of <i>this</i> taxon name
580
	 * @param  ruleConsidered	the string identifying the nomenclatural rule
581
	 * @see  					#getBasionym()
582
	 * @see  					#addBasionym(TaxonNameBase)
583 09487e73 m.geoffroy
	 */
584 d27ee9b1 Andreas Müller
	public void addBasionym(T basionym, String ruleConsidered){
585
		if (basionym != null){
586
			basionym.addRelationshipToName(this, NameRelationshipType.BASIONYM(), ruleConsidered);
587
		}
588
	}
589
	
590 09887ea6 m.geoffroy
	/** 
591
	 * Removes the {@link NameRelationshipType#BASIONYM() basionym} {@link NameRelationship relationship} from the set of
592
	 * {@link #getRelationsToThisName() name relationships to} <i>this</i> taxon name. The same relationhip will be
593
	 * removed from the set of {@link #getRelationsFromThisName() name relationships from} the taxon name
594
	 * previously used as basionym.
595
	 *
596
	 * @see   #getBasionym()
597
	 * @see   #addBasionym(TaxonNameBase)
598
	 */
599 d27ee9b1 Andreas Müller
	public void removeBasionym(){
600
		//TODO implement
601
		logger.warn("not yet implemented");
602 9479da48 Andreas Müller
	}
603
604 09887ea6 m.geoffroy
	/**
605
	 * Returns the {@link eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy cache strategy} used to generate
606
	 * several strings corresponding to <i>this</i> taxon name
607
	 * (in particular taxon name caches and author strings).
608
	 * 
609
	 * @return  the cache strategy used for <i>this</i> taxon name
610
	 * @see 	eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy
611
	 * @see     eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy
612
	 */
613 b70a7f94 Andreas Kohlbecker
	@Transient
614 dadf5cd0 Andreas Kohlbecker
	public abstract S getCacheStrategy();
615 09887ea6 m.geoffroy
	/** 
616
	 * @see 	#getCacheStrategy()
617
	 */
618 ee91bcd9 ben.clark
	
619 dadf5cd0 Andreas Kohlbecker
	public abstract void setCacheStrategy(S cacheStrategy);
620 9479da48 Andreas Müller
	
621 8eebe79d m.geoffroy
	/** 
622 b9d0e8d2 m.geoffroy
	 * Returns the taxonomic {@link Rank rank} of <i>this</i> taxon name.
623 8eebe79d m.geoffroy
	 *
624
	 * @see 	Rank
625
	 */
626 9479da48 Andreas Müller
	public Rank getRank(){
627
		return this.rank;
628
	}
629 ee91bcd9 ben.clark
	
630 8eebe79d m.geoffroy
	/**
631
	 * @see  #getRank()
632
	 */
633 9479da48 Andreas Müller
	public void setRank(Rank rank){
634
		this.rank = rank;
635
	}
636
637 8eebe79d m.geoffroy
	/** 
638 09887ea6 m.geoffroy
	 * Returns the {@link eu.etaxonomy.cdm.model.reference.INomenclaturalReference nomenclatural reference} of <i>this</i> taxon name.
639 8eebe79d m.geoffroy
	 * The nomenclatural reference is here meant to be the one publication
640 b9d0e8d2 m.geoffroy
	 * <i>this</i> taxon name was originally published in while fulfilling the formal
641 a7d9a8c1 m.geoffroy
	 * requirements as specified by the corresponding {@link NomenclaturalCode nomenclatural code}.
642 8eebe79d m.geoffroy
	 *
643 09887ea6 m.geoffroy
	 * @see 	eu.etaxonomy.cdm.model.reference.INomenclaturalReference
644
	 * @see 	eu.etaxonomy.cdm.model.reference.ReferenceBase
645 8eebe79d m.geoffroy
	 */
646 b70a7f94 Andreas Kohlbecker
	public ReferenceBase getNomenclaturalReference(){
647
		return this.nomenclaturalReference;
648 9479da48 Andreas Müller
	}
649 8eebe79d m.geoffroy
	/**
650 09887ea6 m.geoffroy
	 * Assigns a {@link eu.etaxonomy.cdm.model.reference.INomenclaturalReference nomenclatural reference} to <i>this</i> taxon name.
651
	 * The corresponding {@link eu.etaxonomy.cdm.model.reference.ReferenceBase.isNomenclaturallyRelevant nomenclaturally relevant flag} will be set to true
652 8eebe79d m.geoffroy
	 * as it is obviously used for nomenclatural purposes.
653
	 *
654 b70a7f94 Andreas Kohlbecker
	 * @throws IllegalArgumentException if parameter <code>nomenclaturalReference</code> is not assignable from {@link INomenclaturalReference}
655 8eebe79d m.geoffroy
	 * @see  #getNomenclaturalReference()
656
	 */
657 b70a7f94 Andreas Kohlbecker
	public void setNomenclaturalReference(ReferenceBase nomenclaturalReference){
658
		if(nomenclaturalReference != null){
659
			if(!INomenclaturalReference.class.isAssignableFrom(nomenclaturalReference.getClass())){
660
				throw new IllegalArgumentException("Parameter nomenclaturalReference is not assignable from INomenclaturalReference");
661
			}
662
			this.nomenclaturalReference = (ReferenceBase)nomenclaturalReference;
663
		} else {
664
			this.nomenclaturalReference = null;
665
		}
666 9479da48 Andreas Müller
	}
667
668 8eebe79d m.geoffroy
	/** 
669 b9d0e8d2 m.geoffroy
	 * Returns the appended phrase string assigned to <i>this</i> taxon name.
670 8eebe79d m.geoffroy
	 * The appended phrase is a non-atomised addition to a name. It is
671
	 * not ruled by a nomenclatural code.
672
	 */
673 9479da48 Andreas Müller
	public String getAppendedPhrase(){
674
		return this.appendedPhrase;
675
	}
676 ee91bcd9 ben.clark
	
677 8eebe79d m.geoffroy
	/**
678
	 * @see  #getAppendedPhrase()
679
	 */
680 9479da48 Andreas Müller
	public void setAppendedPhrase(String appendedPhrase){
681
		this.appendedPhrase = appendedPhrase;
682
	}
683
684 8eebe79d m.geoffroy
	/** 
685 09887ea6 m.geoffroy
	 * Returns the details string of the {@link #getNomenclaturalReference() nomenclatural reference} assigned
686 b9d0e8d2 m.geoffroy
	 * to <i>this</i> taxon name. The details describe the exact localisation within
687 8eebe79d m.geoffroy
	 * the publication used as nomenclature reference. These are mostly
688
	 * (implicitly) pages but can also be figures or tables or any other
689
	 * element of a publication. A nomenclatural micro reference (details)
690
	 * requires the existence of a nomenclatural reference.
691
	 */
692
	//Details of the nomenclatural reference (protologue). 
693 9479da48 Andreas Müller
	public String getNomenclaturalMicroReference(){
694
		return this.nomenclaturalMicroReference;
695
	}
696 8eebe79d m.geoffroy
	/**
697
	 * @see  #getNomenclaturalMicroReference()
698
	 */
699 9479da48 Andreas Müller
	public void setNomenclaturalMicroReference(String nomenclaturalMicroReference){
700
		this.nomenclaturalMicroReference = nomenclaturalMicroReference;
701
	}
702
703 6680df00 Andreas Müller
	/* (non-Javadoc)
704
	 * @see eu.etaxonomy.cdm.model.common.IParsable#getHasProblem()
705 8eebe79d m.geoffroy
	 */
706 9479da48 Andreas Müller
	public boolean getHasProblem(){
707
		return this.hasProblem;
708
	}
709 6680df00 Andreas Müller
	
710
	/* (non-Javadoc)
711
	 * @see eu.etaxonomy.cdm.model.common.IParsable#setHasProblem(boolean)
712 8eebe79d m.geoffroy
	 */
713 9479da48 Andreas Müller
	public void setHasProblem(boolean hasProblem){
714
		this.hasProblem = hasProblem;
715
	}
716 6680df00 Andreas Müller
	
717
	/* (non-Javadoc)
718
	 * @see eu.etaxonomy.cdm.model.common.IParsable#hasProblem()
719 81c31b35 Andreas Müller
	 */
720
	public boolean hasProblem(){
721
		return getHasProblem();
722
	}
723 6680df00 Andreas Müller
	
724
	/* (non-Javadoc)
725
	 * @see eu.etaxonomy.cdm.model.common.IParsable#problemStarts()
726
	 */
727
	public int getProblemStarts(){
728
		return this.problemStarts;
729
	}
730
	
731
	/* (non-Javadoc)
732
	 * @see eu.etaxonomy.cdm.model.common.IParsable#setProblemStarts(int)
733
	 */
734
	public void setProblemStarts(int start) {
735
		this.problemStarts = start;
736
	}
737
	
738
	/* (non-Javadoc)
739
	 * @see eu.etaxonomy.cdm.model.common.IParsable#problemEnds()
740
	 */
741
	public int getProblemEnds(){
742
		return this.problemEnds;
743
	}
744
745
	/* (non-Javadoc)
746
	 * @see eu.etaxonomy.cdm.model.common.IParsable#setProblemEnds(int)
747
	 */
748
	public void setProblemEnds(int end) {
749
		this.problemEnds = end;
750
	}
751
752 dce4c9cb Andreas Müller
//*********************** TYPE DESIGNATION *********************************************//	
753
	
754 79263e24 m.geoffroy
	/** 
755 dce4c9cb Andreas Müller
	 * Returns the set of {@link TypeDesignationBase type designations} assigned
756
	 * to <i>this</i> taxon name.
757 79263e24 m.geoffroy
	 * @see     NameTypeDesignation
758
	 * @see     SpecimenTypeDesignation
759
	 */
760 dce4c9cb Andreas Müller
	public Set<TypeDesignationBase> getTypeDesignations() {
761
		return typeDesignations;
762 9479da48 Andreas Müller
	}
763 dce4c9cb Andreas Müller
	
764
	/** 
765 6a9737e8 m.geoffroy
	 * Removes one element from the set of {@link TypeDesignationBase type designations} assigned to
766
	 * <i>this</i> taxon name. The type designation itself will be nullified.
767 dce4c9cb Andreas Müller
	 *
768
	 * @param  typeDesignation  the type designation which should be deleted
769
	 */
770
	public void removeTypeDesignation(TypeDesignationBase typeDesignation) {
771
		logger.warn("not yet fully implemented: nullify the specimen type designation itself?");
772
		this.typeDesignations.remove(typeDesignation);
773
	}
774
	
775
	/** 
776
	 * Returns the set of {@link SpecimenTypeDesignation specimen type designations} assigned
777 6a9737e8 m.geoffroy
	 * to <i>this</i> taxon name. The {@link Rank rank} of <i>this</i> taxon name is generally
778
	 * "species" or below. The specimen type designations include all the
779
	 * specimens on which the typification of this name is based (which are
780 09887ea6 m.geoffroy
	 * exclusively used to typify taxon names belonging to the same
781 6a9737e8 m.geoffroy
	 * {@link HomotypicalGroup homotypical group} to which <i>this</i> taxon name
782
	 * belongs) and eventually the status of these designations.
783 dce4c9cb Andreas Müller
	 *
784
	 * @see     SpecimenTypeDesignation
785
	 * @see     NameTypeDesignation
786 6a9737e8 m.geoffroy
	 * @see     HomotypicalGroup
787 dce4c9cb Andreas Müller
	 */
788 b70a7f94 Andreas Kohlbecker
	@Transient
789 dce4c9cb Andreas Müller
	public Set<SpecimenTypeDesignation> getSpecimenTypeDesignationsOfHomotypicalGroup() {
790
		return this.getHomotypicalGroup().getSpecimenTypeDesignations();
791
	}
792
	
793
//*********************** NAME TYPE DESIGNATION *********************************************//	
794
	
795
	/** 
796
	 * Returns the set of {@link NameTypeDesignation name type designations} assigned
797
	 * to <i>this</i> taxon name the rank of which must be above "species".
798
	 * The name type designations include all the taxon names used to typify
799 d82717cb m.geoffroy
	 * <i>this</i> taxon name and eventually the rejected or conserved status
800 dce4c9cb Andreas Müller
	 * of these designations.
801
	 *
802
	 * @see     NameTypeDesignation
803
	 * @see     SpecimenTypeDesignation
804
	 */
805 b70a7f94 Andreas Kohlbecker
	@Transient
806 dce4c9cb Andreas Müller
	public Set<NameTypeDesignation> getNameTypeDesignations() {
807
		Set<NameTypeDesignation> result = new HashSet<NameTypeDesignation>();
808
		for (TypeDesignationBase typeDesignation : this.typeDesignations){
809
			if (typeDesignation instanceof NameTypeDesignation){
810
				result.add((NameTypeDesignation)typeDesignation);
811 c79406dd n.hoffmann
			}
812
		}
813 dce4c9cb Andreas Müller
		return result;
814 c79406dd n.hoffmann
	}
815 ed85df08 Andreas Müller
	
816
	/** 
817
	 * Creates and adds a new {@link NameTypeDesignation name type designation}
818 09887ea6 m.geoffroy
	 * to <i>this</i> taxon name's set of type designations.
819 ed85df08 Andreas Müller
	 *
820 b9d0e8d2 m.geoffroy
	 * @param  typeSpecies				the taxon name to be used as type of <i>this</i> taxon name
821 ed85df08 Andreas Müller
	 * @param  citation					the reference for this new designation
822
	 * @param  citationMicroReference	the string with the details (generally pages) within the reference
823 7d954fd9 m.geoffroy
	 * @param  originalNameString		the taxon name string used in the reference to assert this designation
824 6a9737e8 m.geoffroy
	 * @param  isRejectedType			the boolean status for a rejected name type designation
825
	 * @param  isConservedType			the boolean status for a conserved name type designation
826
	 * @param  isLectoType				the boolean status for a lectotype name type designation
827 d82717cb m.geoffroy
	 * @param  isNotDesignated			the boolean status for a name type designation without name type
828
	 * @param  addToAllHomotypicNames	the boolean indicating whether the name type designation should be
829
	 * 									added to all taxon names of the homotypical group this taxon name belongs to
830 ed85df08 Andreas Müller
	 * @see 			  				#getNameTypeDesignations()
831 6a9737e8 m.geoffroy
	 * @see 			  				NameTypeDesignation
832 57883822 m.geoffroy
	 * @see 			  				TypeDesignationBase#isNotDesignated()
833 ed85df08 Andreas Müller
	 */
834 dce4c9cb Andreas Müller
	public void addNameTypeDesignation(TaxonNameBase typeSpecies, 
835
				ReferenceBase citation, 
836
				String citationMicroReference, 
837
				String originalNameString, 
838
				boolean isRejectedType, 
839
				boolean isConservedType, 
840
				boolean isLectoType, 
841
				boolean isNotDesignated, 
842
				boolean addToAllHomotypicNames) {
843 ec1f7873 Andreas Müller
		NameTypeDesignation nameTypeDesignation = new NameTypeDesignation(typeSpecies, citation, citationMicroReference, originalNameString, isRejectedType, isConservedType, isLectoType, isNotDesignated);
844 168723a2 a.babadshanjan
		nameTypeDesignation.setLectoType(isLectoType);
845 dce4c9cb Andreas Müller
		addTypeDesignation(nameTypeDesignation, addToAllHomotypicNames);
846 ed85df08 Andreas Müller
	}
847
	
848 dce4c9cb Andreas Müller
//*********************** SPECIMEN TYPE DESIGNATION *********************************************//	
849 ed85df08 Andreas Müller
	
850 61106138 m.geoffroy
	/** 
851
	 * Returns the set of {@link SpecimenTypeDesignation specimen type designations}
852 b9d0e8d2 m.geoffroy
	 * that typify <i>this</i> taxon name.
853 ed85df08 Andreas Müller
	 */
854 b70a7f94 Andreas Kohlbecker
	@Transient
855 dce4c9cb Andreas Müller
	public Set<SpecimenTypeDesignation> getSpecimenTypeDesignations() {
856
		Set<SpecimenTypeDesignation> result = new HashSet<SpecimenTypeDesignation>();
857
		for (TypeDesignationBase typeDesignation : this.typeDesignations){
858
			if (typeDesignation instanceof SpecimenTypeDesignation){
859
				result.add((SpecimenTypeDesignation)typeDesignation);
860
			}
861
		}
862
		return result;
863 66b77c3e m.geoffroy
	}
864 dce4c9cb Andreas Müller
865 66b77c3e m.geoffroy
	
866 79263e24 m.geoffroy
	/** 
867 d82717cb m.geoffroy
	 * Creates and adds a new {@link SpecimenTypeDesignation specimen type designation}
868 09887ea6 m.geoffroy
	 * to <i>this</i> taxon name's set of type designations.
869 79263e24 m.geoffroy
	 *
870 d82717cb m.geoffroy
	 * @param  typeSpecimen				the specimen to be used as a type for <i>this</i> taxon name
871 79263e24 m.geoffroy
	 * @param  status					the specimen type designation status
872
	 * @param  citation					the reference for this new specimen type designation
873
	 * @param  citationMicroReference	the string with the details (generally pages) within the reference
874
	 * @param  originalNameString		the taxon name used in the reference to assert this designation
875 57883822 m.geoffroy
	 * @param  isNotDesignated			the boolean status for a specimen type designation without specimen type
876 d82717cb m.geoffroy
	 * @param  addToAllHomotypicNames	the boolean indicating whether the specimen type designation should be
877
	 * 									added to all taxon names of the homotypical group the typified
878
	 * 									taxon name belongs to
879
	 * @see 			  				#getSpecimenTypeDesignations()
880 2d4607f2 a.babadshanjan
	 * @see 			  				SpecimenTypeDesignationStatus
881 d82717cb m.geoffroy
	 * @see 			  				SpecimenTypeDesignation
882 57883822 m.geoffroy
	 * @see 			  				TypeDesignationBase#isNotDesignated()
883 79263e24 m.geoffroy
	 */
884 dce4c9cb Andreas Müller
	public void addSpecimenTypeDesignation(Specimen typeSpecimen, 
885 2d4607f2 a.babadshanjan
				SpecimenTypeDesignationStatus status, 
886 dce4c9cb Andreas Müller
				ReferenceBase citation, 
887
				String citationMicroReference, 
888
				String originalNameString, 
889 57883822 m.geoffroy
				boolean isNotDesignated, 
890 dce4c9cb Andreas Müller
				boolean addToAllHomotypicNames) {
891 57883822 m.geoffroy
		SpecimenTypeDesignation specimenTypeDesignation = new SpecimenTypeDesignation(typeSpecimen, status, citation, citationMicroReference, originalNameString, isNotDesignated);
892 dce4c9cb Andreas Müller
		addTypeDesignation(specimenTypeDesignation, addToAllHomotypicNames);
893 9479da48 Andreas Müller
	}
894 ed85df08 Andreas Müller
	
895 dce4c9cb Andreas Müller
	private boolean addTypeDesignation(TypeDesignationBase typeDesignation, boolean addToAllNames){
896
		//at them moment typeDesignations are not persisted with the homotypical group
897
		//so explicit adding to the homotypical group is not necessary.
898
		if (typeDesignation != null){
899
			this.typeDesignations.add(typeDesignation);
900
			typeDesignation.addTypifiedName(this);
901
			
902
			if (addToAllNames){
903
				for (TaxonNameBase taxonName : this.getHomotypicalGroup().getTypifiedNames()){
904
					if (taxonName != this){
905
						taxonName.addTypeDesignation(typeDesignation, false);
906
					}
907
				}
908
			}
909
		}
910
		return true;
911 ed85df08 Andreas Müller
	}
912 dce4c9cb Andreas Müller
	
913 ed85df08 Andreas Müller
914 dce4c9cb Andreas Müller
	
915
//*********************** HOMOTYPICAL GROUP *********************************************//	
916 9479da48 Andreas Müller
917 dce4c9cb Andreas Müller
	
918 79263e24 m.geoffroy
	/** 
919
	 * Returns the {@link HomotypicalGroup homotypical group} to which
920 b9d0e8d2 m.geoffroy
	 * <i>this</i> taxon name belongs. A homotypical group represents all taxon names
921 d82717cb m.geoffroy
	 * that share the same types.
922 79263e24 m.geoffroy
	 *
923
	 * @see 	HomotypicalGroup
924
	 */
925 ee91bcd9 ben.clark
	
926 9479da48 Andreas Müller
	public HomotypicalGroup getHomotypicalGroup() {
927
		return homotypicalGroup;
928
	}
929 ee91bcd9 ben.clark
	
930
	/* 
931
	 * @see #getHomotypicalGroup()
932
	 */
933
	protected void setHomotypicalGroup(HomotypicalGroup homotypicalGroup) {
934
		this.homotypicalGroup = homotypicalGroup;
935 9479da48 Andreas Müller
	}
936
937 dce4c9cb Andreas Müller
// *************************************************************************//
938
	
939 b3262b1b m.geoffroy
	/** 
940
	 * @see #getNomenclaturalReference()
941
	 */
942 b70a7f94 Andreas Kohlbecker
	@Transient
943 9479da48 Andreas Müller
	public StrictReferenceBase getCitation(){
944 66b77c3e m.geoffroy
		//TODO What is the purpose of this method differing from the getNomenclaturalReference method? 
945 c19dfdc5 Andreas Müller
		logger.warn("getCitation not yet implemented");
946 9479da48 Andreas Müller
		return null;
947
	}
948
949 66b77c3e m.geoffroy
	/** 
950
	 * Returns the complete string containing the
951 09887ea6 m.geoffroy
	 * {@link eu.etaxonomy.cdm.model.reference.INomenclaturalReference#getNomenclaturalCitation() nomenclatural reference citation}
952
	 * and the {@link #getNomenclaturalMicroReference() details} assigned to <i>this</i> taxon name.
953 66b77c3e m.geoffroy
	 * 
954 b9d0e8d2 m.geoffroy
	 * @return  the string containing the nomenclatural reference of <i>this</i> taxon name
955 09887ea6 m.geoffroy
	 * @see		eu.etaxonomy.cdm.model.reference.INomenclaturalReference#getNomenclaturalCitation()
956 b3262b1b m.geoffroy
	 * @see		#getNomenclaturalReference()
957
	 * @see		#getNomenclaturalMicroReference()
958 66b77c3e m.geoffroy
	 */
959 b70a7f94 Andreas Kohlbecker
	@Transient
960 6680df00 Andreas Müller
	@Deprecated
961 9479da48 Andreas Müller
	public String getCitationString(){
962 c19dfdc5 Andreas Müller
		logger.warn("getCitationString not yet implemented");
963 9479da48 Andreas Müller
		return null;
964
	}
965
966 09887ea6 m.geoffroy
	/** 
967
	 * Not yet implemented
968
	 */
969 6680df00 Andreas Müller
	@Deprecated
970 9479da48 Andreas Müller
	public String[] getProblems(){
971 c19dfdc5 Andreas Müller
		logger.warn("getProblems not yet implemented");
972 9479da48 Andreas Müller
		return null;
973
	}
974
975
	/**
976 66b77c3e m.geoffroy
	 * Returns the string containing the publication date (generally only year)
977 09887ea6 m.geoffroy
	 * of the {@link #getNomenclaturalReference() nomenclatural reference} for <i>this</i> taxon name, null if there is
978 b3262b1b m.geoffroy
	 * no nomenclatural reference.
979 66b77c3e m.geoffroy
	 * 
980 b9d0e8d2 m.geoffroy
	 * @return  the string containing the publication date of <i>this</i> taxon name
981 09887ea6 m.geoffroy
	 * @see		eu.etaxonomy.cdm.model.reference.INomenclaturalReference#getYear()
982 9479da48 Andreas Müller
	 */
983 b70a7f94 Andreas Kohlbecker
	@Transient
984 b0b7280d Andreas Müller
	public String getReferenceYear(){
985
		if (this.getNomenclaturalReference() != null ){
986
			return this.getNomenclaturalReference().getYear();
987
		}else{
988
			return null;
989
		}
990 9479da48 Andreas Müller
	}
991
992 66b77c3e m.geoffroy
	/** 
993 09887ea6 m.geoffroy
	 * Returns the set of {@link eu.etaxonomy.cdm.model.taxon.TaxonBase taxon bases} that refer to <i>this</i> taxon name.
994 66b77c3e m.geoffroy
	 * In this context a taxon base means the use of a taxon name by a reference
995 09887ea6 m.geoffroy
	 * either as a {@link eu.etaxonomy.cdm.model.taxon.Taxon taxon} ("accepted/correct" name) or
996
	 * as a (junior) {@link eu.etaxonomy.cdm.model.taxon.Synonym synonym}.
997
	 * A taxon name can be used by several distinct {@link eu.etaxonomy.cdm.model.reference.ReferenceBase references} but only once
998 66b77c3e m.geoffroy
	 * within a taxonomic treatment (identified by one reference).
999
	 *
1000
	 * @see	#getTaxa()
1001
	 * @see	#getSynonyms()
1002
	 */
1003 608eada2 Andreas Müller
	public Set<TaxonBase> getTaxonBases() {
1004
		return this.taxonBases;
1005
	}
1006 ee91bcd9 ben.clark
	
1007 66b77c3e m.geoffroy
	/** 
1008 09887ea6 m.geoffroy
	 * Adds a new {@link eu.etaxonomy.cdm.model.taxon.TaxonBase taxon base}
1009 b9d0e8d2 m.geoffroy
	 * to the set of taxon bases using <i>this</i> taxon name.
1010 66b77c3e m.geoffroy
	 *
1011
	 * @param  taxonBase  the taxon base to be added
1012
	 * @see 			  #getTaxonBases()
1013 61106138 m.geoffroy
	 * @see 			  #removeTaxonBase(TaxonBase)
1014 66b77c3e m.geoffroy
	 */
1015 1cfc54ab Andreas Müller
	//TODO protected
1016
	public void addTaxonBase(TaxonBase taxonBase){
1017 ee91bcd9 ben.clark
		Method method = ReflectionUtils.findMethod(TaxonBase.class, "setName", new Class[] {TaxonNameBase.class});
1018
		ReflectionUtils.makeAccessible(method);
1019
		ReflectionUtils.invokeMethod(method, taxonBase, new Object[] {this});
1020 1cfc54ab Andreas Müller
		taxonBases.add(taxonBase);
1021
	}
1022 b3262b1b m.geoffroy
	/** 
1023 09887ea6 m.geoffroy
	 * Removes one element from the set of {@link eu.etaxonomy.cdm.model.taxon.TaxonBase taxon bases} that refer to <i>this</i> taxon name.
1024 b3262b1b m.geoffroy
	 *
1025
	 * @param  taxonBase	the taxon base which should be removed from the corresponding set
1026 09887ea6 m.geoffroy
	 * @see    				#getTaxonBases()
1027 b3262b1b m.geoffroy
	 * @see    				#addTaxonBase(TaxonBase)
1028
	 */
1029 c1c3a21a Andreas Müller
	public void removeTaxonBase(TaxonBase taxonBase){
1030 ee91bcd9 ben.clark
		Method method = ReflectionUtils.findMethod(TaxonBase.class, "setName", new Class[] {TaxonNameBase.class});
1031
		ReflectionUtils.makeAccessible(method);
1032
		ReflectionUtils.invokeMethod(method, taxonBase, new Object[] {null});
1033 d163fbf6 Andreas Müller
		taxonBases.remove(taxonBase);
1034 1cfc54ab Andreas Müller
	}
1035
	
1036 0d4d2092 m.doering
	/**
1037 09887ea6 m.geoffroy
	 * Returns the set of {@link eu.etaxonomy.cdm.model.taxon.Taxon taxa} ("accepted/correct" names according to any
1038 b9d0e8d2 m.geoffroy
	 * reference) that are based on <i>this</i> taxon name. This set is a subset of
1039 66b77c3e m.geoffroy
	 * the set returned by getTaxonBases(). 
1040
	 * 
1041 09887ea6 m.geoffroy
	 * @see	eu.etaxonomy.cdm.model.taxon.Taxon
1042 66b77c3e m.geoffroy
	 * @see	#getTaxonBases()
1043
	 * @see	#getSynonyms()
1044 0d4d2092 m.doering
	 */
1045 b70a7f94 Andreas Kohlbecker
	@Transient
1046 0d4d2092 m.doering
	public Set<Taxon> getTaxa(){
1047 608eada2 Andreas Müller
		Set<Taxon> result = new HashSet<Taxon>();
1048
		for (TaxonBase taxonBase : this.taxonBases){
1049
			if (taxonBase instanceof Taxon){
1050
				result.add((Taxon)taxonBase);
1051
			}
1052
		}
1053
		return result;
1054 0d4d2092 m.doering
	}
1055 608eada2 Andreas Müller
	
1056 0d4d2092 m.doering
	/**
1057 09887ea6 m.geoffroy
	 * Returns the set of {@link eu.etaxonomy.cdm.model.taxon.Synonym (junior) synonyms} (according to any
1058 b9d0e8d2 m.geoffroy
	 * reference) that are based on <i>this</i> taxon name. This set is a subset of
1059 66b77c3e m.geoffroy
	 * the set returned by getTaxonBases(). 
1060
	 * 
1061 09887ea6 m.geoffroy
	 * @see	eu.etaxonomy.cdm.model.taxon.Synonym
1062 66b77c3e m.geoffroy
	 * @see	#getTaxonBases()
1063
	 * @see	#getTaxa()
1064 0d4d2092 m.doering
	 */
1065 b70a7f94 Andreas Kohlbecker
	@Transient
1066 608eada2 Andreas Müller
	public Set<Synonym> getSynonyms() {
1067
		Set<Synonym> result = new HashSet<Synonym>();
1068
		for (TaxonBase taxonBase : this.taxonBases){
1069
			if (taxonBase instanceof Synonym){
1070
				result.add((Synonym)taxonBase);
1071
			}
1072
		}
1073
		return result;
1074 0d4d2092 m.doering
	}
1075 9118658f m.doering
	
1076 71dcc146 Andreas Müller
	
1077
// *********** DESCRIPTIONS *************************************	
1078
1079 0880a77c m.geoffroy
	/**
1080 09887ea6 m.geoffroy
	 * Returns the set of {@link eu.etaxonomy.cdm.model.description.TaxonNameDescription taxon name descriptions} assigned
1081 b9d0e8d2 m.geoffroy
	 * to <i>this</i> taxon name. A taxon name description is a piece of information
1082 0880a77c m.geoffroy
	 * concerning the taxon name like for instance the content of its first
1083
	 * publication (protolog) or a picture of this publication.
1084
	 * 
1085
	 * @see	#addDescription(TaxonNameDescription)
1086
	 * @see	#removeDescription(TaxonNameDescription)
1087 09887ea6 m.geoffroy
	 * @see	eu.etaxonomy.cdm.model.description.TaxonNameDescription
1088 0880a77c m.geoffroy
	 */
1089 71dcc146 Andreas Müller
	public Set<TaxonNameDescription> getDescriptions() {
1090
		return descriptions;
1091
	}
1092 ee91bcd9 ben.clark
1093 0880a77c m.geoffroy
	/** 
1094 09887ea6 m.geoffroy
	 * Adds a new {@link eu.etaxonomy.cdm.model.description.TaxonNameDescription taxon name description}
1095 b9d0e8d2 m.geoffroy
	 * to the set of taxon name descriptions assigned to <i>this</i> taxon name. The
1096 09887ea6 m.geoffroy
	 * content of the {@link eu.etaxonomy.cdm.model.description.TaxonNameDescription#getTaxonName() taxonName attribute} of the
1097 b9d0e8d2 m.geoffroy
	 * taxon name description itself will be replaced with <i>this</i> taxon name.
1098 0880a77c m.geoffroy
	 *
1099
	 * @param  description  the taxon name description to be added
1100
	 * @see					#getDescriptions()
1101
	 * @see 			  	#removeDescription(TaxonNameDescription)
1102 71dcc146 Andreas Müller
	 */
1103
	public void addDescription(TaxonNameDescription description) {
1104 fd7ee7b1 ben.clark
		java.lang.reflect.Field field = ReflectionUtils.findField(TaxonNameDescription.class, "taxonName", TaxonNameBase.class);
1105 c49c125c Andreas Müller
		ReflectionUtils.makeAccessible(field);
1106
		ReflectionUtils.setField(field, description, this);
1107 71dcc146 Andreas Müller
		descriptions.add(description);
1108
	}
1109 0880a77c m.geoffroy
	/** 
1110 09887ea6 m.geoffroy
	 * Removes one element from the set of {@link eu.etaxonomy.cdm.model.description.TaxonNameDescription taxon name descriptions} assigned
1111
	 * to <i>this</i> taxon name. The content of the {@link eu.etaxonomy.cdm.model.description.TaxonNameDescription#getTaxonName() taxonName attribute}
1112 0880a77c m.geoffroy
	 * of the description itself will be set to "null".
1113
	 *
1114
	 * @param  description  the taxon name description which should be removed
1115
	 * @see     		  	#getDescriptions()
1116
	 * @see     		  	#addDescription(TaxonNameDescription)
1117 09887ea6 m.geoffroy
	 * @see 			  	eu.etaxonomy.cdm.model.description.TaxonNameDescription#getTaxonName()
1118 0880a77c m.geoffroy
	 */
1119 71dcc146 Andreas Müller
	public void removeDescription(TaxonNameDescription description) {
1120 fd7ee7b1 ben.clark
		java.lang.reflect.Field field = ReflectionUtils.findField(TaxonNameDescription.class, "taxonName", TaxonNameBase.class);
1121 c49c125c Andreas Müller
		ReflectionUtils.makeAccessible(field);
1122
		ReflectionUtils.setField(field, description, null);
1123 71dcc146 Andreas Müller
		descriptions.remove(description);
1124
	}
1125
	
1126 95449e99 Andreas Müller
// ***********
1127 66b77c3e m.geoffroy
	/**
1128
	 * Returns the boolean value indicating whether a given taxon name belongs
1129 b9d0e8d2 m.geoffroy
	 * to the same {@link HomotypicalGroup homotypical group} as <i>this</i> taxon name (true)
1130 66b77c3e m.geoffroy
	 * or not (false). Returns "true" only if the homotypical groups of both
1131
	 * taxon names exist and if they are identical. 
1132
	 *
1133
	 * @param	homoTypicName  the taxon name the homotypical group of which is to be checked
1134
	 * @return  			   the boolean value of the check
1135
	 * @see     			   HomotypicalGroup
1136
	 */
1137 b70a7f94 Andreas Kohlbecker
	@Transient
1138 95449e99 Andreas Müller
	public boolean isHomotypic(TaxonNameBase homoTypicName) {
1139
		if (homoTypicName == null) {
1140
			return false;
1141
		}
1142
		HomotypicalGroup homotypicGroup = homoTypicName.getHomotypicalGroup();
1143
		if (homotypicGroup == null || this.getHomotypicalGroup() == null) {
1144
			return false;
1145
		}
1146
		if (homotypicGroup.equals(this.getHomotypicalGroup())) {
1147
			return true;
1148
		}
1149
		return false;
1150
	}
1151
	
1152
//*********  Rank comparison shortcuts   ********************//
1153 4cc4f6f7 m.geoffroy
	/**
1154 b9d0e8d2 m.geoffroy
	 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of <i>this</i>
1155 4cc4f6f7 m.geoffroy
	 * taxon name is higher than the genus rank (true) or not (false).
1156
	 * Suprageneric non viral names are monomials.
1157 bef42c31 Andreas Müller
	 * Returns false if rank is null.
1158 4cc4f6f7 m.geoffroy
	 * 
1159
	 * @see  #isGenus()
1160
	 * @see  #isInfraGeneric()
1161
	 * @see  #isSpecies()
1162
	 * @see  #isInfraSpecific()
1163
	 */
1164 b70a7f94 Andreas Kohlbecker
	@Transient
1165 451c6005 m.doering
	public boolean isSupraGeneric() {
1166 bef42c31 Andreas Müller
		if (rank == null){
1167
			return false;
1168
		}
1169 451c6005 m.doering
		return getRank().isSupraGeneric();
1170
	}
1171 4cc4f6f7 m.geoffroy
	/**
1172 b9d0e8d2 m.geoffroy
	 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of <i>this</i>
1173 4cc4f6f7 m.geoffroy
	 * taxon name is the genus rank (true) or not (false). Non viral names with
1174 10a54497 m.geoffroy
	 * genus rank are monomials. Returns false if rank is null.
1175 4cc4f6f7 m.geoffroy
	 *
1176
	 * @see  #isSupraGeneric()
1177
	 * @see  #isInfraGeneric()
1178
	 * @see  #isSpecies()
1179
	 * @see  #isInfraSpecific()
1180
	 */
1181 b70a7f94 Andreas Kohlbecker
	@Transient
1182 451c6005 m.doering
	public boolean isGenus() {
1183 bef42c31 Andreas Müller
		if (rank == null){
1184
			return false;
1185
		}
1186 451c6005 m.doering
		return getRank().isGenus();
1187
	}
1188 4cc4f6f7 m.geoffroy
	/**
1189 b9d0e8d2 m.geoffroy
	 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of <i>this</i>
1190 10a54497 m.geoffroy
	 * taxon name is higher than the species rank and lower than the
1191
	 * genus rank (true) or not (false). Infrageneric non viral names are
1192
	 * binomials. Returns false if rank is null.
1193 4cc4f6f7 m.geoffroy
	 *
1194
	 * @see  #isSupraGeneric()
1195
	 * @see  #isGenus()
1196
	 * @see  #isSpecies()
1197
	 * @see  #isInfraSpecific()
1198
	 */
1199 b70a7f94 Andreas Kohlbecker
	@Transient
1200 451c6005 m.doering
	public boolean isInfraGeneric() {
1201 bef42c31 Andreas Müller
		if (rank == null){
1202
			return false;
1203
		}
1204 451c6005 m.doering
		return getRank().isInfraGeneric();
1205
	}
1206 4cc4f6f7 m.geoffroy
	/**
1207 b9d0e8d2 m.geoffroy
	 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of <i>this</i>
1208 10a54497 m.geoffroy
	 * taxon name is the species rank (true) or not (false). Non viral names
1209 4cc4f6f7 m.geoffroy
	 * with species rank are binomials.
1210 bef42c31 Andreas Müller
	 * Returns false if rank is null.
1211 4cc4f6f7 m.geoffroy
	 *
1212
	 * @see  #isSupraGeneric()
1213
	 * @see  #isGenus()
1214
	 * @see  #isInfraGeneric()
1215
	 * @see  #isInfraSpecific()
1216
	 */
1217 b70a7f94 Andreas Kohlbecker
	@Transient
1218 451c6005 m.doering
	public boolean isSpecies() {
1219 bef42c31 Andreas Müller
		if (rank == null){
1220
			return false;
1221
		}
1222 451c6005 m.doering
		return getRank().isSpecies();
1223
	}
1224 4cc4f6f7 m.geoffroy
	/**
1225 b9d0e8d2 m.geoffroy
	 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of <i>this</i>
1226 4cc4f6f7 m.geoffroy
	 * taxon name is lower than the species rank (true) or not (false).
1227
	 * Infraspecific non viral names are trinomials.
1228 bef42c31 Andreas Müller
	 * Returns false if rank is null.
1229 4cc4f6f7 m.geoffroy
	 *
1230
	 * @see  #isSupraGeneric()
1231
	 * @see  #isGenus()
1232
	 * @see  #isInfraGeneric()
1233
	 * @see  #isSpecies()
1234
	 */
1235 b70a7f94 Andreas Kohlbecker
	@Transient
1236 451c6005 m.doering
	public boolean isInfraSpecific() {
1237 bef42c31 Andreas Müller
		if (rank == null){
1238
			return false;
1239
		}
1240 451c6005 m.doering
		return getRank().isInfraSpecific();
1241
	}
1242 5c19d7f0 Andreas Müller
	
1243 7ebeb288 Andreas Müller
	
1244 4cc4f6f7 m.geoffroy
	/**
1245 eb7e638a m.geoffroy
	 * Returns null as the {@link NomenclaturalCode nomenclatural code} that governs
1246 b9d0e8d2 m.geoffroy
	 * the construction of <i>this</i> taxon name since there is no specific
1247 eb7e638a m.geoffroy
	 * nomenclatural code defined. The real implementention takes place in the
1248
	 * subclasses {@link ViralName ViralName}, {@link BacterialName BacterialName},
1249
	 * {@link BotanicalName BotanicalName}, {@link CultivarPlantName CultivarPlantName} and
1250
	 * {@link ZoologicalName ZoologicalName}. Each taxon name is governed by one
1251 4cc4f6f7 m.geoffroy
	 * and only one nomenclatural code. 
1252
	 *
1253 eb7e638a m.geoffroy
	 * @return  null
1254 b3262b1b m.geoffroy
	 * @see  	#isCodeCompliant()
1255
	 * @see  	#getHasProblem()
1256 4cc4f6f7 m.geoffroy
	 */
1257 bef42c31 Andreas Müller
	abstract public NomenclaturalCode getNomenclaturalCode();
1258 d50a2c5d Andreas Müller
	/* (non-Javadoc)
1259
	 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
1260
	 */
1261 b3262b1b m.geoffroy
	/**
1262 b9d0e8d2 m.geoffroy
	 * Generates and returns the string with the scientific name of <i>this</i>
1263 7e759003 m.geoffroy
	 * taxon name (only non viral taxon names can be generated from their
1264
	 * components). This string may be stored in the inherited
1265 09887ea6 m.geoffroy
	 * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} attribute.
1266 b3262b1b m.geoffroy
	 * This method overrides the generic and inherited
1267 09887ea6 m.geoffroy
	 * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle() method} from
1268
	 * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity IdentifiableEntity}.
1269 b3262b1b m.geoffroy
	 *
1270
	 * @return  the string with the composed name of this non viral taxon name with authorship (and maybe year)
1271 09887ea6 m.geoffroy
	 * @see  	eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
1272
	 * @see  	eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
1273 b3262b1b m.geoffroy
	 */
1274 d50a2c5d Andreas Müller
	@Override
1275
	public String generateTitle() {
1276
		// TODO Auto-generated method stub
1277 788ff862 Andreas Müller
		logger.warn("not yet implemented");
1278 d50a2c5d Andreas Müller
		return null;
1279 ee91bcd9 ben.clark
	}	
1280 dadf5cd0 Andreas Kohlbecker
}