X-Git-Url: https://dev.e-taxonomy.eu/gitweb/cdmlib.git/blobdiff_plain/d5fe74bec9d17549a4a8cc65c474c511a3c8497c..58136b31ffc20c3f283b8d73bd14b09e0a3d3e7f:/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/CdmBase.java
diff --git a/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/CdmBase.java b/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/CdmBase.java
index 1d4d31531a..0ffa01ec8d 100644
--- a/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/CdmBase.java
+++ b/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/CdmBase.java
@@ -13,6 +13,8 @@ import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
import java.util.UUID;
import javax.persistence.Basic;
@@ -37,9 +39,10 @@ import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.apache.log4j.Logger;
-import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.Type;
+import org.hibernate.envers.Audited;
+import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.FieldBridge;
@@ -49,10 +52,11 @@ import org.joda.time.DateTime;
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
import eu.etaxonomy.cdm.hibernate.search.DateTimeBridge;
-import eu.etaxonomy.cdm.hibernate.search.PaddedIntegerBridge;
+import eu.etaxonomy.cdm.hibernate.search.NotNullAwareIdBridge;
import eu.etaxonomy.cdm.hibernate.search.UuidBridge;
import eu.etaxonomy.cdm.jaxb.DateTimeAdapter;
import eu.etaxonomy.cdm.jaxb.UUIDAdapter;
+import eu.etaxonomy.cdm.model.NewEntityListener;
import eu.etaxonomy.cdm.strategy.match.Match;
import eu.etaxonomy.cdm.strategy.match.MatchMode;
@@ -78,7 +82,7 @@ import eu.etaxonomy.cdm.strategy.match.MatchMode;
"createdBy"
})
@MappedSuperclass
-public abstract class CdmBase implements Serializable, ICdmBase, Cloneable{
+public abstract class CdmBase implements Serializable, ICdmBase, ISelfDescriptive, Cloneable{
private static final long serialVersionUID = -3053225700018294809L;
@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(CdmBase.class);
@@ -87,29 +91,37 @@ public abstract class CdmBase implements Serializable, ICdmBase, Cloneable{
@XmlTransient
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
+ @Transient
+ @XmlTransient
+ private static NewEntityListener newEntityListener;
+
//@XmlAttribute(name = "id", required = true)
@XmlTransient
@Id
-// @GeneratedValue(generator = "system-increment")
+// @GeneratedValue(generator = "system-increment") //see also AuditEvent.revisionNumber
// @GeneratedValue(generator = "enhanced-table")
@GeneratedValue(generator = "custom-enhanced-table")
@DocumentId
- @FieldBridge(impl=PaddedIntegerBridge.class)
+ @FieldBridge(impl=NotNullAwareIdBridge.class)
+ //commented since Hibernate Search 5.5.x since HSEARCH000247 is thrown otherwise
+// @Field(store=Store.YES, termVector=TermVector.NO)
@Match(MatchMode.IGNORE)
@NotNull
@Min(0)
+ @Audited
private int id;
@XmlAttribute(required = true)
@XmlJavaTypeAdapter(UUIDAdapter.class)
+ @XmlID
@Type(type="uuidUserType")
@NaturalId // This has the effect of placing a "unique" constraint on the database column
- @XmlID
- @Column(length=36)
+ @Column(length=36) //TODO needed? Type UUID will always assure that is exactly 36
@Match(MatchMode.IGNORE)
@NotNull
- @Field(store = Store.YES, index = Index.UN_TOKENIZED)
+ @Field(store = Store.YES, index = Index.YES, analyze = Analyze.NO)
@FieldBridge(impl = UuidBridge.class)
+ @Audited
protected UUID uuid;
@XmlElement (name = "Created", type= String.class)
@@ -117,8 +129,9 @@ public abstract class CdmBase implements Serializable, ICdmBase, Cloneable{
@Type(type="dateTimeUserType")
@Basic(fetch = FetchType.LAZY)
@Match(MatchMode.IGNORE)
- @Field(index = Index.UN_TOKENIZED)
+ @Field(analyze = Analyze.NO)
@FieldBridge(impl = DateTimeBridge.class)
+ @Audited
private DateTime created;
@XmlElement (name = "CreatedBy")
@@ -126,6 +139,7 @@ public abstract class CdmBase implements Serializable, ICdmBase, Cloneable{
@XmlSchemaType(name = "IDREF")
@ManyToOne(fetch=FetchType.LAZY)
@Match(MatchMode.IGNORE)
+ @Audited
private User createdBy;
/**
@@ -137,6 +151,16 @@ public abstract class CdmBase implements Serializable, ICdmBase, Cloneable{
this.created = new DateTime().withMillisOfSecond(0);
}
+ public static void setNewEntityListener(NewEntityListener nel) {
+ newEntityListener = nel;
+ }
+
+ public static void fireOnCreateEvent(CdmBase cdmBase) {
+ if(newEntityListener != null) {
+ newEntityListener.onCreate(cdmBase);
+ }
+ }
+
/**
* see {@link PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)}
* @param listener
@@ -189,44 +213,68 @@ public abstract class CdmBase implements Serializable, ICdmBase, Cloneable{
propertyChangeSupport.firePropertyChange(evt);
}
- /* (non-Javadoc)
- * @see eu.etaxonomy.cdm.model.common.ICdmBase#getUuid()
+ /**
+ * This method was initially added to {@link CdmBase} to fix #5161.
+ * It can be overridden by subclasses such as {@link IdentifiableEntity}
+ * to explicitly initialize listeners. This is needed e.g. after de-serialization
+ * as listeners are not serialized due to the @Transient annotation.
+ * However, it can be generally used for other use-cases as well
+ */
+ public void initListener() {}
+
+ /**
+ * Adds an item to a set of this
object and fires the according
+ * {@link PropertyChangeEvent}. Workaround as long as add and remove is not yet
+ * implemented in aspectJ.
+ * @param set the set the new item is added to
+ * @param newItem the new item to be added to the set
+ * @param propertyName the name of the set as property in this
object
+ */
+ protected void addToSetWithChangeEvent(Set set, T newItem, String propertyName ){
+ Set oldValue = new HashSet(set);
+ set.add(newItem);
+ firePropertyChange(new PropertyChangeEvent(this, propertyName, oldValue, set));
+ }
+
+ /**
+ * Removes an item from a set of this
object and fires the according
+ * {@link PropertyChangeEvent}. Workaround as long as add and remove is not yet
+ * implemented in aspectJ.
+ * @param set the set the item is to be removed from
+ * @param itemToRemove the item to be removed from the set
+ * @param propertyName the name of the set as property in this
object
*/
+ protected void removeFromSetWithChangeEvent(Set set, T itemToRemove, String propertyName ){
+ Set oldValue = new HashSet(set);
+ set.remove(itemToRemove);
+ firePropertyChange(new PropertyChangeEvent(this, propertyName, oldValue, set));
+ }
+
+ @Override
public UUID getUuid() {
return uuid;
}
- /* (non-Javadoc)
- * @see eu.etaxonomy.cdm.model.common.ICdmBase#setUuid(java.util.UUID)
- */
+ @Override
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
- /* (non-Javadoc)
- * @see eu.etaxonomy.cdm.model.common.ICdmBase#getId()
- */
+ @Override
public int getId() {
return this.id;
}
- /* (non-Javadoc)
- * @see eu.etaxonomy.cdm.model.common.ICdmBase#setId(int)
- */
- public void setId(int id) {
+ @Override
+ public void setId(int id) { //see #265 (private ?)
this.id = id;
}
- /* (non-Javadoc)
- * @see eu.etaxonomy.cdm.model.common.ICdmBase#getCreated()
- */
+ @Override
public DateTime getCreated() {
return created;
}
- /* (non-Javadoc)
- * @see eu.etaxonomy.cdm.model.common.ICdmBase#setCreated(java.util.Calendar)
- */
+ @Override
public void setCreated(DateTime created) {
if (created != null){
- new DateTime();
created = created.withMillisOfSecond(0);
//created.set(Calendar.MILLISECOND, 0); //old, can be deleted
}
@@ -234,15 +282,11 @@ public abstract class CdmBase implements Serializable, ICdmBase, Cloneable{
}
- /* (non-Javadoc)
- * @see eu.etaxonomy.cdm.model.common.ICdmBase#getCreatedBy()
- */
+ @Override
public User getCreatedBy() {
return this.createdBy;
}
- /* (non-Javadoc)
- * @see eu.etaxonomy.cdm.model.common.ICdmBase#setCreatedBy(eu.etaxonomy.cdm.model.agent.Person)
- */
+ @Override
public void setCreatedBy(User createdBy) {
this.createdBy = createdBy;
}
@@ -376,21 +420,35 @@ public abstract class CdmBase implements Serializable, ICdmBase, Cloneable{
}
}
+ @Transient
+ @Override
+ public String getUserFriendlyTypeName(){
+ return getClass().getSimpleName();
+ }
+
+ @Transient
+ @Override
+ public String getUserFriendlyDescription(){
+ return toString();
+ }
+
+ @Override
+ public String getUserFriendlyFieldName(String field){
+ return field;
+ }
+
//********************** CLONE *****************************************/
- protected void clone(CdmBase clone){
- clone.setCreatedBy(createdBy);
- clone.setId(id);
- clone.propertyChangeSupport=new PropertyChangeSupport(clone);
- //Constructor Attributes
- //clone.setCreated(created);
- //clone.setUuid(getUuid());
+// protected void clone(CdmBase clone){
+// clone.setCreatedBy(createdBy);
+// clone.setId(id);
+// clone.propertyChangeSupport=new PropertyChangeSupport(clone);
+// //Constructor Attributes
+// //clone.setCreated(created);
+// //clone.setUuid(getUuid());
+//
+// }
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#clone()
- */
@Override
public Object clone() throws CloneNotSupportedException{
CdmBase result = (CdmBase)super.clone();