(no commit message)
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / name / TaxonNameBase.java
index 535613aefb038973bc9f29da6a7dd16d3bd286f7..cf376049226cc1683c3a900a0408075c5d684131 100644 (file)
@@ -16,7 +16,6 @@ import eu.etaxonomy.cdm.model.reference.StrictReferenceBase;
 import eu.etaxonomy.cdm.model.taxon.Synonym;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
-import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
 import eu.etaxonomy.cdm.model.common.IParsable;
 import eu.etaxonomy.cdm.model.common.IRelated;
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
@@ -27,6 +26,7 @@ import eu.etaxonomy.cdm.model.common.RelationshipBase;
 import org.apache.log4j.Logger;
 import org.hibernate.annotations.Cascade;
 import org.hibernate.annotations.CascadeType;
+import org.hibernate.annotations.Index;
 import org.hibernate.annotations.Target;
 
 import eu.etaxonomy.cdm.strategy.cache.INameCacheStrategy;
@@ -40,11 +40,9 @@ import javax.persistence.*;
 
 /**
  * The upmost (abstract) class for scientific taxon names regardless of any
- * particular nomenclatural code. The scientific name including author strings and
- * maybe year can be stored as a string in the inherited {@link common.IdentifiableEntity#getTitleCache() titleCache} attribute.
- * The scientific name string without author strings and year can be stored in the {@link #getNameCache() nameCache} attribute.
- * The scientific taxon name does not depend on the use made of it
- * in a publication or a treatment ({@link taxon.TaxonBase taxon concept respectively potential taxon})
+ * particular nomenclature code. The scientific taxon name does not depend
+ * on the use made of it in a publication or a treatment
+ * ({@link taxon.TaxonBase taxon concept respectively potential taxon})
  * as an {@link taxon.Taxon "accepted" respectively "correct" (taxon) name}
  * or as a {@link taxon.Synonym synonym}.
  * 
@@ -56,11 +54,11 @@ import javax.persistence.*;
 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
 public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCacheStrategy> extends IdentifiableEntity<TaxonNameBase> implements IReferencedEntity, IParsable, IRelated {
        static Logger logger = Logger.getLogger(TaxonNameBase.class);
-       //Non-atomised addition to a name not ruled by a nomenclatural code
        private String appendedPhrase;
        private String nomenclaturalMicroReference;
        private boolean hasProblem = false;
        protected Set<NameTypeDesignation> nameTypeDesignations  = new HashSet<NameTypeDesignation>();
+       private Set<SpecimenTypeDesignation> specimenTypeDesignations = new HashSet<SpecimenTypeDesignation>();
        private HomotypicalGroup homotypicalGroup = new HomotypicalGroup();
        private Set<NameRelationship> relationsFromThisName = new HashSet<NameRelationship>();
        private Set<NameRelationship> relationsToThisName = new HashSet<NameRelationship>();
@@ -69,13 +67,11 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
        private Rank rank;
        private INomenclaturalReference nomenclaturalReference;
 
-       protected boolean protectedNameCache;
-       
        static Method methodTaxonBaseSetName;
        
 // ************* CONSTRUCTORS *************/   
        /** 
-        * Class constructor: creates a new empty taxon name instance.
+        * Class constructor: creates a new empty taxon name.
         * 
         * @see #TaxonNameBase(Rank)
         * @see #TaxonNameBase(HomotypicalGroup)
@@ -85,7 +81,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
                this(null, null);
        }
        /** 
-        * Class constructor: creates a new taxon name instance
+        * Class constructor: creates a new taxon name
         * only containing its {@link common.Rank rank}.
         * 
         * @param  rank  the rank to be assigned to this taxon name
@@ -97,9 +93,9 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
                this(rank, null);
        }
        /** 
-        * Class constructor: creates a new taxon name instance
+        * Class constructor: creates a new taxon name
         * only containing its {@link common.HomotypicalGroup homotypical group}.
-        * The new taxon name instance will be also added to the set of taxon names
+        * The new taxon name will be also added to the set of taxon names
         * belonging to this homotypical group. If the homotypical group 
         * does not exist a new instance will be created for it.
         * 
@@ -112,7 +108,7 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
                this(null, homotypicalGroup);
        }
        /** 
-        * Class constructor: creates a new instance of a taxon name
+        * Class constructor: creates a new taxon name
         * only containing its {@link common.Rank rank} and
         * its {@link common.HomotypicalGroup homotypical group}.
         * 
@@ -133,11 +129,15 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
        
 //********* METHODS **************************************/
 
