diff options
Diffstat (limited to 'src')
5 files changed, 111 insertions, 5 deletions
diff --git a/src/main/java/com/amazon/carbonado/Storable.java b/src/main/java/com/amazon/carbonado/Storable.java index d6f0c1c..40372c4 100644 --- a/src/main/java/com/amazon/carbonado/Storable.java +++ b/src/main/java/com/amazon/carbonado/Storable.java @@ -435,6 +435,14 @@ public interface Storable<S extends Storable<S>> {      S copy();
      /**
 +     * Prepares a new object for loading, inserting, updating, or deleting.
 +     *
 +     * @see Storage#prepare
 +     * @since 1.2
 +     */
 +    S prepare();
 +
 +    /**
       * Serializes property values and states for temporary storage or for
       * network transfer. Call {@link #readFrom} to restore. Derived and join
       * properties are not serialized.
 diff --git a/src/main/java/com/amazon/carbonado/gen/CodeBuilderUtil.java b/src/main/java/com/amazon/carbonado/gen/CodeBuilderUtil.java index 1f01872..a99ea56 100644 --- a/src/main/java/com/amazon/carbonado/gen/CodeBuilderUtil.java +++ b/src/main/java/com/amazon/carbonado/gen/CodeBuilderUtil.java @@ -125,8 +125,8 @@ public class CodeBuilderUtil {      }
      /**
 -     * Add copy bridge methods for all classes/interfaces between the leaf (genericised class)
 -     * and the root (genericised baseclass).
 +     * Add copy bridge methods for all classes/interfaces between the leaf
 +     * (genericised class) and the root (genericised baseclass).
       *
       * @param cf file to which to add the copy bridge
       * @param leaf leaf class
 @@ -140,9 +140,9 @@ public class CodeBuilderUtil {      }
      /**
 -     * Add a copy bridge method to the classfile for the given type.  This is needed to allow
 -     * the genericised class make a copy itself -- which will be erased to the base type -- and
 -     * return it as the correct type.
 +     * Add a copy bridge method to the classfile for the given type.  This is
 +     * needed to allow the genericised class make a copy itself -- which will
 +     * be erased to the base type -- and return it as the correct type.
       *
       * @param cf file to which to add the copy bridge
       * @param leaf leaf class
 @@ -165,6 +165,98 @@ public class CodeBuilderUtil {      }
      /**
 +     * Defines a Storable prepare method, which assumes that a support field
 +     * exists and a single-argument constructor exists which accepts a support
 +     * instance.
 +     *
 +     * @param cf file to which to add the prepare method
 +     * @since 1.2
 +     */
 +    public static void definePrepareMethod(ClassFile cf,
 +                                           Class storableClass,
 +                                           TypeDesc supportCtorType)
 +    {
 +        definePrepareMethod(cf, storableClass, supportCtorType,
 +                            StorableGenerator.SUPPORT_FIELD_NAME,
 +                            TypeDesc.forClass(TriggerSupport.class));
 +    }
 +
 +    /**
 +     * Defines a Storable prepare method, which assumes that a support field
 +     * exists and a single-argument constructor exists which accepts a support
 +     * instance.
 +     *
 +     * @param cf file to which to add the prepare method
 +     * @since 1.2
 +     */
 +    public static void definePrepareMethod(ClassFile cf,
 +                                           Class storableClass,
 +                                           TypeDesc supportCtorType,
 +                                           String supportFieldName,
 +                                           TypeDesc supportFieldType)
 +    {
 +        TypeDesc storableType = TypeDesc.forClass(storableClass);
 +
 +        if (!isPublicMethodFinal(storableClass, PREPARE_METHOD_NAME, storableType, null)) {
 +            MethodInfo mi = cf.addMethod
 +                (Modifiers.PUBLIC, PREPARE_METHOD_NAME, cf.getType(), null);
 +
 +            CodeBuilder b = new CodeBuilder(mi);
 +            b.newObject(cf.getType());
 +            b.dup();
 +            b.loadThis();
 +            b.loadField(supportFieldName, supportFieldType);
 +            if (supportFieldType != supportCtorType) {
 +                b.checkCast(supportCtorType);
 +            }
 +            b.invokeConstructor(new TypeDesc[] {supportCtorType});
 +            b.returnValue(cf.getType());
 +        }
 +
 +        definePrepareBridges(cf, storableClass);
 +    }
 +
 +    /**
 +     * Add prepare bridge methods for all classes/interfaces between the leaf
 +     * (genericised class) and the root (genericised baseclass).
 +     *
 +     * @param cf file to which to add the prepare bridge
 +     * @param leaf leaf class
 +     * @since 1.2
 +     */
 +    public static void definePrepareBridges(ClassFile cf, Class leaf) {
 +        for (Class c : gatherAllBridgeTypes(new HashSet<Class>(), leaf)) {
 +            if (c != Object.class) {
 +                definePrepareBridge(cf, leaf, c);
 +            }
 +        }
 +    }
 +
 +    /**
 +     * Add a prepare bridge method to the classfile for the given type.
 +     *
 +     * @param cf file to which to add the prepare bridge
 +     * @param leaf leaf class
 +     * @param returnClass type returned from generated bridge method
 +     * @since 1.2
 +     */
 +    private static void definePrepareBridge(ClassFile cf, Class leaf, Class returnClass) {
 +        TypeDesc returnType = TypeDesc.forClass(returnClass);
 +
 +        if (isPublicMethodFinal(leaf, PREPARE_METHOD_NAME, returnType, null)) {
 +            // Cannot override.
 +            return;
 +        }
 +
 +        MethodInfo mi = cf.addMethod(Modifiers.PUBLIC.toBridge(true),
 +                                     PREPARE_METHOD_NAME, returnType, null);
 +        CodeBuilder b = new CodeBuilder(mi);
 +        b.loadThis();
 +        b.invokeVirtual(PREPARE_METHOD_NAME, cf.getType(), null);
 +        b.returnValue(returnType);
 +    }
 +
 +    /**
       * Returns true if a public final method exists which matches the given
       * specification.
       */
 diff --git a/src/main/java/com/amazon/carbonado/gen/DelegateStorableGenerator.java b/src/main/java/com/amazon/carbonado/gen/DelegateStorableGenerator.java index 4de28bd..38b612c 100644 --- a/src/main/java/com/amazon/carbonado/gen/DelegateStorableGenerator.java +++ b/src/main/java/com/amazon/carbonado/gen/DelegateStorableGenerator.java @@ -113,6 +113,8 @@ public class DelegateStorableGenerator<S extends Storable> {              b.returnVoid();
          }
 +        CodeBuilderUtil.definePrepareMethod(mClassFile, mStorableType, delegateSupportType);
 +
          // Implement abstract methods which all delegate to DelegateSupport instance.
          generateDelegatedMethod
 diff --git a/src/main/java/com/amazon/carbonado/raw/GenericStorableCodec.java b/src/main/java/com/amazon/carbonado/raw/GenericStorableCodec.java index 6a5d89d..dd43515 100644 --- a/src/main/java/com/amazon/carbonado/raw/GenericStorableCodec.java +++ b/src/main/java/com/amazon/carbonado/raw/GenericStorableCodec.java @@ -182,6 +182,8 @@ public class GenericStorableCodec<S extends Storable> implements StorableCodec<S              b.returnVoid();
          }
 +        CodeBuilderUtil.definePrepareMethod(cf, storableClass, rawSupportType);
 +
          // Implement protected abstract methods inherited from parent class.
          // byte[] encodeKey()
 diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java index d136206..1abe8d8 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java @@ -248,6 +248,8 @@ class JDBCStorableGenerator<S extends Storable> {              b.returnVoid();
          }
 +        CodeBuilderUtil.definePrepareMethod(mClassFile, mStorableType, jdbcSupportType);
 +
          // Add private method to extract all properties from a ResultSet row.
          defineExtractAllMethod(lobLoaderMap);
          // Add private method to extract non-pk properties from a ResultSet row.
  | 
