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
.agent
.INomenclaturalAuthor
;
14 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
15 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
16 import eu
.etaxonomy
.cdm
.strategy
.cache
.INameCacheStrategy
;
17 import eu
.etaxonomy
.cdm
.strategy
.cache
.INonViralNameCacheStrategy
;
18 import eu
.etaxonomy
.cdm
.strategy
.cache
.NonViralNameDefaultCacheStrategy
;
20 import org
.apache
.log4j
.Logger
;
21 import org
.hibernate
.annotations
.Cascade
;
22 import org
.hibernate
.annotations
.CascadeType
;
23 import org
.hibernate
.annotations
.Target
;
25 import javax
.persistence
.*;
28 * The taxon name class for all non viral taxa. Parentetical authorship is derived
29 * from basionym relationship. The scientific name including author strings and
30 * maybe year can be stored as a string in the inherited {@link common.IdentifiableEntity#getTitleCache() titleCache} attribute.
31 * The scientific name string without author strings and year can be stored in the {@link #getNameCache() nameCache} attribute.
35 * @created 08-Nov-2007 13:06:39
38 public class NonViralName
<T
extends NonViralName
> extends TaxonNameBase
<NonViralName
, INonViralNameCacheStrategy
> {
39 private static final Logger logger
= Logger
.getLogger(NonViralName
.class);
41 private String nameCache
;
42 private String genusOrUninomial
;
43 private String infraGenericEpithet
;
44 private String specificEpithet
;
45 private String infraSpecificEpithet
;
46 private INomenclaturalAuthor combinationAuthorTeam
;
47 private INomenclaturalAuthor exCombinationAuthorTeam
;
48 private INomenclaturalAuthor basionymAuthorTeam
;
49 private INomenclaturalAuthor exBasionymAuthorTeam
;
50 private String authorshipCache
;
51 protected boolean protectedAuthorshipCache
;
52 protected boolean protectedNameCache
;
54 protected INonViralNameCacheStrategy cacheStrategy
;
56 // ************* CONSTRUCTORS *************/
60 * Class constructor: creates a new non viral taxon name instance
61 * only containing the {@link eu.etaxonomy.cdm.strategy.cache.NonViralNameDefaultCacheStrategy default cache strategy}.
63 * @see #NonViralName(Rank, HomotypicalGroup)
64 * @see #NonViralName(Rank, String, String, String, TeamOrPersonBase, INomenclaturalReference, String, HomotypicalGroup)
65 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy
66 * @see eu.etaxonomy.cdm.strategy.cache.INameCacheStrategy
67 * @see eu.etaxonomy.cdm.strategy.cache.IIdentifiableEntityCacheStrategy
69 protected NonViralName(){
71 setNameCacheStrategy();
75 * Class constructor: creates a new non viral taxon name instance
76 * only containing its {@link common.Rank rank},
77 * its {@link common.HomotypicalGroup homotypical group} and
78 * only containing the {@link eu.etaxonomy.cdm.strategy.cache.NonViralNameDefaultCacheStrategy default cache strategy}.
80 * @param rank the rank to be assigned to this non viral taxon name
81 * @param homotypicalGroup the homotypical group to which this non viral taxon name belongs
82 * @see #NonViralName()
83 * @see #NonViralName(Rank, String, String, String, TeamOrPersonBase, INomenclaturalReference, String, HomotypicalGroup)
84 * @see #NewInstance(Rank, HomotypicalGroup)
85 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy
86 * @see eu.etaxonomy.cdm.strategy.cache.INameCacheStrategy
87 * @see eu.etaxonomy.cdm.strategy.cache.IIdentifiableEntityCacheStrategy
89 protected NonViralName(Rank rank
, HomotypicalGroup homotypicalGroup
) {
90 super(rank
, homotypicalGroup
);
91 setNameCacheStrategy();
94 * Class constructor: creates a new non viral taxon name instance
95 * containing its {@link common.Rank rank},
96 * its {@link common.HomotypicalGroup homotypical group},
97 * its scientific name components, its {@link agent.TeamOrPersonBase author(team)},
98 * its {@link reference.INomenclaturalReference nomenclatural reference} and
99 * the {@link eu.etaxonomy.cdm.strategy.cache.NonViralNameDefaultCacheStrategy default cache strategy}.
101 * @param rank the rank to be assigned to this non viral taxon name
102 * @param genusOrUninomial the string for this taxon name
103 * if its rank is genus or higher or for the genus part
104 * if its rank is lower than genus
105 * @param specificEpithet the string for the first epithet of
106 * this non viral taxon name if its rank is lower than genus
107 * @param infraSpecificEpithet the string for the second epithet of
108 * this non viral taxon name if its rank is lower than species
109 * @param combinationAuthorTeam the author or the team who published this non viral taxon name
110 * @param nomenclaturalReference the nomenclatural reference where this non viral taxon name was published
111 * @param nomenclMicroRef the string with the details for precise location within the nomenclatural reference
112 * @param homotypicalGroup the homotypical group to which this non viral taxon name belongs
113 * @see #NonViralName()
114 * @see #NonViralName(Rank, HomotypicalGroup)
115 * @see #NewInstance(Rank, HomotypicalGroup)
116 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy
117 * @see eu.etaxonomy.cdm.strategy.cache.INameCacheStrategy
118 * @see eu.etaxonomy.cdm.strategy.cache.IIdentifiableEntityCacheStrategy
120 protected NonViralName(Rank rank
, String genusOrUninomial
, String specificEpithet
, String infraSpecificEpithet
, TeamOrPersonBase combinationAuthorTeam
, INomenclaturalReference nomenclaturalReference
, String nomenclMicroRef
, HomotypicalGroup homotypicalGroup
) {
121 super(rank
, homotypicalGroup
);
122 setNameCacheStrategy();
123 setGenusOrUninomial(genusOrUninomial
);
124 setSpecificEpithet(specificEpithet
);
125 setInfraSpecificEpithet(infraSpecificEpithet
);
126 setCombinationAuthorTeam(combinationAuthorTeam
);
127 setNomenclaturalReference(nomenclaturalReference
);
128 this.setNomenclaturalMicroReference(nomenclMicroRef
);
131 //********* METHODS **************************************/
133 * Creates a new non viral taxon name instance
134 * only containing its {@link common.Rank rank} and
135 * the {@link eu.etaxonomy.cdm.strategy.cache.NonViralNameDefaultCacheStrategy default cache strategy}.
137 * @param rank the rank to be assigned to this non viral taxon name
138 * @see #NewInstance(Rank, HomotypicalGroup)
139 * @see #NonViralName(Rank, HomotypicalGroup)
140 * @see #NonViralName()
141 * @see #NonViralName(Rank, String, String, String, TeamOrPersonBase, INomenclaturalReference, String, HomotypicalGroup)
142 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy
143 * @see eu.etaxonomy.cdm.strategy.cache.INameCacheStrategy
144 * @see eu.etaxonomy.cdm.strategy.cache.IIdentifiableEntityCacheStrategy
146 public static NonViralName
NewInstance(Rank rank
){
147 return new NonViralName(rank
, null);
151 * Creates a new non viral taxon name instance
152 * only containing its {@link common.Rank rank} and
153 * its {@link common.HomotypicalGroup homotypical group} and
154 * the {@link eu.etaxonomy.cdm.strategy.cache.NonViralNameDefaultCacheStrategy default cache strategy}.
155 * The new non viral taxon name instance will be also added to the set of
156 * non viral taxon names belonging to this homotypical group. If the homotypical
157 * group does not exist a new instance will be created for it.
159 * @param rank the rank to be assigned to this non viral taxon name
160 * @param homotypicalGroup the homotypical group to which this non viral taxon name belongs
161 * @see #NewInstance(Rank)
162 * @see #NonViralName(Rank, HomotypicalGroup)
163 * @see #NonViralName()
164 * @see #NonViralName(Rank, String, String, String, TeamOrPersonBase, INomenclaturalReference, String, HomotypicalGroup)
165 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy
166 * @see eu.etaxonomy.cdm.strategy.cache.INameCacheStrategy
167 * @see eu.etaxonomy.cdm.strategy.cache.IIdentifiableEntityCacheStrategy
169 public static NonViralName
NewInstance(Rank rank
, HomotypicalGroup homotypicalGroup
){
170 return new NonViralName(rank
, homotypicalGroup
);
173 private void setNameCacheStrategy(){
174 if (getClass() == NonViralName
.class){
175 this.cacheStrategy
= NonViralNameDefaultCacheStrategy
.NewInstance();
182 * Returns the {@link eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy cache strategy} used to generate
183 * several strings corresponding to this non viral taxon name
184 * (in particular taxon name caches and author strings).
186 * @return the cache strategy used for this non viral taxon name
187 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy
188 * @see eu.etaxonomy.cdm.strategy.cache.INameCacheStrategy
189 * @see eu.etaxonomy.cdm.strategy.cache.IIdentifiableEntityCacheStrategy
193 public INonViralNameCacheStrategy
getCacheStrategy() {
194 return cacheStrategy
;
197 * @see #getCacheStrategy()
200 public void setCacheStrategy(INonViralNameCacheStrategy cacheStrategy
) {
201 this.cacheStrategy
= cacheStrategy
;
207 * Returns the {@link agent.INomenclaturalAuthor author (team)} that published this non viral
210 * @return the nomenclatural author (team) of this non viral taxon name
211 * @see agent.INomenclaturalAuthor
212 * @see agent.TeamOrPersonBase#getNomenclaturalTitle()
215 @Cascade({CascadeType
.SAVE_UPDATE
})
216 @Target(TeamOrPersonBase
.class)
217 public INomenclaturalAuthor
getCombinationAuthorTeam(){
218 return this.combinationAuthorTeam
;
221 * @see #getCombinationAuthorTeam()
223 public void setCombinationAuthorTeam(INomenclaturalAuthor combinationAuthorTeam
){
224 this.combinationAuthorTeam
= combinationAuthorTeam
;
228 * Returns the {@link agent.INomenclaturalAuthor author (team)} that contributed to
229 * the publication of this non viral taxon name as generally stated by
230 * the {@link #getCombinationAuthorTeam() combination author (team)} itself.
231 * The presence of an author (team) of this non viral taxon name is a
232 * condition for the existence of an ex author (team) for this same name.
234 * @return the nomenclatural ex author (team) of this non viral taxon name
235 * @see #getCombinationAuthorTeam()
236 * @see agent.INomenclaturalAuthor
237 * @see agent.TeamOrPersonBase#getNomenclaturalTitle()
240 @Cascade({CascadeType
.SAVE_UPDATE
})
241 @Target(TeamOrPersonBase
.class)
242 public INomenclaturalAuthor
getExCombinationAuthorTeam(){
243 return this.exCombinationAuthorTeam
;
246 * @see #getExCombinationAuthorTeam()
248 public void setExCombinationAuthorTeam(INomenclaturalAuthor exCombinationAuthorTeam
){
249 this.exCombinationAuthorTeam
= exCombinationAuthorTeam
;
253 * Returns the {@link agent.INomenclaturalAuthor author (team)} that published the original combination
254 * on which this non viral taxon name is nomenclaturally based. Such an
255 * author (team) can only exist if this non viral taxon name is a new
256 * combination due to a taxonomical revision.
258 * @return the nomenclatural basionym author (team) of this non viral taxon name
259 * @see #getCombinationAuthorTeam()
260 * @see agent.INomenclaturalAuthor
261 * @see agent.TeamOrPersonBase#getNomenclaturalTitle()
264 @Cascade({CascadeType
.SAVE_UPDATE
})
265 @Target(TeamOrPersonBase
.class)
266 public INomenclaturalAuthor
getBasionymAuthorTeam(){
267 return basionymAuthorTeam
;
270 * @see #getBasionymAuthorTeam()
272 public void setBasionymAuthorTeam(INomenclaturalAuthor basionymAuthorTeam
) {
273 this.basionymAuthorTeam
= basionymAuthorTeam
;
277 * Returns the {@link agent.INomenclaturalAuthor author (team)} that contributed to
278 * the publication of the original combination this non viral taxon name is
279 * based on. This should have been generally stated by
280 * the {@link #getCombinationAuthorTeam() basionym author (team)} itself.
281 * The presence of a basionym author (team) of this non viral taxon name is a
282 * condition for the existence of an ex basionym author (team)
283 * for this same name.
285 * @return the nomenclatural ex basionym author (team) of this non viral taxon name
286 * @see #getBasionymAuthorTeam()
287 * @see #getCombinationAuthorTeam()
288 * @see agent.INomenclaturalAuthor
289 * @see agent.TeamOrPersonBase#getNomenclaturalTitle()
292 @Cascade({CascadeType
.SAVE_UPDATE
})
293 @Target(TeamOrPersonBase
.class)
294 public INomenclaturalAuthor
getExBasionymAuthorTeam(){
295 return exBasionymAuthorTeam
;
298 * @see #getExBasionymAuthorTeam()
300 public void setExBasionymAuthorTeam(INomenclaturalAuthor exBasionymAuthorTeam
) {
301 this.exBasionymAuthorTeam
= exBasionymAuthorTeam
;
304 * Returns either the scientific name string (without authorship) for this
305 * non viral taxon name if its rank is genus or higher (monomial) or the string for
306 * the genus part of it if its {@link Rank rank} is lower than genus (bi- or trinomial).
307 * Genus or uninomial strings begin with an upper case letter.
309 * @return the string containing the suprageneric name, the genus name or the genus part of this non viral taxon name
310 * @see #getNameCache()
312 public String
getGenusOrUninomial() {
313 return genusOrUninomial
;
317 * @see #getGenusOrUninomial()
319 public void setGenusOrUninomial(String genusOrUninomial
) {
320 this.genusOrUninomial
= genusOrUninomial
;
324 * Returns the genus subdivision epithet string (infrageneric part) for
325 * this non viral taxon name if its {@link Rank rank} is infrageneric (lower than genus and
326 * higher than species aggregate). Genus subdivision epithet strings begin
327 * with an upper case letter.
329 * @return the string containing the infrageneric part of this non viral taxon name
330 * @see #getNameCache()
332 public String
getInfraGenericEpithet(){
333 return this.infraGenericEpithet
;
337 * @see #getInfraGenericEpithet()
339 public void setInfraGenericEpithet(String infraGenericEpithet
){
340 this.infraGenericEpithet
= infraGenericEpithet
;
344 * Returns the species epithet string for this non viral taxon name if its {@link Rank rank} is
345 * species aggregate or lower. Species epithet strings begin with a
348 * @return the string containing the species epithet of this non viral taxon name
349 * @see #getNameCache()
351 public String
getSpecificEpithet(){
352 return this.specificEpithet
;
356 * @see #getSpecificEpithet()
358 public void setSpecificEpithet(String specificEpithet
){
359 this.specificEpithet
= specificEpithet
;
363 * Returns the species subdivision epithet string (infraspecific part) for
364 * this non viral taxon name if its {@link Rank rank} is infraspecific (lower than species).
365 * Species subdivision epithet strings begin with a lower case letter.
367 * @return the string containing the infraspecific part of this non viral taxon name
368 * @see #getNameCache()
370 public String
getInfraSpecificEpithet(){
371 return this.infraSpecificEpithet
;
375 * @see #getInfraSpecificEpithet()
377 public void setInfraSpecificEpithet(String infraSpecificEpithet
){
378 this.infraSpecificEpithet
= infraSpecificEpithet
;
382 * Generates and returns the string with the scientific name of this
383 * non viral taxon name including author strings and maybe year according to
384 * the strategy defined in
385 * {@link eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy INonViralNameCacheStrategy}.
386 * This string may be stored in the inherited
387 * {@link common.IdentifiableEntity#getTitleCache() titleCache} attribute.
388 * This method overrides the generic and inherited
389 * TaxonNameBase#generateTitle() method.
391 * @return the string with the composed name of this non viral taxon name with authorship (and maybe year)
392 * @see common.IdentifiableEntity#generateTitle()
393 * @see common.IdentifiableEntity#getTitleCache()
394 * @see TaxonNameBase#generateTitle()
397 public String
generateTitle(){
398 if (cacheStrategy
== null){
399 logger
.warn("No CacheStrategy defined for nonViralName: " + this.getUuid());
402 return cacheStrategy
.getTitleCache(this);
407 * Generates the composed name string of this non viral taxon name without author
408 * strings or year according to the strategy defined in
409 * {@link eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy INonViralNameCacheStrategy}.
410 * The result might be stored in {@link #getNameCache() nameCache} if the
411 * flag {@link #isProtectedNameCache() protectedNameCache} is not set.
413 * @return the string with the composed name of this non viral taxon name without authors or year
414 * @see #getNameCache()
416 protected String
generateNameCache(){
417 if (cacheStrategy
== null){
418 logger
.warn("No CacheStrategy defined for taxonName: " + this.toString());
421 return cacheStrategy
.getNameCache(this);
426 * Returns or generates the nameCache (scientific name
427 * without author strings and year) string for this non viral taxon name. If the
428 * {@link #isProtectedNameCache() protectedNameCache} flag is not set (False)
429 * the string will be generated according to a defined strategy,
430 * otherwise the value of the actual nameCache string will be returned.
432 * @return the string which identifies this non viral taxon name (without authors or year)
433 * @see #generateNameCache()
435 public String
getNameCache() {
436 if (protectedNameCache
){
437 return this.nameCache
;
439 // is title dirty, i.e. equal NULL?
440 if (nameCache
== null){
441 this.nameCache
= generateNameCache();
447 * Assigns a nameCache string to this non viral taxon name and protects it from being overwritten.
449 * @param nameCache the string which identifies this non viral taxon name (without authors or year)
450 * @see #getNameCache()
452 public void setNameCache(String nameCache
){
453 this.nameCache
= nameCache
;
454 this.setProtectedTitleCache(false);
455 this.setProtectedNameCache(true);
459 * Returns the boolean value of the flag intended to protect (true)
460 * or not (false) the {@link #getNameCache() nameCache} (scientific name without author strings and year)
461 * string of this non viral taxon name.
463 * @return the boolean value of the protectedNameCache flag
464 * @see #getNameCache()
466 public boolean isProtectedNameCache() {
467 return protectedNameCache
;
471 * @see #isProtectedNameCache()
473 public void setProtectedNameCache(boolean protectedNameCache
) {
474 this.protectedNameCache
= protectedNameCache
;
479 * Generates and returns a concatenated and formated authorteams string
480 * including basionym and combination authors of this non viral taxon name
481 * according to the strategy defined in
482 * {@link eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy#getAuthorshipCache(NonViralName) INonViralNameCacheStrategy}.
484 * @return the string with the concatenated and formated authorteams for this non viral taxon name
485 * @see eu.etaxonomy.cdm.strategy.cache.INonViralNameCacheStrategy#getAuthorshipCache(NonViralName)
487 public String
generateAuthorship(){
488 if (cacheStrategy
== null){
489 logger
.warn("No CacheStrategy defined for nonViralName: " + this.getUuid());
492 return ((INonViralNameCacheStrategy
<T
>)cacheStrategy
).getAuthorshipCache((T
)this);
497 * Returns the concatenated and formated authorteams string including
498 * basionym and combination authors of this non viral taxon name.
499 * If the protectedAuthorshipCache flag is set this method returns the
500 * string stored in the the authorshipCache attribute, otherwise it
501 * generates the complete authorship string, returns it and stores it in
502 * the authorshipCache attribute.
504 * @return the string with the concatenated and formated authorteams for this non viral taxon name
505 * @see #generateAuthorship()
507 public String
getAuthorshipCache() {
508 if (protectedAuthorshipCache
){
509 return this.authorshipCache
;
511 // is title dirty, i.e. equal NULL?
512 if (authorshipCache
== null){
513 this.authorshipCache
= generateAuthorship();
515 //TODO get is Dirty of authors
516 this.authorshipCache
= generateAuthorship();
518 return authorshipCache
;
522 * Assigns an authorshipCache string to this non viral taxon name.
524 * @param authorshipCache the string which identifies the complete authorship of this non viral taxon name
525 * @see #getAuthorshipCache()
527 public void setAuthorshipCache(String authorshipCache
) {
528 this.authorshipCache
= authorshipCache
;
534 * Returns the boolean value "true" if the components of this non viral taxon name
535 * follow the rules of the corresponding {@link NomenclaturalCode nomenclatural code},
536 * "false" otherwise. The nomenclatural code depends on
537 * the concrete name subclass ({@link BacterialName BacterialName},
538 * {@link BotanicalName BotanicalName}, {@link CultivarPlantName CultivarPlantName} or
539 * {@link ZoologicalName ZoologicalName} to which this non viral taxon name belongs.
540 * This method overrides the isCodeCompliant method from {@link TaxonNameBase#isCodeCompliant() TaxonNameBase}.
542 * @return the boolean value expressing the compliance of this non viral taxon name to its nomenclatural code
543 * @see TaxonNameBase#isCodeCompliant()
547 public boolean isCodeCompliant() {
549 logger
.warn("is CodeCompliant not yet implemented");
554 * @see eu.etaxonomy.cdm.model.name.TaxonNameBase#getNomeclaturalCode()
557 * Returns null as {@link NomenclaturalCode nomenclatural code} that governs
558 * the construction of this non viral taxon name since there is no specific
559 * nomenclatural code defined. The real implementention takes place in the
560 * subclasses {@link BacterialName BacterialName},
561 * {@link BotanicalName BotanicalName}, {@link CultivarPlantName CultivarPlantName} and
562 * {@link ZoologicalName ZoologicalName}.
563 * This method overrides the getNomeclaturalCode method from {@link TaxonNameBase#getNomeclaturalCode() TaxonNameBase}.
566 * @see #isCodeCompliant()
567 * @see TaxonNameBase#getHasProblem()
571 public NomenclaturalCode
getNomeclaturalCode() {
572 //TODO What is the purpose of overriding the inherited method?
573 logger
.warn("Non Viral Name has no specific Code defined. Use subclasses");
578 * Returns the boolean value of the flag intended to protect (true)
579 * or not (false) the {@link #getAuthorshipCache() authorshipCache} (complete authorship string)
580 * of this non viral taxon name.
582 * @return the boolean value of the protectedAuthorshipCache flag
583 * @see #getAuthorshipCache()
585 public boolean isProtectedAuthorshipCache() {
586 return protectedAuthorshipCache
;
590 * @see #isProtectedAuthorshipCache()
591 * @see #getAuthorshipCache()
593 public void setProtectedAuthorshipCache(boolean protectedAuthorshipCache
) {
594 this.protectedAuthorshipCache
= protectedAuthorshipCache
;