+       //@Index(name="TaxonNameBaseTitleCacheIndex")
+//     public String getTitleCache(){
+//             return super.getTitleCache();
+//     }
        
        /**
         * Returns the boolean value "true" if the components of this taxon name
         * follow the rules of the corresponding {@link NomenclaturalCode nomenclatural code},
-        * "false" otherwise. The nomenclatural code depends on
+        * "false" otherwise. The nomenclature code depends on
         * the concrete name subclass ({@link BacterialName BacterialName},
         * {@link BotanicalName BotanicalName}, {@link CultivarPlantName CultivarPlantName},
         * {@link ZoologicalName ZoologicalName} or {@link ViralName ViralName}) 
@@ -467,16 +467,14 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
        }
 
        /**
-        * Returns the boolean value of the flag indicating whether the 
-        * or not (false) the {@link #getNameCache() nameCache} (scientific name without author strings and year)
-        * string of this taxon name. This flag shows whether the getNameCache
-        * method should return a generated value (false) or the present name cache
-        * string (true).  
+        * Returns the boolean value of the flag indicating whether the used {@link eu.etaxonomy.cdm.strategy.parser.INonViralNameParser parser} 
+        * method was able to parse the taxon name string successfully (false)
+        * or not (true). The parser itself may also depend on the {@link NomenclaturalCode nomenclatural code}
+        * governing the construction of this taxon name.
         *  
-        * @return  the boolean value of the protectedNameCache flag
+        * @return  the boolean value of the hasProblem flag
         * @see     #getNameCache()
         */
-       //this flag will be set to true if the parseName method was unable to successfully parse the name
        public boolean getHasProblem(){
                return this.hasProblem;
        }
@@ -487,6 +485,8 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
                this.hasProblem = hasProblem;
        }
        /**
+        * Returns exactly the same boolean value as the {@link #getHasProblem() getHasProblem} method.  
+        *  
         * @see  #getHasProblem()
         */
        public boolean hasProblem(){
@@ -494,30 +494,144 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
        }
 
 
+       /** 
+        * Returns the set of {@link NameTypeDesignation name type designations} assigned
+        * to this taxon name the rank of which must be above "species".
+        * The name type designations include all the taxon names used to typify
+        * this name and eventually the rejected or conserved status
+        * of these designations.
+        *
+        * @see     NameTypeDesignation
+        * @see     SpecimenTypeDesignation
+        */
        @OneToMany
        //TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
        @Cascade(CascadeType.SAVE_UPDATE)
        public Set<NameTypeDesignation> getNameTypeDesignations() {
                return nameTypeDesignations;
        }
+       /** 
+        * @see     #getNameTypeDesignations()
+        */
        protected void setNameTypeDesignations(Set<NameTypeDesignation> nameTypeDesignations) {
                this.nameTypeDesignations = nameTypeDesignations;
        }
+
        
