mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 15:55:55 +00:00
#463 - ENH: Add @DraftReset support - property that is set to null on the draft been when it is published (@Draftable feature)
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks a property on a @Draftable bean that is set to null on the 'draft bean' on publish.
|
||||
* <p>
|
||||
* This is expected to be put on properties that get 'reset' or 'cleared' after a publish.
|
||||
* These properties might represent a publish comment or publish timestamp.
|
||||
* </p>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface DraftReset {
|
||||
|
||||
}
|
||||
@@ -837,6 +837,13 @@ public class BeanDescriptor<T> implements MetaBeanInfo, SpiBeanType<T> {
|
||||
return draftHelp.publish(draftBean, liveBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset properties on the draft bean based on @DraftDirty and @DraftReset.
|
||||
*/
|
||||
public boolean draftReset(T draftBean) {
|
||||
return draftHelp.draftReset(draftBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the draft dirty boolean property or null if there is not one assigned to this bean type.
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.avaje.ebeaninternal.server.deploy;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper for BeanDescriptor that manages draft entity beans.
|
||||
*
|
||||
@@ -12,16 +15,60 @@ public final class BeanDescriptorDraftHelp<T> {
|
||||
|
||||
private final BeanDescriptor<T> desc;
|
||||
|
||||
private final BeanProperty draftDirty;
|
||||
|
||||
private final BeanProperty[] resetProperties;
|
||||
|
||||
public BeanDescriptorDraftHelp(BeanDescriptor<T> desc) {
|
||||
this.desc = desc;
|
||||
this.draftDirty = desc.getDraftDirty();
|
||||
this.resetProperties = resetProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Return the properties that are reset on draft beans after publish.
|
||||
*/
|
||||
public void initialise() {
|
||||
private BeanProperty[] resetProperties() {
|
||||
|
||||
List<BeanProperty> list = new ArrayList<BeanProperty>();
|
||||
|
||||
BeanProperty[] props = desc.propertiesNonMany();
|
||||
for (BeanProperty prop : props) {
|
||||
if (prop.isDraftReset()) {
|
||||
list.add(prop);
|
||||
}
|
||||
}
|
||||
|
||||
return list.toArray(new BeanProperty[list.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of all the 'reset properties' to null on the draft bean.
|
||||
*/
|
||||
public boolean draftReset(T draftBean) {
|
||||
|
||||
EntityBean draftEntityBean = (EntityBean)draftBean;
|
||||
|
||||
if (draftDirty != null) {
|
||||
// set @DraftDirty property to false
|
||||
draftDirty.setValueIntercept(draftEntityBean, false);
|
||||
}
|
||||
|
||||
// set to null on all @DraftReset properties
|
||||
for (BeanProperty resetProperty : resetProperties) {
|
||||
resetProperty.setValueIntercept(draftEntityBean, null);
|
||||
}
|
||||
|
||||
// return true if the bean is dirty (and should be persisted)
|
||||
return draftEntityBean._ebean_getIntercept().isDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer the values from the draftBean to the liveBean.
|
||||
* <p>
|
||||
* This will recursive transfer values to all @DraftableElement properties.
|
||||
* </p>
|
||||
*/
|
||||
public T publish(T draftBean, T liveBean) {
|
||||
|
||||
if (liveBean == null) {
|
||||
|
||||
@@ -227,6 +227,8 @@ public class BeanProperty implements ElPropertyValue {
|
||||
|
||||
final boolean draftDirty;
|
||||
|
||||
final boolean draftReset;
|
||||
|
||||
final boolean indexed;
|
||||
|
||||
final String indexName;
|
||||
@@ -255,6 +257,7 @@ public class BeanProperty implements ElPropertyValue {
|
||||
this.excludedFromHistory = deploy.isExcludedFromHistory();
|
||||
this.draftDirty = deploy.isDraftDirty();
|
||||
this.draftOnly = deploy.isDraftOnly();
|
||||
this.draftReset = deploy.isDraftReset();
|
||||
|
||||
this.secondaryTable = deploy.isSecondaryTable();
|
||||
if (secondaryTable) {
|
||||
@@ -341,6 +344,7 @@ public class BeanProperty implements ElPropertyValue {
|
||||
this.excludedFromHistory = source.excludedFromHistory;
|
||||
this.draftDirty = source.draftDirty;
|
||||
this.draftOnly = source.draftOnly;
|
||||
this.draftReset = source.draftReset;
|
||||
this.fetchEager = source.fetchEager;
|
||||
this.unidirectionalShadow = source.unidirectionalShadow;
|
||||
this.discriminator = source.discriminator;
|
||||
@@ -1045,6 +1049,13 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return draftDirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this property is reset/cleared on publish (on the draft bean).
|
||||
*/
|
||||
public boolean isDraftReset() {
|
||||
return draftReset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this property should be included in an Insert.
|
||||
*/
|
||||
|
||||
@@ -185,6 +185,7 @@ public class DeployBeanProperty {
|
||||
|
||||
private boolean draftOnly;
|
||||
private boolean draftDirty;
|
||||
private boolean draftReset;
|
||||
|
||||
public DeployBeanProperty(DeployBeanDescriptor<?> desc, Class<?> propertyType, ScalarType<?> scalarType, ScalarTypeConverter<?, ?> typeConverter) {
|
||||
this.desc = desc;
|
||||
@@ -854,4 +855,12 @@ public class DeployBeanProperty {
|
||||
public boolean isDraftDirty() {
|
||||
return draftDirty;
|
||||
}
|
||||
|
||||
public void setDraftReset() {
|
||||
this.draftReset = true;
|
||||
}
|
||||
|
||||
public boolean isDraftReset() {
|
||||
return draftReset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,10 +152,12 @@ public class AnnotationFields extends AnnotationParser {
|
||||
if (get(prop, DraftOnly.class) != null) {
|
||||
prop.setDraftOnly();
|
||||
}
|
||||
|
||||
if (get(prop, DraftDirty.class) != null) {
|
||||
prop.setDraftDirty();
|
||||
}
|
||||
if (get(prop, DraftReset.class) != null) {
|
||||
prop.setDraftReset();
|
||||
}
|
||||
|
||||
DbJson dbJson = get(prop, DbJson.class);
|
||||
if (dbJson != null) {
|
||||
|
||||
@@ -159,10 +159,7 @@ public final class DefaultPersister implements Persister {
|
||||
|
||||
BeanManager<T> mgr = beanDescriptorManager.getBeanManager(beanType);
|
||||
|
||||
// collect a list of draft beans that have had their
|
||||
// dirty status set back to false by the publish
|
||||
List<T> draftUpdates = new ArrayList<T>();
|
||||
BeanProperty draftDirty = desc.getDraftDirty();
|
||||
DraftHandler draftHandler = new DraftHandler(desc);
|
||||
|
||||
for (T draftBean: draftBeans) {
|
||||
Object draftID = desc.getBeanId(draftBean);
|
||||
@@ -181,34 +178,52 @@ public final class DefaultPersister implements Persister {
|
||||
update(request);
|
||||
}
|
||||
|
||||
unsetDraftDirtyProperty(draftUpdates, draftDirty, draftBean);
|
||||
draftHandler.resetDraft(draftBean);
|
||||
}
|
||||
|
||||
if (!draftUpdates.isEmpty()) {
|
||||
// update the dirty status on the drafts that have been published
|
||||
PUB.debug("publish - update dirty status on [{}] drafts", draftUpdates.size());
|
||||
for (T draftUpdate : draftUpdates) {
|
||||
update(createRequest(draftUpdate, transaction, null, mgr, Type.UPDATE, false, false));
|
||||
}
|
||||
}
|
||||
draftHandler.updateDrafts(transaction, mgr);
|
||||
|
||||
PUB.debug("publish - complete for [{}]", desc.getName());
|
||||
|
||||
return livePublish;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the draft dirty state to false and add to the draftUpdates list.
|
||||
* Helper to handle draft beans (properties reset etc).
|
||||
*/
|
||||
private <T> void unsetDraftDirtyProperty(List<T> draftUpdates, BeanProperty draftDirty, T draftBean) {
|
||||
class DraftHandler<T> {
|
||||
|
||||
if (draftDirty != null) {
|
||||
EntityBean draftEntityBean = (EntityBean)draftBean;
|
||||
draftDirty.setValueIntercept(draftEntityBean, false);
|
||||
if (draftEntityBean._ebean_getIntercept().isDirty()) {
|
||||
final BeanDescriptor<T> desc;
|
||||
final BeanProperty draftDirty;
|
||||
final List<T> draftUpdates = new ArrayList<T>();
|
||||
|
||||
DraftHandler(BeanDescriptor<T> desc) {
|
||||
this.desc = desc;
|
||||
this.draftDirty = desc.getDraftDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the draft dirty state to false and reset any dirtyReset properties.
|
||||
*/
|
||||
void resetDraft(T draftBean) {
|
||||
if (desc.draftReset(draftBean)) {
|
||||
// draft bean is dirty so collect it for persisting later
|
||||
draftUpdates.add(draftBean);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all the draft beans (with various properties reset etc).
|
||||
*/
|
||||
void updateDrafts(Transaction transaction, BeanManager<T> mgr) {
|
||||
if (!draftUpdates.isEmpty()) {
|
||||
// update the dirty status on the drafts that have been published
|
||||
PUB.debug("publish - update dirty status on [{}] drafts", draftUpdates.size());
|
||||
for (T draftUpdate : draftUpdates) {
|
||||
update(createRequest(draftUpdate, transaction, null, mgr, Type.UPDATE, false, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user