import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
+import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.UUID;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlID;
+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 javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
+
/**
* The base class for all CDM domain classes implementing UUIDs and bean property change event firing.
* It provides a globally unique UUID and keeps track of creation date and person.
* @author m.doering
*
*/
+@XmlAccessorType(XmlAccessType.PROPERTY)
+@XmlType(name = "CdmBase", propOrder = {
+ "created",
+ "createdBy"
+})
+@XmlRootElement(name = "CdmBase")
@MappedSuperclass
-public abstract class CdmBase implements Serializable{
+public abstract class CdmBase implements Serializable, ICdmBase{
+
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
private int id;
- private UUID uuid;
+ private UUID uuid;
private Calendar created;
- private Person createdBy;
+ private Person createdBy;
/**
* Class constructor assigning a unique UUID and creation date.
this.uuid = UUID.randomUUID();
this.setCreated(Calendar.getInstance());
}
-
/**
* see {@link PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)}
propertyChangeSupport.firePropertyChange(evt);
}
- /**
- * Returns local unique identifier for the concrete subclass
- * @return
- */
- @Id
- @GeneratedValue(generator = "system-increment")
- public int getId() {
- return this.id;
- }
- /**
- * Assigns a unique local ID to this object.
- * Because of the EJB3 @Id and @GeneratedValue annotation this id will be
- * set automatically by the persistence framework when object is saved.
- * @param id
- */
- public void setId(int id) {
- this.id = id;
- }
-
-
/**
* Method for hibernate only to read the UUID value as a simple string from the object and persist it (e.g. in a database).
* For reading the UUID please use getUuid method
* @return String representation of the UUID
*/
+ @XmlAttribute(name = "uuid", required = true)
+ @XmlID
+ @XmlSchemaType(name = "ID")
private String getStrUuid() {
return this.uuid.toString();
}
}
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.model.common.ICdmBase#getId()
+ */
+ @XmlAttribute(name = "id", required = true)
+ @Id
+ @GeneratedValue(generator = "system-increment")
+ public int getId() {
+ return this.id;
+ }
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.model.common.ICdmBase#setId(int)
+ */
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.model.common.ICdmBase#getUuid()
+ */
+ @XmlTransient
@Transient
public UUID getUuid() {
return this.uuid;
}
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.model.common.ICdmBase#setUuid(java.util.UUID)
+ */
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.model.common.ICdmBase#getCreated()
+ */
+ @XmlElement (name = "Created")
@Temporal(TemporalType.TIMESTAMP)
@Basic(fetch = FetchType.LAZY)
public Calendar getCreated() {
return created;
}
- /**
- * Sets the timestamp this object was created.
- * Most databases cannot store milliseconds, so they are removed by this method.
- * Caution: We are planning to replace the Calendar class with a different datetime representation which is more suitable for hibernate
- * see {@link http://dev.e-taxonomy.eu/trac/ticket/247 TRAC ticket}
- *
- * @param created
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.model.common.ICdmBase#setCreated(java.util.Calendar)
*/
public void setCreated(Calendar created) {
if (created != null){
}
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.model.common.ICdmBase#getCreatedBy()
+ */
+ @XmlElement (name = "CreatedBy")
@ManyToOne(fetch=FetchType.LAZY)
@Cascade( { CascadeType.SAVE_UPDATE })
public Person getCreatedBy() {
return this.createdBy;
}
+ /* (non-Javadoc)
+ * @see eu.etaxonomy.cdm.model.common.ICdmBase#setCreatedBy(eu.etaxonomy.cdm.model.agent.Person)
+ */
public void setCreatedBy(Person createdBy) {
this.createdBy = createdBy;
}
/**
- * Is true if UUID and created timestamp are the same for the passed Object and this one.
+ * Is true if UUID is the same for the passed Object and this one.
* @see java.lang.Object#equals(java.lang.Object)
+ * See {@link http://www.hibernate.org/109.html hibernate109}, {@link http://www.geocities.com/technofundo/tech/java/equalhash.html geocities}
+ * or {@link http://www.ibm.com/developerworks/java/library/j-jtp05273.html ibm}
+ * for more information about equals and hashcode.
*/
@Override
public boolean equals(Object obj) {
+ if (obj == this){
+ return true;
+ }
if (obj == null){
return false;
- }else if (CdmBase.class.isAssignableFrom(obj.getClass())){
- CdmBase cdmObj = (CdmBase)obj;
- boolean uuidEqual = cdmObj.getUuid().equals(this.getUuid());
- boolean createdEqual = cdmObj.getCreated().equals(this.getCreated());
- if (uuidEqual && createdEqual){
- return true;
- }
}
- return false;
+ if (!CdmBase.class.isAssignableFrom(obj.getClass())){
+ return false;
+ }
+ ICdmBase cdmObj = (ICdmBase)obj;
+ boolean uuidEqual = cdmObj.getUuid().equals(this.getUuid());
+ boolean createdEqual = cdmObj.getCreated().equals(this.getCreated());
+ if (! uuidEqual || !createdEqual){
+ return false;
+ }
+ return true;
}
+
+ /** Overrides {@link java.lang.Object#hashCode()}
+ * See {@link http://www.hibernate.org/109.html hibernate109}, {@link http://www.geocities.com/technofundo/tech/java/equalhash.html geocities}
+ * or {@link http://www.ibm.com/developerworks/java/library/j-jtp05273.html ibm}
+ * for more information about equals and hashcode.
+ */
+ @Override
+ public int hashCode() {
+ int hashCode = 7;
+ hashCode = 29 * hashCode + this.getUuid().hashCode();
+ return hashCode;
+ }
+
/**
- * Returns the class, id and uuid as a string for any CDM object.
+ * Overrides {@link java.lang.Object#toString()}.
+ * This returns an String that identifies the object well without beeing necessarily unique.
+ * Specification: This method should never call other object' methods so it can be well used for debugging
+ * without problems like lazy loading, unreal states etc.
+ * Note: If overriding this method's javadoc always copy or link the above requirement.
+ * If not overwritten by a subclass method returns the class, id and uuid as a string for any CDM object.
* For example: Taxon#13<b5938a98-c1de-4dda-b040-d5cc5bfb3bc0>
* @see java.lang.Object#toString()
*/
return this.getClass().getSimpleName()+"#"+this.getId()+"<"+this.getUuid()+">";
}
+ protected void invokeSetMethod(Method method, Object object){
+ try {
+ method.invoke(object, this);
+ } catch (Exception e) {
+ e.printStackTrace();
+ //TODO handle exceptioin;
+ }
+ }
+
+ protected void invokeSetMethodWithNull(Method method, Object object){
+ try {
+ Object[] nul = new Object[]{null};
+ method.invoke(object, nul);
+ } catch (Exception e) {
+ e.printStackTrace();
+ //TODO handle exceptioin;
+ }
+ }
+
+//********************** CLONE *****************************************/
+
+ protected void clone(CdmBase clone){
+ clone.setCreatedBy(createdBy);
+ clone.setId(id);
+ //Constructor Attributes
+ //clone.setCreated(created);
+ //clone.setUuid(getUuid());
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#clone()
+ */
+ public Object clone() throws CloneNotSupportedException{
+ CdmBase result = (CdmBase)super.clone();
+
+ //TODO ?
+ result.setId(0);
+ result.setUuid(UUID.randomUUID());
+ result.setCreated(Calendar.getInstance());
+ result.setCreatedBy(null);
+
+ //no changes to: -
+ return result;
+ }
+
}