2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.name
;
13 import eu
.etaxonomy
.cdm
.model
.occurrence
.Specimen
;
14 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
15 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
16 import eu
.etaxonomy
.cdm
.model
.reference
.StrictReferenceBase
;
17 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
18 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationship
;
19 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
20 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
21 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
22 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
23 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
24 import eu
.etaxonomy
.cdm
.model
.common
.IReferencedEntity
;
25 import org
.apache
.log4j
.Logger
;
26 import org
.hibernate
.annotations
.Cascade
;
27 import org
.hibernate
.annotations
.CascadeType
;
29 import eu
.etaxonomy
.cdm
.strategy
.INameCacheStrategy
;
30 import eu
.etaxonomy
.cdm
.strategy
.ITaxonNameParser
;
34 import javax
.persistence
.*;
37 * The upmost (abstract) class for scientific taxon names regardless of the any
38 * particular nomenclatural code. The scientific name including author strings and
39 * maybe year is stored in IdentifiableEntity.titleCache
43 * @created 08-Nov-2007 13:06:57
46 @Inheritance(strategy
=InheritanceType
.SINGLE_TABLE
)
47 public abstract class TaxonNameBase
<T
extends TaxonNameBase
> extends IdentifiableEntity
<TaxonNameBase
> implements IReferencedEntity
{
48 static Logger logger
= Logger
.getLogger(TaxonNameBase
.class);
49 //The scientific name without author strings and year
50 private String nameCache
;
51 //Non-atomised addition to a name not ruled by a nomenclatural code
52 private String appendedPhrase
;
53 //Details of the nomenclatural reference (protologue). These are mostly (implicitly) pages but can also be figures or
54 //tables or any other element of a publication. {only if a nomenclatural reference exists}
55 private String nomenclaturalMicroReference
;
56 //this flag will be set to true if the parseName method was unable to successfully parse the name
57 private boolean hasProblem
= false;
58 protected Set
<NameTypeDesignation
> nameTypeDesignations
= new HashSet();
59 private HomotypicalGroup homotypicalGroup
= new HomotypicalGroup();
60 private Set
<NameRelationship
> relationsFromThisName
= new HashSet();
61 private Set
<NameRelationship
> relationsToThisName
= new HashSet();
62 private Set
<NomenclaturalStatus
> status
= new HashSet();
64 //if set, the Reference.isNomenclaturallyRelevant flag should be set to true!
65 private INomenclaturalReference nomenclaturalReference
;
69 protected boolean protectedNameCache
;
71 protected INameCacheStrategy cacheStrategy
;
73 static protected ITaxonNameParser nameParser
;
76 // * Returns a TaxonNameBase instance
79 // abstract public static TaxonNameBase PARSED_NAME(String fullName);
81 // ************* CONSTRUCTORS *************/
82 public TaxonNameBase() {
85 public TaxonNameBase(Rank rank
) {
90 //********* METHODS **************************************/
92 protected String
generateNameCache(){
93 if (cacheStrategy
== null){
94 logger
.warn("No CacheStrategy defined for taxonName: " + this.toString());
97 return cacheStrategy
.getNameCache(this);
101 public String
getNameCache() {
102 if (protectedNameCache
){
103 return this.nameCache
;
105 // is title dirty, i.e. equal NULL?
106 if (nameCache
== null){
107 this.nameCache
= generateNameCache();
112 public void setNameCache(String nameCache
){
113 this.nameCache
= nameCache
;
114 // TODO this.setProtectedNameCache(true);
117 // public void setTitleCache(String titleCache, boolean protectCache){
118 // this.titleCache = titleCache;
119 // this.setProtectedTitleCache(protectCache);
124 public abstract boolean isCodeCompliant();
128 public Set
<NameRelationship
> getNameRelations() {
129 Set
<NameRelationship
> rels
= new HashSet
<NameRelationship
>();
130 rels
.addAll(getRelationsFromThisName());
131 rels
.addAll(getRelationsToThisName());
135 * Add a name relationship to both names involved
138 public void addRelationshipToName(TaxonNameBase toName
, NameRelationshipType type
, String ruleConsidered
){
139 NameRelationship rel
= new NameRelationship(toName
, this, type
, ruleConsidered
);
141 public void addRelationshipFromName(TaxonNameBase fromName
, NameRelationshipType type
, String ruleConsidered
){
142 NameRelationship rel
= new NameRelationship(this, fromName
, type
, ruleConsidered
);
144 protected void addNameRelationship(NameRelationship rel
) {
145 if (rel
!=null && rel
.getToName().equals(this)){
146 this.relationsToThisName
.add(rel
);
147 }else if(rel
!=null && rel
.getFromName().equals(this)){
148 this.relationsFromThisName
.add(rel
);
150 //TODO: raise error???
153 public void removeNameRelationship(NameRelationship nameRelation
) {
154 this.relationsToThisName
.remove(nameRelation
);
155 this.relationsFromThisName
.remove(nameRelation
);
159 @OneToMany(mappedBy
="fromName")
160 @Cascade({CascadeType
.SAVE_UPDATE
})
161 public Set
<NameRelationship
> getRelationsFromThisName() {
162 return relationsFromThisName
;
164 private void setRelationsFromThisName(Set
<NameRelationship
> relationsFromThisName
) {
165 this.relationsFromThisName
= relationsFromThisName
;
168 @OneToMany(mappedBy
="toName")
169 @Cascade({CascadeType
.SAVE_UPDATE
})
170 public Set
<NameRelationship
> getRelationsToThisName() {
171 return relationsToThisName
;
173 private void setRelationsToThisName(Set
<NameRelationship
> relationsToThisName
) {
174 this.relationsToThisName
= relationsToThisName
;
180 @Cascade({CascadeType
.SAVE_UPDATE
})
181 public Set
<NomenclaturalStatus
> getStatus() {
184 protected void setStatus(Set
<NomenclaturalStatus
> status
) {
185 this.status
= status
;
187 public void addStatus(NomenclaturalStatus status
) {
188 this.status
.add(status
);
190 public void removeStatus(NomenclaturalStatus status
) {
191 this.status
.remove(status
);
196 public T
getBasionym(){
197 //TODO: pick the right name relationships...
200 public void setBasionym(T basionym
){
201 setBasionym(basionym
, null);
203 public void setBasionym(T basionym
, String ruleConsidered
){
204 basionym
.addRelationshipToName(this, NameRelationshipType
.BASIONYM(), null);
211 public INameCacheStrategy
getCacheStrategy() {
212 return cacheStrategy
;
214 public void setCacheStrategy(INameCacheStrategy cacheStrategy
) {
215 this.cacheStrategy
= cacheStrategy
;
219 //@Cascade({CascadeType.SAVE_UPDATE})
220 public Rank
getRank(){
223 public void setRank(Rank rank
){
228 @Cascade({CascadeType
.SAVE_UPDATE
})
229 public ReferenceBase
getNomenclaturalReference(){
230 return (ReferenceBase
) this.nomenclaturalReference
;
232 public void setNomenclaturalReference(INomenclaturalReference nomenclaturalReference
){
233 this.nomenclaturalReference
= nomenclaturalReference
;
237 public String
getAppendedPhrase(){
238 return this.appendedPhrase
;
240 public void setAppendedPhrase(String appendedPhrase
){
241 this.appendedPhrase
= appendedPhrase
;
244 public String
getNomenclaturalMicroReference(){
245 return this.nomenclaturalMicroReference
;
247 public void setNomenclaturalMicroReference(String nomenclaturalMicroReference
){
248 this.nomenclaturalMicroReference
= nomenclaturalMicroReference
;
251 public boolean getHasProblem(){
252 return this.hasProblem
;
254 public void setHasProblem(boolean hasProblem
){
255 this.hasProblem
= hasProblem
;
260 //TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
261 @Cascade(CascadeType
.SAVE_UPDATE
)
262 public Set
<NameTypeDesignation
> getNameTypeDesignations() {
263 return nameTypeDesignations
;
265 protected void setNameTypeDesignations(Set
<NameTypeDesignation
> nameTypeDesignations
) {
266 this.nameTypeDesignations
= nameTypeDesignations
;
269 public void addTypeDesignation(TaxonNameBase typeSpecies
, ReferenceBase citation
, String citationMicroReference
, String originalNameString
, boolean isRejectedType
, boolean isConservedType
) {
270 NameTypeDesignation td
= new NameTypeDesignation(this, typeSpecies
, citation
, citationMicroReference
, originalNameString
, isRejectedType
, isConservedType
);
272 public void addTypeDesignation(Specimen typeSpecimen
, TypeDesignationStatus status
, ReferenceBase citation
, String citationMicroReference
, String originalNameString
) {
273 this.homotypicalGroup
.addTypeDesignation(typeSpecimen
, status
, citation
, citationMicroReference
, originalNameString
);
275 public void removeTypeDesignation(NameTypeDesignation typeDesignation
) {
276 this.nameTypeDesignations
.remove(typeDesignation
);
278 public void removeTypeDesignation(SpecimenTypeDesignation typeDesignation
) {
279 this.homotypicalGroup
.removeTypeDesignation(typeDesignation
);
284 @Cascade({CascadeType
.SAVE_UPDATE
})
285 public HomotypicalGroup
getHomotypicalGroup() {
286 return homotypicalGroup
;
288 public void setHomotypicalGroup(HomotypicalGroup newHomotypicalGroup
) {
289 if(this.homotypicalGroup
== newHomotypicalGroup
) return;
290 if (homotypicalGroup
!= null) {
291 homotypicalGroup
.typifiedNames
.remove(this);
293 if (newHomotypicalGroup
!= null) {
294 newHomotypicalGroup
.typifiedNames
.add(this);
296 this.homotypicalGroup
= newHomotypicalGroup
;
300 public StrictReferenceBase
getCitation(){
305 public String
getCitationString(){
310 public String
[] getProblems(){
315 * returns year of according nomenclatural reference, null if nomenclatural
316 * reference does not exist
319 public String
getYear(){
325 * Return a set of taxa that use this name
329 public Set
<Taxon
> getTaxa(){
330 // TODO: implement this method via bidirectional TaxonBase-NameBase relation or use a DAO instead
334 * Return a set of synonyms that use this name
338 public Set
<Synonym
> getSynonyms(){
339 // TODO: implement this method via bidirectional TaxonBase-NameBase relation or use a DAO instead
344 public Set
<SpecimenTypeDesignation
> getSpecimenTypeDesignations() {
345 return this.getHomotypicalGroup().getTypeDesignations();
348 // Rank comparison shortcuts
350 public boolean isSupraGeneric() {
351 return getRank().isSupraGeneric();
354 public boolean isGenus() {
355 return getRank().isGenus();
358 public boolean isInfraGeneric() {
359 return getRank().isInfraGeneric();
362 public boolean isSpecies() {
363 return getRank().isSpecies();
366 public boolean isInfraSpecific() {
367 return getRank().isInfraSpecific();
370 public boolean isSupraGeneric(Rank rank
) {
371 return getRank().isHigher(rank
);