-       public void addTypeDesignation(TaxonNameBase typeSpecies, ReferenceBase citation, String citationMicroReference, String originalNameString, boolean isRejectedType, boolean isConservedType) {
+       /** 
+        * Creates and adds a new {@link NameTypeDesignation name type designation}
+        * to this taxon name's set of name type designations.
+        *
+        * @param  typeSpecies                          the taxon name to be used as type of this taxon name
+        * @param  citation                                     the reference for this new designation
+        * @param  citationMicroReference       the string with the details (generally pages) within the reference
+        * @param  originalNameString           the taxon name used in the reference to assert this designation
+        * @param  isRejectedType                       the boolean status for rejected
+        * @param  isConservedType                      the boolean status for conserved
+        * @see                                                         #getNameTypeDesignations()
+        * @see                                                         #addTypeDesignation(Specimen, TypeDesignationStatus, ReferenceBase, String, String)
+        */
+       public void addNameTypeDesignation(TaxonNameBase typeSpecies, ReferenceBase citation, String citationMicroReference, String originalNameString, boolean isRejectedType, boolean isConservedType) {
                NameTypeDesignation td = new NameTypeDesignation(this, typeSpecies, citation, citationMicroReference, originalNameString, isRejectedType, isConservedType);
        }
-       public void addTypeDesignation(Specimen typeSpecimen, TypeDesignationStatus status, ReferenceBase citation, String citationMicroReference, String originalNameString) {
-               this.homotypicalGroup.addTypeDesignation(typeSpecimen, status,  citation, citationMicroReference, originalNameString);
-       }
-       public void removeTypeDesignation(NameTypeDesignation typeDesignation) {
+       
+       /** 
+        * Removes one element from the set of {@link NameTypeDesignation name type designations} of this taxon name.
+        * The name type designation itself will be nullified.
+        *
+        * @param  typeDesignation  the name type designation of this taxon name which should be deleted
+        * @see                                 #getNameTypeDesignations()
+        * @see                                 #removeTypeDesignation(SpecimenTypeDesignation)
+        */
+       public void removeNameTypeDesignation(NameTypeDesignation typeDesignation) {
+               //TODO
+               logger.warn("not yet fully implemented: nullify the name type designation itself?");
                this.nameTypeDesignations.remove(typeDesignation);
        }
+       
+       /**
+        * @return the specimenTypeDesignations
+        */
+       @ManyToMany
+       @Cascade(CascadeType.SAVE_UPDATE)
+       public Set<SpecimenTypeDesignation> getSpecimenTypeDesignations() {
+               return specimenTypeDesignations;
+       }
+       /**
+        * @param specimenTypeDesignations the specimenTypeDesignations to set
+        */
+       protected void setSpecimenTypeDesignations(Set<SpecimenTypeDesignation> specimenTypeDesignations) {
+               this.specimenTypeDesignations = specimenTypeDesignations;
+       }
+       
+       /** 
+        * Returns the set of {@link SpecimenTypeDesignation specimen type designations} assigned
+        * indirectly to this taxon name through its {@link HomotypicalGroup homotypical group}.
+        * The rank of this taxon name is generally "species" or below.
+        * The specimen type designations include all the specimens on which
+        * the typification of this name is based (and which are common to all
+        * taxon names belonging to the homotypical group) and eventually
+        * the status of these designations.
+        *
+        * @see     SpecimenTypeDesignation
+        * @see     NameTypeDesignation
+        */
+       @Transient
+       public Set<SpecimenTypeDesignation> getSpecimenTypeDesignationsOfHomotypicalGroup() {
+               return this.getHomotypicalGroup().getTypeDesignations();
+       }
+       
+       /** 
+        * Adds a new {@link SpecimenTypeDesignation specimen type designation}
+        * to the set of specimen type designations assigned to the
+        * {@link HomotypicalGroup homotypical group} to which this taxon name belongs.
+        *
+        * @param  typeSpecimen                         the specimen to be used as a type for this taxon name's homotypical group
+        * @param  status                                       the specimen type designation status
+        * @param  citation                                     the reference for this new specimen type designation
+        * @param  citationMicroReference       the string with the details (generally pages) within the reference
+        * @param  originalNameString           the taxon name used in the reference to assert this designation
+        * @see                                                         HomotypicalGroup#getTypeDesignations()
+        * @see                                                         #addTypeDesignation(TaxonNameBase, ReferenceBase, String, String, boolean, boolean)
+        * @see                                                         TypeDesignationStatus
+        */
+       public void addSpecimenTypeDesignation(Specimen typeSpecimen, TypeDesignationStatus status, ReferenceBase citation, String citationMicroReference, String originalNameString, boolean addToAllNames) {
+               SpecimenTypeDesignation specimenTypeDesignation = 
+                       SpecimenTypeDesignation.NewInstance(typeSpecimen, status, citation, citationMicroReference, originalNameString);
+               this.getHomotypicalGroup().addTypeDesignation(specimenTypeDesignation, addToAllNames);
+       }
+
+       //only to be used for xxx
+       protected void addSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation) {
+               this.specimenTypeDesignations.add(specimenTypeDesignation);
+       }
+       
+       //only to be used for xxx
+       protected void removeSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation) {
+               this.specimenTypeDesignations.remove(specimenTypeDesignation);
+       }
+
+       /** 
+        * Removes one element from the set of {@link SpecimenTypeDesignation specimen type designations} assigned to the
+        * {@link HomotypicalGroup homotypical group} to which this taxon name belongs.
+        * The specimen type designation itself will be nullified.
+        *
+        * @param  typeDesignation  the specimen type designation which should be deleted
+        * @see                                 HomotypicalGroup#getTypeDesignations()
+        * @see                                 #removeTypeDesignation(NameTypeDesignation)
+        */
        public void removeTypeDesignation(SpecimenTypeDesignation typeDesignation) {
+               logger.warn("not yet fully implemented: nullify the specimen type designation itself?");
                this.homotypicalGroup.removeTypeDesignation(typeDesignation);
        }
 
