(no commit message)
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / CdmBase.java
1 package eu.etaxonomy.cdm.model.common;
2
3 import java.beans.PropertyChangeEvent;
4 import java.beans.PropertyChangeListener;
5 import java.beans.PropertyChangeSupport;
6 import java.io.Serializable;
7 import java.util.Calendar;
8 import java.util.UUID;
9
10 import javax.persistence.Basic;
11 import javax.persistence.FetchType;
12 import javax.persistence.GeneratedValue;
13 import javax.persistence.Id;
14 import javax.persistence.ManyToOne;
15 import javax.persistence.MappedSuperclass;
16 import javax.persistence.Temporal;
17 import javax.persistence.TemporalType;
18 import javax.persistence.Transient;
19
20 import org.hibernate.annotations.Cascade;
21 import org.hibernate.annotations.CascadeType;
22
23 import eu.etaxonomy.cdm.model.agent.Person;
24
25
26
27 /**
28 * The base class for all CDM domain classes implementing UUIDs and bean property change event firing.
29 * It provides a globally unique UUID and keeps track of creation date and person.
30 * The UUID is the same for different versions (see {@link VersionableEntity}) of a CDM object, so a locally unique id exists in addition
31 * that allows to safely access and store several objects (=version) with the same UUID.
32 *
33 * This class together with the {@link eu.etaxonomy.cdm.aspectj.PropertyChangeAspect}
34 * will fire bean change events to all registered listeners. Listener registration and event firing
35 * is done with the help of the {@link PropertyChangeSupport} class.
36 *
37 * @author m.doering
38 *
39 */
40 @MappedSuperclass
41 public abstract class CdmBase implements Serializable, ICdmBase{
42 private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
43 private int id;
44 private UUID uuid;
45 private Calendar created;
46 private Person createdBy;
47
48 /**
49 * Class constructor assigning a unique UUID and creation date.
50 * UUID can be changed later via setUuid method.
51 */
52 public CdmBase() {
53 this.uuid = UUID.randomUUID();
54 this.setCreated(Calendar.getInstance());
55 }
56
57 /**
58 * see {@link PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)}
59 * @param listener
60 */
61 public void addPropertyChangeListener(PropertyChangeListener listener) {
62 propertyChangeSupport.addPropertyChangeListener(listener);
63 }
64
65 /**
66 * see {@link PropertyChangeSupport#addPropertyChangeListener(String, PropertyChangeListener)}
67 */
68 public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
69 propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
70 }
71
72 /**
73 * see {@link PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)}
74 */
75 public void removePropertyChangeListener(PropertyChangeListener listener) {
76 propertyChangeSupport.removePropertyChangeListener(listener);
77 }
78
79 /**
80 * @see PropertyChangeSupport#addPropertyChangeListener(String, PropertyChangeListener)
81 */
82 public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
83 propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
84 }
85
86 @Transient
87 public boolean hasListeners(String propertyName) {
88 return propertyChangeSupport.hasListeners(propertyName);
89 }
90
91 public void firePropertyChange(String property, String oldval, String newval) {
92 propertyChangeSupport.firePropertyChange(property, oldval, newval);
93 }
94 public void firePropertyChange(String property, int oldval, int newval) {
95 propertyChangeSupport.firePropertyChange(property, oldval, newval);
96 }
97 public void firePropertyChange(String property, float oldval, float newval) {
98 propertyChangeSupport.firePropertyChange(property, oldval, newval);
99 }
100 public void firePropertyChange(String property, boolean oldval, boolean newval) {
101 propertyChangeSupport.firePropertyChange(property, oldval, newval);
102 }
103 public void firePropertyChange(String property, Object oldval, Object newval) {
104 propertyChangeSupport.firePropertyChange(property, oldval, newval);
105 }
106 public void firePropertyChange(PropertyChangeEvent evt) {
107 propertyChangeSupport.firePropertyChange(evt);
108 }
109
110 /* (non-Javadoc)
111 * @see eu.etaxonomy.cdm.model.common.ICdmBase#getId()
112 */
113 @Id
114 @GeneratedValue(generator = "system-increment")
115 public int getId() {
116 return this.id;
117 }
118 /* (non-Javadoc)
119 * @see eu.etaxonomy.cdm.model.common.ICdmBase#setId(int)
120 */
121 public void setId(int id) {
122 this.id = id;
123 }
124
125
126 /**
127 * Method for hibernate only to read the UUID value as a simple string from the object and persist it (e.g. in a database).
128 * For reading the UUID please use getUuid method
129 * @return String representation of the UUID
130 */
131 private String getStrUuid() {
132 return this.uuid.toString();
133 }
134 /**
135 * Method for hibernate only to set the UUID value as a simple string as it was stored in the persistence layer (e.g. a database).
136 * For setting the UUID please use setUuid method
137 */
138 private void setStrUuid(String uuid) {
139 this.uuid = UUID.fromString(uuid);
140 }
141
142
143 /* (non-Javadoc)
144 * @see eu.etaxonomy.cdm.model.common.ICdmBase#getUuid()
145 */
146 @Transient
147 public UUID getUuid() {
148 return this.uuid;
149 }
150 /* (non-Javadoc)
151 * @see eu.etaxonomy.cdm.model.common.ICdmBase#setUuid(java.util.UUID)
152 */
153 public void setUuid(UUID uuid) {
154 this.uuid = uuid;
155 }
156
157
158 /* (non-Javadoc)
159 * @see eu.etaxonomy.cdm.model.common.ICdmBase#getCreated()
160 */
161 @Temporal(TemporalType.TIMESTAMP)
162 @Basic(fetch = FetchType.LAZY)
163 public Calendar getCreated() {
164 return created;
165 }
166 /* (non-Javadoc)
167 * @see eu.etaxonomy.cdm.model.common.ICdmBase#setCreated(java.util.Calendar)
168 */
169 public void setCreated(Calendar created) {
170 if (created != null){
171 created.set(Calendar.MILLISECOND, 0);
172 }
173 this.created = created;
174 }
175
176
177 /* (non-Javadoc)
178 * @see eu.etaxonomy.cdm.model.common.ICdmBase#getCreatedBy()
179 */
180 @ManyToOne(fetch=FetchType.LAZY)
181 @Cascade( { CascadeType.SAVE_UPDATE })
182 public Person getCreatedBy() {
183 return this.createdBy;
184 }
185 /* (non-Javadoc)
186 * @see eu.etaxonomy.cdm.model.common.ICdmBase#setCreatedBy(eu.etaxonomy.cdm.model.agent.Person)
187 */
188 public void setCreatedBy(Person createdBy) {
189 this.createdBy = createdBy;
190 }
191
192
193 /**
194 * Is true if UUID is the same for the passed Object and this one.
195 * @see java.lang.Object#equals(java.lang.Object)
196 * See {@link http://www.hibernate.org/109.html hibernate109}, {@link http://www.geocities.com/technofundo/tech/java/equalhash.html geocities}
197 * or {@link http://www.ibm.com/developerworks/java/library/j-jtp05273.html ibm}
198 * for more information about equals and hashcode.
199 */
200 @Override
201 public boolean equals(Object obj) {
202 if (obj == this){
203 return true;
204 }
205 if (obj == null){
206 return false;
207 }
208 if (!CdmBase.class.isAssignableFrom(obj.getClass())){
209 return false;
210 }
211 ICdmBase cdmObj = (ICdmBase)obj;
212 boolean uuidEqual = cdmObj.getUuid().equals(this.getUuid());
213 boolean createdEqual = cdmObj.getCreated().equals(this.getCreated());
214 if (! uuidEqual || !createdEqual){
215 return false;
216 }
217 return true;
218 }
219
220
221 /** Overrides {@link java.lang.Object#hashCode()}
222 * See {@link http://www.hibernate.org/109.html hibernate109}, {@link http://www.geocities.com/technofundo/tech/java/equalhash.html geocities}
223 * or {@link http://www.ibm.com/developerworks/java/library/j-jtp05273.html ibm}
224 * for more information about equals and hashcode.
225 */
226 @Override
227 public int hashCode() {
228 int hashCode = 7;
229 hashCode = 29 * hashCode + this.getUuid().hashCode();
230 return hashCode;
231 }
232
233 /**
234 * Returns the class, id and uuid as a string for any CDM object.
235 * For example: Taxon#13<b5938a98-c1de-4dda-b040-d5cc5bfb3bc0>
236 * @see java.lang.Object#toString()
237 */
238 @Override
239 public String toString() {
240 return this.getClass().getSimpleName()+"#"+this.getId()+"<"+this.getUuid()+">";
241 }
242
243 }