package eu.etaxonomy.cdm.model.description;
-import eu.etaxonomy.cdm.model.common.Language;
-import eu.etaxonomy.cdm.model.common.LanguageString;
-import eu.etaxonomy.cdm.model.common.MultilanguageSet;
-import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
+import java.util.HashMap;
+import java.util.Map;
-import org.apache.log4j.Logger;
-import javax.persistence.*;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import org.apache.log4j.Logger;
+import org.hibernate.annotations.Cascade;
+import org.hibernate.annotations.CascadeType;
+import org.hibernate.envers.Audited;
+import org.hibernate.search.annotations.Indexed;
+
+import eu.etaxonomy.cdm.jaxb.MultilanguageTextAdapter;
+import eu.etaxonomy.cdm.model.common.IMultiLanguageTextHolder;
+import eu.etaxonomy.cdm.model.common.Language;
+import eu.etaxonomy.cdm.model.common.LanguageString;
+import eu.etaxonomy.cdm.model.common.MultilanguageText;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
/**
- * {type is "host" or "hybrid_parent"}
+ * This class represents associations between the described
+ * {@link SpecimenOrObservationBase specimen or observation}
+ * and a second one (for instance a host).
+ * Only {@link SpecimenDescription specimen descriptions} may contain individuals association.
+ * The association itself is described by a {@link MultilanguageText multilanguage text}.
+ * <P>
+ * This class corresponds (partially) to NaturalLanguageDescriptionType
+ * according to the SDD schema.
+ *
* @author m.doering
* @version 1.0
* @created 08-Nov-2007 13:06:28
})
@XmlRootElement(name = "IndividualsAssociation")
@Entity
-public class IndividualsAssociation extends DescriptionElementBase {
-
- static Logger logger = Logger.getLogger(IndividualsAssociation.class);
+@Audited
+@Indexed(index = "eu.etaxonomy.cdm.model.description.DescriptionElementBase")
+public class IndividualsAssociation extends DescriptionElementBase implements IMultiLanguageTextHolder, Cloneable{
+ private static final long serialVersionUID = -4117554860254531809L;
+ @SuppressWarnings("unused")
+ private static final Logger logger = Logger.getLogger(IndividualsAssociation.class);
@XmlElement(name = "Description")
- private MultilanguageSet description;
+ @XmlJavaTypeAdapter(MultilanguageTextAdapter.class)
+ @OneToMany(fetch = FetchType.LAZY)
+ @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE, CascadeType.DELETE, CascadeType.DELETE_ORPHAN })
+ @JoinTable(name = "IndividualAssociation_LanguageString")
+ private Map<Language,LanguageString> description = new HashMap<Language,LanguageString>();
@XmlElement(name = "AssociatedSpecimenOrObservation")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
+ @ManyToOne(fetch = FetchType.LAZY)
+ @Cascade(CascadeType.SAVE_UPDATE)
private SpecimenOrObservationBase associatedSpecimenOrObservation;
-
- /**
- * Factory method
- * @return
+ /**
+ * Class constructor: creates a new empty individuals association instance.
*/
- public static IndividualsAssociation NewInstance(){
- return new IndividualsAssociation();
+ protected IndividualsAssociation(){
+ super(null);
}
- /**
- * Constructor
+ /**
+ * Creates a new empty individuals association instance.
*/
- protected IndividualsAssociation(){
- super(null);
+ public static IndividualsAssociation NewInstance(){
+ IndividualsAssociation result = new IndividualsAssociation();
+ result.setFeature(Feature.INDIVIDUALS_ASSOCIATION());
+ return result;
}
- @ManyToOne
+ /**
+ * Returns the second {@link SpecimenOrObservationBase specimen or observation}
+ * involved in <i>this</i> individuals association.
+ * The first specimen or observation is the specimen or observation
+ * described in the corresponding {@link SpecimenDescription specimen description}.
+ */
public SpecimenOrObservationBase getAssociatedSpecimenOrObservation() {
return associatedSpecimenOrObservation;
}
+ /**
+ * @see #getAssociatedSpecimenOrObservation()
+ */
public void setAssociatedSpecimenOrObservation(
SpecimenOrObservationBase associatedSpecimenOrObservation) {
this.associatedSpecimenOrObservation = associatedSpecimenOrObservation;
}
- public MultilanguageSet getDescription(){
+ /**
+ * Returns the {@link MultilanguageText multilanguage text} used to describe
+ * <i>this</i> individuals association. The different {@link LanguageString language strings}
+ * contained in the multilanguage text should all have the same meaning.
+ */
+ public Map<Language,LanguageString> getDescription(){
return this.description;
}
- private void setDescription(MultilanguageSet description){
- this.description = description;
- }
+
+ /**
+ * Adds a translated {@link LanguageString text in a particular language}
+ * to the {@link MultilanguageText multilanguage text} used to describe
+ * <i>this</i> individuals association.
+ *
+ * @param description the language string describing the individuals association
+ * in a particular language
+ * @see #getDescription()
+ * @see #putDescription(Language, String)
+ * @deprecated should follow the put semantic of maps, this method will be removed in v4.0
+ * Use the {@link #putDescription(LanguageString) putDescription} method instead
+ */
public void addDescription(LanguageString description){
- this.description.add(description);
+ this.putDescription(description);
}
- public void addDescription(String text, Language language){
+
+ /**
+ * Adds a translated {@link LanguageString text in a particular language}
+ * to the {@link MultilanguageText multilanguage text} used to describe
+ * <i>this</i> individuals association.
+ *
+ * @param description the language string describing the individuals association
+ * in a particular language
+ * @see #getDescription()
+ * @see #putDescription(Language, String)
+ *
+ */
+ public void putDescription(LanguageString description){
+ this.description.put(description.getLanguage(),description);
+ }
+ /**
+ * Creates a {@link LanguageString language string} based on the given text string
+ * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text}
+ * used to describe <i>this</i> individuals association.
+ *
+ * @param text the string describing the individuals association
+ * in a particular language
+ * @param language the language in which the text string is formulated
+ * @see #getDescription()
+ * @see #putDescription(LanguageString)
+ */
+ public void putDescription(Language language, String text){
this.description.put(language, LanguageString.NewInstance(text, language));
}
+
+ /**
+ * Creates a {@link LanguageString language string} based on the given text string
+ * and the given {@link Language language} and adds it to the {@link MultilanguageText multilanguage text}
+ * used to describe <i>this</i> individuals association.
+ *
+ * @param text the string describing the individuals association
+ * in a particular language
+ * @param language the language in which the text string is formulated
+ * @see #getDescription()
+ * @see #putDescription(LanguageString)
+ * @deprecated should follow the put semantic of maps, this method will be removed in v4.0
+ * Use the {@link #putDescription(Language, String) putDescription} method instead
+ */
+ public void addDescription(String text, Language language){
+ this.putDescription(language, text);
+ }
+ /**
+ * Removes from the {@link MultilanguageText multilanguage text} used to describe
+ * <i>this</i> individuals association the one {@link LanguageString language string}
+ * with the given {@link Language language}.
+ *
+ * @param language the language in which the language string to be removed
+ * has been formulated
+ * @see #getDescription()
+ */
public void removeDescription(Language language){
this.description.remove(language);
}
-}
\ No newline at end of file
+
+//*********************************** CLONE *****************************************/
+
+ /**
+ * Clones <i>this</i> individuals association. This is a shortcut that enables to create
+ * a new instance that differs only slightly from <i>this</i> individuals association by
+ * modifying only some of the attributes.
+ *
+ * @see eu.etaxonomy.cdm.model.description.DescriptionElementBase#clone()
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public Object clone() {
+
+ try {
+ IndividualsAssociation result = (IndividualsAssociation)super.clone();
+
+ //description
+ result.description = new HashMap<Language, LanguageString>();
+ for (Language language : getDescription().keySet()){
+ //TODO clone needed?
+ LanguageString newLanguageString = (LanguageString)getDescription().get(language).clone();
+ result.description.put(language, newLanguageString);
+ }
+
+
+ return result;
+ //no changes to: associatedSpecimenOrObservation
+ } catch (CloneNotSupportedException e) {
+ logger.warn("Object does not implement cloneable");
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+}