-
+       /** 
+        * Returns the {@link HomotypicalGroup homotypical group} to which
+        * this taxon name belongs. A homotypical group represents all taxon names
+        * that share the same type specimens.
+        *
+        * @see         HomotypicalGroup
+        */
        @ManyToOne
        @Cascade({CascadeType.SAVE_UPDATE})
        public HomotypicalGroup getHomotypicalGroup() {
@@ -530,10 +644,20 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
 
        @Transient
        public StrictReferenceBase getCitation(){
+               //TODO What is the purpose of this method differing from the getNomenclaturalReference method? 
                logger.warn("getCitation not yet implemented");
                return null;
        }
 
+       /** 
+        * Returns the complete string containing the
+        * {@link reference.INomenclaturalReference#getNomenclaturalCitation() nomenclatural reference citation}
+        * (including {@link #getNomenclaturalMicroReference() details}) assigned to this taxon name.
+        * 
+        * @see reference.INomenclaturalReference#getNomenclaturalCitation()
+        * @see #getNomenclaturalReference()
+        * @see #getNomenclaturalMicroReference()
+        */
        @Transient
        public String getCitationString(){
                logger.warn("getCitationString not yet implemented");
@@ -547,8 +671,11 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
        }
 
        /**
-        * returns year of according nomenclatural reference, null if nomenclatural
-        * reference does not exist
+        * Returns the string containing the publication date (generally only year)
+        * of the nomenclatural reference, null if there is no nomenclatural
+        * reference.
+        * 
+        * @see reference.INomenclaturalReference#getYear()
         */
        @Transient
        public String getReferenceYear(){
@@ -559,10 +686,24 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
                }
        }
 
+       /** 
+        * Returns the set of {@link taxon.TaxonBase taxon bases} that refer to this taxon name.
+        * In this context a taxon base means the use of a taxon name by a reference
+        * either as a taxon ("accepted/correct" name) or as a (junior) synonym.
+        * A taxon name can be used by several distinct references but only once
+        * within a taxonomic treatment (identified by one reference).
+        *
+        * @see  taxon.TaxonBase
+        * @see #getTaxa()
+        * @see #getSynonyms()
+        */
        @OneToMany(mappedBy="name", fetch= FetchType.EAGER)
        public Set<TaxonBase> getTaxonBases() {
                return this.taxonBases;
        }
+       /** 
+        * @see     #getTaxonBases()
+        */
        protected void setTaxonBases(Set<TaxonBase> taxonBases) {
                if (taxonBases == null){
                        taxonBases = new HashSet<TaxonBase>();
@@ -570,12 +711,24 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
                        this.taxonBases = taxonBases;
                }
        }
+       /** 
+        * Adds a new {@link taxon.TaxonBase taxon base}
+        * to the set of taxon bases using this taxon name.
+        *
+        * @param  taxonBase  the taxon base to be added
+        * @see                           #getTaxonBases()
+        */
        //TODO protected
        public void addTaxonBase(TaxonBase taxonBase){
                taxonBases.add(taxonBase);
                initMethods();
                invokeSetMethod(methodTaxonBaseSetName, taxonBase);
        }
