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();