From ff8e5af4e5a4c3f9aa8d7d3c50fbd18893e6a824 Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Mon, 7 Dec 2015 11:11:22 +1300 Subject: [PATCH] #481 - ENH: @Draftable ... add support for transient @Draft boolean draft; property ... used to distinguish a 'live' instance from a 'draft' instance. --- .../com/avaje/ebean/annotation/Draft.java | 19 +++++++++++++++++++ .../server/deploy/BeanDescriptor.java | 13 +++++++++++++ .../server/deploy/BeanProperty.java | 12 ++++++++++++ .../deploy/meta/DeployBeanProperty.java | 11 +++++++++++ .../deploy/meta/DeployBeanPropertyLists.java | 9 +++++++++ .../server/deploy/parse/AnnotationFields.java | 3 +++ .../server/query/SqlTreeNodeBean.java | 3 +++ 7 files changed, 70 insertions(+) create mode 100644 src/main/java/com/avaje/ebean/annotation/Draft.java diff --git a/src/main/java/com/avaje/ebean/annotation/Draft.java b/src/main/java/com/avaje/ebean/annotation/Draft.java new file mode 100644 index 000000000..26f7c3398 --- /dev/null +++ b/src/main/java/com/avaje/ebean/annotation/Draft.java @@ -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 boolean property on a @Draftable bean that indicates if the bean instance is a 'draft' or 'live' bean. + * The property is transient and has no underlying DB column. + *

+ * For beans returned from an asDraft() query this property will be set to true. + *

+ */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Draft { + +} diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java index 991ad293c..df81a623a 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java @@ -163,6 +163,8 @@ public class BeanDescriptor implements MetaBeanInfo, SpiBeanType { private final boolean draftableElement; + private final BeanProperty draft; + private final BeanProperty draftDirty; /** @@ -403,6 +405,7 @@ public class BeanDescriptor implements MetaBeanInfo, SpiBeanType { this.softDelete = (softDeleteProperty != null); this.idProperty = listHelper.getId(); this.versionProperty = listHelper.getVersionProperty(); + this.draft = listHelper.getDraft(); this.draftDirty = listHelper.getDraftDirty(); this.propMap = listHelper.getPropertyMap(); this.propertiesTransient = listHelper.getTransients(); @@ -1989,6 +1992,16 @@ public class BeanDescriptor implements MetaBeanInfo, SpiBeanType { return draftableElement; } + /** + * Set the draft to true for this entity bean instance. + * This bean is being loaded via asDraft() query. + */ + public void setDraft(EntityBean entityBean) { + if (draft != null) { + draft.setValue(entityBean, true); + } + } + /** * If there is a @DraftDirty property set it's value on the bean. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java index 0f2e02d52..bb0911b11 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java @@ -224,6 +224,8 @@ public class BeanProperty implements ElPropertyValue { final boolean jsonDeserialize; + final boolean draft; + final boolean draftOnly; final boolean draftDirty; @@ -262,6 +264,7 @@ public class BeanProperty implements ElPropertyValue { this.dbInsertable = deploy.isDbInsertable(); this.dbUpdatable = deploy.isDbUpdateable(); this.excludedFromHistory = deploy.isExcludedFromHistory(); + this.draft = deploy.isDraft(); this.draftDirty = deploy.isDraftDirty(); this.draftOnly = deploy.isDraftOnly(); this.draftReset = deploy.isDraftReset(); @@ -358,6 +361,7 @@ public class BeanProperty implements ElPropertyValue { this.formula = false; this.excludedFromHistory = source.excludedFromHistory; + this.draft = source.draft; this.draftDirty = source.draftDirty; this.draftOnly = source.draftOnly; this.draftReset = source.draftReset; @@ -1083,6 +1087,14 @@ public class BeanProperty implements ElPropertyValue { return draftOnly; } + /** + * Return true if this property is a boolean flag on a draftable bean + * indicating if the instance is a draft or live bean. + */ + public boolean isDraft() { + return draft; + } + /** * Return true if this property is a boolean flag only on the draft table * indicating that when the draft is different from the published row. diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanProperty.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanProperty.java index 30858aac0..9ef22652e 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanProperty.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanProperty.java @@ -186,6 +186,7 @@ public class DeployBeanProperty { private boolean excludedFromHistory; + private boolean draft; private boolean draftOnly; private boolean draftDirty; private boolean draftReset; @@ -657,6 +658,7 @@ public class DeployBeanProperty { return false; } } + /** * Return true if this property is based on a secondary table. */ @@ -853,6 +855,15 @@ public class DeployBeanProperty { this.excludedFromHistory = true; } + public void setDraft() { + this.draft = true; + this.isTransient = true; + } + + public boolean isDraft() { + return draft; + } + public void setDraftOnly() { this.draftOnly = true; } diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java index 700fe851f..697f13dcd 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java @@ -28,6 +28,8 @@ public class DeployBeanPropertyLists { private BeanProperty versionProperty; + private BeanProperty draft; + private BeanProperty draftDirty; private final BeanDescriptor desc; @@ -136,6 +138,9 @@ public class DeployBeanPropertyLists { private void allocateToList(BeanProperty prop) { if (prop.isTransient()) { transients.add(prop); + if (prop.isDraft()) { + draft = prop; + } return; } if (prop.isId()) { @@ -293,6 +298,10 @@ public class DeployBeanPropertyLists { return draftDirty; } + public BeanProperty getDraft() { + return draft; + } + public BeanProperty getSoftDeleteProperty() { for (BeanProperty prop: nonManys) { diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java index fde8d0041..d6dcc65a8 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java @@ -149,6 +149,9 @@ public class AnnotationFields extends AnnotationParser { util.setLobType(prop); } + if (get(prop, Draft.class) != null) { + prop.setDraft(); + } if (get(prop, DraftOnly.class) != null) { prop.setDraftOnly(); } diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java index a0a20e710..b64dacb58 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -301,6 +301,9 @@ public class SqlTreeNodeBean implements SqlTreeNode { if (readId && !temporalVersions) { createListProxies(localDesc, ctx, localBean); } + if (temporalMode == SpiQuery.TemporalMode.DRAFT) { + localDesc.setDraft(localBean); + } localDesc.postLoad(localBean); EntityBeanIntercept ebi = localBean._ebean_getIntercept();