import java.lang.reflect.Method;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import javax.persistence.Column;
import javax.xml.bind.annotation.XmlIDREF;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
-import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import org.apache.log4j.Logger;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.Table;
-import org.hibernate.annotations.Target;
+import org.hibernate.envers.Audited;
+import org.hibernate.search.annotations.Field;
+import org.springframework.util.ReflectionUtils;
import eu.etaxonomy.cdm.model.common.IParsable;
import eu.etaxonomy.cdm.model.common.IReferencedEntity;
"relationsFromThisName",
"relationsToThisName",
"status",
- "descriptions"
-// "taxonBases"
+ "descriptions",
+ "taxonBases"
})
@XmlRootElement(name = "TaxonNameBase")
@Entity
+@Audited
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@Table(appliesTo="TaxonNameBase", indexes = { @Index(name = "taxonNameBaseTitleCacheIndex", columnNames = { "titleCache" }) })
-public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INameCacheStrategy> extends IdentifiableEntity<TaxonNameBase> implements IReferencedEntity, IParsable, IRelated {
+public abstract class TaxonNameBase<T extends TaxonNameBase<?,?>, S extends INameCacheStrategy> extends IdentifiableEntity<S> implements IReferencedEntity, IParsable, IRelated {
- /**
- *
- */
private static final long serialVersionUID = -4530368639601532116L;
-
private static final Logger logger = Logger.getLogger(TaxonNameBase.class);
- private static Method methodDescriptionSetTaxonName;
-
@XmlElement(name = "FullTitleCache")
+ @Column(length=330, name="fullTitleCache")
private String fullTitleCache;
//if true titleCache will not be automatically generated/updated
@XmlElementWrapper(name = "Descriptions")
@XmlElement(name = "Description")
+ @OneToMany(mappedBy="taxonName", fetch= FetchType.LAZY)
+ @Cascade({CascadeType.SAVE_UPDATE})
private Set<TaxonNameDescription> descriptions = new HashSet<TaxonNameDescription>();
@XmlElement(name = "AppendedPhrase")
+ @Field(index= org.hibernate.search.annotations.Index.TOKENIZED)
private String appendedPhrase;
@XmlElement(name = "NomenclaturalMicroReference")
+ @Field(index= org.hibernate.search.annotations.Index.TOKENIZED)
private String nomenclaturalMicroReference;
@XmlAttribute
@XmlElement(name = "TypeDesignation")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
+ @ManyToMany(fetch = FetchType.LAZY)
+ //TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
+ @Cascade(CascadeType.SAVE_UPDATE)
private Set<TypeDesignationBase> typeDesignations = new HashSet<TypeDesignationBase>();
@XmlElement(name = "HomotypicalGroup")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
- private HomotypicalGroup homotypicalGroup = new HomotypicalGroup();
+ @ManyToOne(fetch = FetchType.LAZY)
+ @Cascade({CascadeType.SAVE_UPDATE})
+ private HomotypicalGroup homotypicalGroup;
@XmlElementWrapper(name = "RelationsFromThisName")
@XmlElement(name = "RelationFromThisName")
- @XmlIDREF
- @XmlSchemaType(name = "IDREF")
+ @OneToMany(mappedBy="relatedFrom", fetch= FetchType.LAZY)
+ //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)
+ @Cascade(CascadeType.SAVE_UPDATE)
private Set<NameRelationship> relationsFromThisName = new HashSet<NameRelationship>();
@XmlElementWrapper(name = "RelationsToThisName")
@XmlElement(name = "RelationToThisName")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
+ @OneToMany(mappedBy="relatedTo", fetch= FetchType.LAZY)
+ //@Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
+ @Cascade(CascadeType.SAVE_UPDATE)
private Set<NameRelationship> relationsToThisName = new HashSet<NameRelationship>();
- @XmlElementWrapper(name = "NomenclaturalStatus_")
+ @XmlElementWrapper(name = "NomenclaturalStatuses")
@XmlElement(name = "NomenclaturalStatus")
- @XmlIDREF
- @XmlSchemaType(name = "IDREF")
+ @OneToMany(fetch= FetchType.LAZY)
+ @Cascade({CascadeType.SAVE_UPDATE})
private Set<NomenclaturalStatus> status = new HashSet<NomenclaturalStatus>();
- @XmlTransient
- //@XmlElementWrapper(name = "TaxonBases")
- //@XmlElement(name = "TaxonBase")
+ @XmlElementWrapper(name = "TaxonBases")
+ @XmlElement(name = "TaxonBase")
+ @XmlIDREF
+ @XmlSchemaType(name = "IDREF")
+ @OneToMany(mappedBy="name", fetch= FetchType.LAZY)
private Set<TaxonBase> taxonBases = new HashSet<TaxonBase>();
-
-
-
@XmlElement(name = "Rank")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
+ @ManyToOne(fetch = FetchType.EAGER)
private Rank rank;
-// FIXME: This must be an IDREF to the corresponding nomenclatural reference.
-// @XmlTransient
-// @XmlAnyElement
- @XmlElement(name = "NomenclaturalReference", type = ReferenceBase.class)
+ @XmlElement(name = "NomenclaturalReference")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
- private INomenclaturalReference nomenclaturalReference;
-
- static Method methodTaxonBaseSetName;
+ @ManyToOne(fetch = FetchType.LAZY)
+ @Cascade({CascadeType.SAVE_UPDATE})
+ private ReferenceBase nomenclaturalReference;
// ************* CONSTRUCTORS *************/
/**
* @see #TaxonNameBase(Rank, HomotypicalGroup)
*/
public TaxonNameBase() {
- this(null, null);
+ super();
}
/**
* Class constructor: creates a new taxon name
}
//********* METHODS **************************************/
-
- //@Index(name="TaxonNameBaseTitleCacheIndex")
-// public String getTitleCache(){
-// return super.getTitleCache();
-// }
/**
* Returns the boolean value "false" since the components of <i>this</i> taxon name
public abstract String generateFullTitle();
- @Transient
+ @Transient
public String getFullTitleCache(){
if (protectedFullTitleCache){
return this.fullTitleCache;
}
return fullTitleCache;
}
+
+ @Transient
+ public List<Object> getTaggedName(){
+ return getCacheStrategy().getTaggedName(this);
+ }
public void setFullTitleCache(String fullTitleCache){
setFullTitleCache(fullTitleCache, PROTECTED);
this.setProtectedFullTitleCache(protectCache);
}
- @Column(length=330, name="fullTitleCache")
- @Deprecated //for hibernate use only
- protected String getPersistentFullTitleCache(){
- return getFullTitleCache();
- }
-
- @Deprecated //for hibernate use only
- protected void setPersistentFullTitleCache(String fullTitleCache){
- this.fullTitleCache = fullTitleCache;
- }
-
public boolean isProtectedFullTitleCache() {
return protectedFullTitleCache;
}
* @see #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
*/
@Transient
-// @OneToMany(mappedBy="relatedTo", fetch=FetchType.LAZY)
-// @Cascade({CascadeType.SAVE_UPDATE})
public Set<NameRelationship> getNameRelations() {
Set<NameRelationship> rels = new HashSet<NameRelationship>();
rels.addAll(getRelationsFromThisName());
return rels;
}
-// protected void setNameRelations(Set<NameRelationship> nameRelations) {
-// this.nameRelations = nameRelations;
-// }
-
/**
* Creates a new {@link NameRelationship#NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, String) name relationship} from <i>this</i> taxon name to another taxon name
* and adds it both to the set of {@link #getRelationsFromThisName() relations from <i>this</i> taxon name} and
public void addRelationshipToName(TaxonNameBase toName, NameRelationshipType type, String ruleConsidered){
NameRelationship rel = new NameRelationship(toName, this, type, ruleConsidered);
}
+
+ public void addRelationshipToName(TaxonNameBase toName, NameRelationshipType type, ReferenceBase citation, String microCitation, String ruleConsidered){
+ NameRelationship rel = new NameRelationship(toName, this, type, citation, microCitation, ruleConsidered);
+ }
+
/**
* Creates a new {@link NameRelationship#NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, String) name relationship} from another taxon name to <i>this</i> taxon name
* and adds it both to the set of {@link #getRelationsToThisName() relations to <i>this</i> taxon name} and
public void addRelationshipFromName(TaxonNameBase fromName, NameRelationshipType type, String ruleConsidered){
NameRelationship rel = new NameRelationship(this, fromName, type, ruleConsidered);
}
+ public void addRelationshipFromName(TaxonNameBase fromName, NameRelationshipType type, ReferenceBase citation, String microCitation, String ruleConsidered){
+ NameRelationship rel = new NameRelationship(this, fromName, type, citation, microCitation, ruleConsidered);
+ }
+
/**
* Adds an existing {@link NameRelationship name relationship} either to the set of
* {@link #getRelationsToThisName() relations to <i>this</i> taxon name} or to the set of
this.relationsToThisName.remove(nameRelation);
this.relationsFromThisName.remove(nameRelation);
}
-
public void removeTaxonName(TaxonNameBase taxonName) {
Set<NameRelationship> nameRelationships = new HashSet<NameRelationship>();
* @see #getRelationsToThisName()
* @see #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
*/
- @OneToMany(mappedBy="relatedFrom", fetch= FetchType.LAZY)
- @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
public Set<NameRelationship> getRelationsFromThisName() {
return relationsFromThisName;
}
- private void setRelationsFromThisName(Set<NameRelationship> relationsFromThisName) {
- this.relationsFromThisName = relationsFromThisName;
- }
-
+
/**
* Returns the set of all {@link NameRelationship name relationships}
* in which <i>this</i> taxon name is involved as a target.
* @see #getRelationsFromThisName()
* @see #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
*/
- @OneToMany(mappedBy="relatedTo", fetch= FetchType.LAZY)
- @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
public Set<NameRelationship> getRelationsToThisName() {
return relationsToThisName;
}
- private void setRelationsToThisName(Set<NameRelationship> relationsToThisName) {
- this.relationsToThisName = relationsToThisName;
- }
-
/**
* Returns the set of {@link NomenclaturalStatus nomenclatural status} assigned
* @see NomenclaturalStatus
* @see NomenclaturalStatusType
*/
- @OneToMany(fetch= FetchType.LAZY)
- @Cascade({CascadeType.SAVE_UPDATE})
public Set<NomenclaturalStatus> getStatus() {
return status;
}
- /**
- * @see #getStatus()
- */
- protected void setStatus(Set<NomenclaturalStatus> nomStatus) {
- this.status = nomStatus;
- }
+
/**
* Adds a new {@link NomenclaturalStatus nomenclatural status}
* to <i>this</i> taxon name's set of nomenclatural status.
public void addStatus(NomenclaturalStatus nomStatus) {
this.status.add(nomStatus);
}
+
/**
* Removes one element from the set of nomenclatural status of <i>this</i> taxon name.
* Type and ruleConsidered attributes of the nomenclatural status object
* @see #addBasionym(TaxonNameBase, String)
*/
public void addBasionym(T basionym){
- addBasionym(basionym, null);
+ addBasionym(basionym, null, null, null);
}
/**
* Assigns a taxon name as {@link NameRelationshipType#BASIONYM() basionym} of <i>this</i> taxon name
* @see #getBasionym()
* @see #addBasionym(TaxonNameBase)
*/
- public void addBasionym(T basionym, String ruleConsidered){
+ public void addBasionym(T basionym, ReferenceBase citation, String microcitation, String ruleConsidered){
if (basionym != null){
- basionym.addRelationshipToName(this, NameRelationshipType.BASIONYM(), ruleConsidered);
+ basionym.addRelationshipToName(this, NameRelationshipType.BASIONYM(), citation, microcitation, ruleConsidered);
}
}
//TODO implement
logger.warn("not yet implemented");
}
-
-
-
- /**
- * Returns the {@link eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy cache strategy} used to generate
- * several strings corresponding to <i>this</i> taxon name
- * (in particular taxon name caches and author strings).
- *
- * @return the cache strategy used for <i>this</i> taxon name
- * @see eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy
- * @see eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy
- */
- @Transient
- public abstract S getCacheStrategy();
- /**
- * @see #getCacheStrategy()
- */
- public abstract void setCacheStrategy(S cacheStrategy);
/**
* Returns the taxonomic {@link Rank rank} of <i>this</i> taxon name.
*
* @see Rank
*/
- @ManyToOne
- //@Cascade({CascadeType.SAVE_UPDATE})
public Rank getRank(){
return this.rank;
}
+
/**
* @see #getRank()
*/
* @see eu.etaxonomy.cdm.model.reference.INomenclaturalReference
* @see eu.etaxonomy.cdm.model.reference.ReferenceBase
*/
- @ManyToOne
- @Cascade({CascadeType.SAVE_UPDATE})
- @Target(ReferenceBase.class)
- public INomenclaturalReference getNomenclaturalReference(){
+ public ReferenceBase getNomenclaturalReference(){
return this.nomenclaturalReference;
}
/**
* The corresponding {@link eu.etaxonomy.cdm.model.reference.ReferenceBase.isNomenclaturallyRelevant nomenclaturally relevant flag} will be set to true
* as it is obviously used for nomenclatural purposes.
*
+ * @throws IllegalArgumentException if parameter <code>nomenclaturalReference</code> is not assignable from {@link INomenclaturalReference}
* @see #getNomenclaturalReference()
*/
- public void setNomenclaturalReference(INomenclaturalReference nomenclaturalReference){
- this.nomenclaturalReference = nomenclaturalReference;
+ public void setNomenclaturalReference(ReferenceBase nomenclaturalReference){
+ if(nomenclaturalReference != null){
+ if(!INomenclaturalReference.class.isAssignableFrom(nomenclaturalReference.getClass())){
+ throw new IllegalArgumentException("Parameter nomenclaturalReference is not assignable from INomenclaturalReference");
+ }
+ this.nomenclaturalReference = (ReferenceBase)nomenclaturalReference;
+ } else {
+ this.nomenclaturalReference = null;
+ }
}
/**
public String getAppendedPhrase(){
return this.appendedPhrase;
}
+
/**
* @see #getAppendedPhrase()
*/
this.problemEnds = end;
}
-
-
-
//*********************** TYPE DESIGNATION *********************************************//
-
-
-
/**
* Returns the set of {@link TypeDesignationBase type designations} assigned
* to <i>this</i> taxon name.
* @see NameTypeDesignation
* @see SpecimenTypeDesignation
*/
- @ManyToMany(fetch = FetchType.LAZY)
- //TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
- @Cascade(CascadeType.SAVE_UPDATE)
public Set<TypeDesignationBase> getTypeDesignations() {
return typeDesignations;
}
- /**
- * @see #getNameTypeDesignations()
- */
- private void setTypeDesignations(Set<TypeDesignationBase> typeDesignations) {
- this.typeDesignations = typeDesignations;
- }
-
/**
* Removes one element from the set of {@link TypeDesignationBase type designations} assigned to
* <i>this</i> taxon name. The type designation itself will be nullified.
this.typeDesignations.remove(typeDesignation);
}
-
/**
* Returns the set of {@link SpecimenTypeDesignation specimen type designations} assigned
* to <i>this</i> taxon name. The {@link Rank rank} of <i>this</i> taxon name is generally
boolean isLectoType,
boolean isNotDesignated,
boolean addToAllHomotypicNames) {
- NameTypeDesignation nameTypeDesignation = new NameTypeDesignation(typeSpecies, citation, citationMicroReference, originalNameString, isRejectedType, isConservedType, isNotDesignated);
+ NameTypeDesignation nameTypeDesignation = new NameTypeDesignation(typeSpecies, citation, citationMicroReference, originalNameString, isRejectedType, isConservedType, isLectoType, isNotDesignated);
+ nameTypeDesignation.setLectoType(isLectoType);
addTypeDesignation(nameTypeDesignation, addToAllHomotypicNames);
}
* added to all taxon names of the homotypical group the typified
* taxon name belongs to
* @see #getSpecimenTypeDesignations()
- * @see TypeDesignationStatus
+ * @see SpecimenTypeDesignationStatus
* @see SpecimenTypeDesignation
* @see TypeDesignationBase#isNotDesignated()
*/
public void addSpecimenTypeDesignation(Specimen typeSpecimen,
- TypeDesignationStatus status,
+ SpecimenTypeDesignationStatus status,
ReferenceBase citation,
String citationMicroReference,
String originalNameString,
*
* @see HomotypicalGroup
*/
- @ManyToOne
- @Cascade({CascadeType.SAVE_UPDATE})
+
public HomotypicalGroup getHomotypicalGroup() {
return homotypicalGroup;
}
- @Deprecated //only for bidirectional and persistence use
- protected void setHomotypicalGroup(HomotypicalGroup newHomotypicalGroup) {
- this.homotypicalGroup = newHomotypicalGroup;
+
+ /*
+ * @see #getHomotypicalGroup()
+ */
+ protected void setHomotypicalGroup(HomotypicalGroup homotypicalGroup) {
+ this.homotypicalGroup = homotypicalGroup;
}
// *************************************************************************//
/**
* Not yet implemented
*/
- @Transient
@Deprecated
public String[] getProblems(){
logger.warn("getProblems not yet implemented");
* @see #getTaxa()
* @see #getSynonyms()
*/
- @OneToMany(mappedBy="name", fetch= FetchType.LAZY)
public Set<TaxonBase> getTaxonBases() {
return this.taxonBases;
}
- /**
- * @see #getTaxonBases()
- */
- protected void setTaxonBases(Set<TaxonBase> taxonBases) {
- if (taxonBases == null){
- taxonBases = new HashSet<TaxonBase>();
- }else{
- this.taxonBases = taxonBases;
- }
- }
+
/**
* Adds a new {@link eu.etaxonomy.cdm.model.taxon.TaxonBase taxon base}
* to the set of taxon bases using <i>this</i> taxon name.
*/
//TODO protected
public void addTaxonBase(TaxonBase taxonBase){
+ Method method = ReflectionUtils.findMethod(TaxonBase.class, "setName", new Class[] {TaxonNameBase.class});
+ ReflectionUtils.makeAccessible(method);
+ ReflectionUtils.invokeMethod(method, taxonBase, new Object[] {this});
taxonBases.add(taxonBase);
- initMethods();
- invokeSetMethod(methodTaxonBaseSetName, taxonBase);
}
/**
* Removes one element from the set of {@link eu.etaxonomy.cdm.model.taxon.TaxonBase taxon bases} that refer to <i>this</i> taxon name.
* @see #addTaxonBase(TaxonBase)
*/
public void removeTaxonBase(TaxonBase taxonBase){
+ Method method = ReflectionUtils.findMethod(TaxonBase.class, "setName", new Class[] {TaxonNameBase.class});
+ ReflectionUtils.makeAccessible(method);
+ ReflectionUtils.invokeMethod(method, taxonBase, new Object[] {null});
taxonBases.remove(taxonBase);
- initMethods();
- invokeSetMethodWithNull(methodTaxonBaseSetName, taxonBase);
}
-
- private void initMethods(){
- if (methodTaxonBaseSetName == null){
- try {
- methodTaxonBaseSetName = TaxonBase.class.getDeclaredMethod("setName", TaxonNameBase.class);
- methodTaxonBaseSetName.setAccessible(true);
- } catch (Exception e) {
- e.printStackTrace();
- //TODO handle exception
- }
- }
- if (methodDescriptionSetTaxonName == null){
- try {
- methodDescriptionSetTaxonName = TaxonNameDescription.class.getDeclaredMethod("setTaxonName", TaxonNameBase.class);
- methodDescriptionSetTaxonName.setAccessible(true);
- } catch (Exception e) {
- e.printStackTrace();
- //TODO handle exception
- }
- }
- }
-
-
/**
* Returns the set of {@link eu.etaxonomy.cdm.model.taxon.Taxon taxa} ("accepted/correct" names according to any
* @see #removeDescription(TaxonNameDescription)
* @see eu.etaxonomy.cdm.model.description.TaxonNameDescription
*/
- @OneToMany(mappedBy="taxonName", fetch= FetchType.LAZY)
- @Cascade({CascadeType.SAVE_UPDATE})
public Set<TaxonNameDescription> getDescriptions() {
return descriptions;
}
- /**
- * @see #getDescriptions()
- */
- protected void setDescriptions(Set<TaxonNameDescription> descriptions) {
- this.descriptions = descriptions;
- }
+
/**
* Adds a new {@link eu.etaxonomy.cdm.model.description.TaxonNameDescription taxon name description}
* to the set of taxon name descriptions assigned to <i>this</i> taxon name. The
* @see #removeDescription(TaxonNameDescription)
*/
public void addDescription(TaxonNameDescription description) {
- initMethods();
- this.invokeSetMethod(methodDescriptionSetTaxonName, description);
+ java.lang.reflect.Field field = ReflectionUtils.findField(TaxonNameDescription.class, "taxonName", TaxonNameBase.class);
+ ReflectionUtils.makeAccessible(field);
+ ReflectionUtils.setField(field, description, this);
descriptions.add(description);
}
/**
* @see eu.etaxonomy.cdm.model.description.TaxonNameDescription#getTaxonName()
*/
public void removeDescription(TaxonNameDescription description) {
- initMethods();
- this.invokeSetMethod(methodDescriptionSetTaxonName, null);
+ java.lang.reflect.Field field = ReflectionUtils.findField(TaxonNameDescription.class, "taxonName", TaxonNameBase.class);
+ ReflectionUtils.makeAccessible(field);
+ ReflectionUtils.setField(field, description, null);
descriptions.remove(description);
}
-
-
-
-
-
// ***********
/**
* Returns the boolean value indicating whether a given taxon name belongs
* @return the boolean value of the check
* @see HomotypicalGroup
*/
+ @Transient
public boolean isHomotypic(TaxonNameBase homoTypicName) {
if (homoTypicName == null) {
return false;
return false;
}
-
-
//********* Rank comparison shortcuts ********************//
/**
* Returns the boolean value indicating whether the taxonomic {@link Rank rank} of <i>this</i>
* @see #isCodeCompliant()
* @see #getHasProblem()
*/
- @Transient
abstract public NomenclaturalCode getNomenclaturalCode();
/* (non-Javadoc)
* @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
* @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
* @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
*/
- @Override
- public String generateTitle() {
- // TODO Auto-generated method stub
- logger.warn("not yet implemented");
- return null;
- }
-
+// @Override
+// public abstract String generateTitle();
}