+       public void removeTaxonBase(TaxonBase taxonBase){
+               taxonBases.remove(taxonBase);
+               initMethods();
+               invokeSetMethodWithNull(methodTaxonBaseSetName, taxonBase);
+       }
 
        private void initMethods(){
                if (methodTaxonBaseSetName == null){
@@ -591,8 +744,13 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
        
        
        /**
-        * Return a set of taxa that use this name.
-        * @return Set<Taxon> The set of taxa this TaxonName belongs to
+        * Returns the set of {@link taxon.Taxon taxa} ("accepted/correct" names according to any
+        * reference) that are based on this taxon name. This set is a subset of
+        * the set returned by getTaxonBases(). 
+        * 
+        * @see taxon.Taxon
+        * @see #getTaxonBases()
+        * @see #getSynonyms()
         */
        @Transient
        public Set<Taxon> getTaxa(){
@@ -606,8 +764,13 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
        }
        
        /**
-        * Return a set of synonyms that use this name
-        * @return The set of synonyms this TaxonName belongs to
+        * Returns the set of {@link taxon.Synonym (junior) synonyms} (according to any
+        * reference) that are based on this taxon name. This set is a subset of
+        * the set returned by getTaxonBases(). 
+        * 
+        * @see taxon.Synonym
+        * @see #getTaxonBases()
+        * @see #getTaxa()
         */
        @Transient
        public Set<Synonym> getSynonyms() {
@@ -620,12 +783,17 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
                return result;
        }
        
-       @Transient
-       public Set<SpecimenTypeDesignation> getSpecimenTypeDesignations() {
-               return this.getHomotypicalGroup().getTypeDesignations();
-       }
-       
 // ***********
+       /**
+        * Returns the boolean value indicating whether a given taxon name belongs
+        * to the same {@link HomotypicalGroup homotypical group} as this taxon name (true)
+        * or not (false). Returns "true" only if the homotypical groups of both
+        * taxon names exist and if they are identical. 
+        *
+        * @param       homoTypicName  the taxon name the homotypical group of which is to be checked
+        * @return                         the boolean value of the check
+        * @see                            HomotypicalGroup
+        */
        public boolean isHomotypic(TaxonNameBase homoTypicName) {
                if (homoTypicName == null) {
                        return false;
@@ -643,36 +811,91 @@ public abstract class TaxonNameBase<T extends TaxonNameBase, S extends INameCach
        
        
 //*********  Rank comparison shortcuts   ********************//
+       /**
+        * Returns the boolean value indicating whether the taxonomic rank of this
+        * taxon name is higher than the genus rank (true) or not (false).
+        * Suprageneric non viral names are monomials.
+        * 
+        * @see  #isGenus()
+        * @see  #isInfraGeneric()
+        * @see  #isSpecies()
+        * @see  #isInfraSpecific()
+        */
        @Transient
        public boolean isSupraGeneric() {
                return getRank().isSupraGeneric();
        }
+       /**
+        * Returns the boolean value indicating whether the taxonomic rank of this
+        * taxon name is the genus rank (true) or not (false). Non viral names with
+        * genus rank are monomials.
+        *
+        * @see  #isSupraGeneric()
+        * @see  #isInfraGeneric()
+        * @see  #isSpecies()
+        * @see  #isInfraSpecific()
+        */
        @Transient
        public boolean isGenus() {
                return getRank().isGenus();
        }
+       /**
+        * Returns the boolean value indicating whether the taxonomic rank of this
+        * taxon name is higher than the species rank and lower than
+        * the genus rank (true) or not (false). Infrageneric non viral names
+        * are binomials.
+        *
+        * @see  #isSupraGeneric()
+        * @see  #isGenus()
+        * @see  #isSpecies()
+        * @see  #isInfraSpecific()
+        */
        @Transient
        public boolean isInfraGeneric() {
                return getRank().isInfraGeneric();
        }
+       /**
+        * Returns the boolean value indicating whether the taxonomic rank of this
+        * taxon name is the species rank (true) or not (false). Non viral names
+        * with species rank are binomials.
+
+        *
+        * @see  #isSupraGeneric()
+        * @see  #isGenus()
+        * @see  #isInfraGeneric()
+        * @see  #isInfraSpecific()
+        */
        @Transient
        public boolean isSpecies() {
                return getRank().isSpecies();
        }
+       /**
+        * Returns the boolean value indicating whether the taxonomic rank of this
+        * taxon name is lower than the species rank (true) or not (false).
+        * Infraspecific non viral names are trinomials.
+        *
+        * @see  #isSupraGeneric()
+        * @see  #isGenus()
+        * @see  #isInfraGeneric()
+        * @see  #isSpecies()
+        */
        @Transient
        public boolean isInfraSpecific() {
                return getRank().isInfraSpecific();
        }
        
        
+       /**
+        * Returns the {@link NomenclaturalCode nomenclatural code} that governs
+        * the construction of this taxon name. Each taxon name is governed by one
+        * and only one nomenclatural code. 
+        *
+        * @see  #isCodeCompliant()
+        * @see  #getHasProblem()
+        */
        @Transient
        abstract public NomenclaturalCode getNomeclaturalCode();
 
-       @Override
-       public String generateTitle() {
-               // TODO Auto-generated method stub
-               return null;
-       }
        
 
 }
\ No newline at end of file