From 76874edfb087f74bc4d0f88397b9a4845f590479 Mon Sep 17 00:00:00 2001
From: "Brian S. O'Neill" <bronee@gmail.com>
Date: Wed, 8 Aug 2007 17:48:10 +0000
Subject: Merged synthetic alternate key support from pojo branch.

---
 .../carbonado/synthetic/SyntheticBuilder.java      | 10 +++-
 .../synthetic/SyntheticStorableBuilder.java        | 65 ++++++++++++++++++----
 .../SyntheticStorableReferenceBuilder.java         | 12 ++++
 3 files changed, 75 insertions(+), 12 deletions(-)

(limited to 'src/main')

diff --git a/src/main/java/com/amazon/carbonado/synthetic/SyntheticBuilder.java b/src/main/java/com/amazon/carbonado/synthetic/SyntheticBuilder.java
index 057825c..fa4efe8 100644
--- a/src/main/java/com/amazon/carbonado/synthetic/SyntheticBuilder.java
+++ b/src/main/java/com/amazon/carbonado/synthetic/SyntheticBuilder.java
@@ -30,6 +30,7 @@ import com.amazon.carbonado.SupportException;
  * returned by {@link #prepare}.
  *
  * @author Don Schneider
+ * @author David Rosenstrauch
  */
 public interface SyntheticBuilder {
 
@@ -84,9 +85,16 @@ public interface SyntheticBuilder {
      */
     public SyntheticKey addPrimaryKey();
 
+    /**
+     * Add an alternate key to be built.
+     * @return key to be decorated with property values defining the alternate key
+     * @since 1.2
+     */
+    public SyntheticKey addAlternateKey();
+
     /**
      * Add an index to the set managed by this builder.  All indexes added this
-     * way will be in addition to the primary key index.
+     * way will be in addition to the primary and alternate key indexes.
      * @return index to be decorated with property values defining the index
      */
     public SyntheticIndex addIndex();
diff --git a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableBuilder.java b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableBuilder.java
index dcbdeb7..98b7dad 100644
--- a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableBuilder.java
+++ b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableBuilder.java
@@ -30,8 +30,10 @@ import org.cojen.classfile.TypeDesc;
 import org.cojen.classfile.attribute.Annotation;
 import org.cojen.util.ClassInjector;
 
+import com.amazon.carbonado.AlternateKeys;
 import com.amazon.carbonado.Index;
 import com.amazon.carbonado.Indexes;
+import com.amazon.carbonado.Key;
 import com.amazon.carbonado.Nullable;
 import com.amazon.carbonado.PrimaryKey;
 import com.amazon.carbonado.Storable;
@@ -52,6 +54,7 @@ import com.amazon.carbonado.util.AnnotationDescParser;
  *
  * @author Don Schneider
  * @author Brian S O'Neill
+ * @author David Rosenstrauch
  */
 public class SyntheticStorableBuilder
         implements SyntheticBuilder {
@@ -118,7 +121,12 @@ public class SyntheticStorableBuilder
     private SyntheticKey mPrimaryKey;
 
     /**
-     * List of indexes (in addition to the primary key) for this storable
+     * List of alternate keys for this storable
+     */
+    private List<SyntheticKey> mAlternateKeys;
+
+    /**
+     * List of indexes (in addition to the primary and alternate keys) for this storable
      */
     private List<SyntheticIndex> mExtraIndexes;
 
@@ -158,6 +166,7 @@ public class SyntheticStorableBuilder
         mName = name;
         mLoader = loader;
         mPropertyList = new ArrayList<SyntheticProperty>();
+        mAlternateKeys = new ArrayList<SyntheticKey>();
         mExtraIndexes = new ArrayList<SyntheticIndex>();
         mClassNameProvider = new DefaultProvider();
     }
@@ -187,6 +196,7 @@ public class SyntheticStorableBuilder
         }
 
         definePrimaryKey(cf);
+        defineAlternateKeys(cf);
         defineIndexes(cf);
 
         return mClassFileGenerator;
@@ -257,6 +267,17 @@ public class SyntheticStorableBuilder
         return mPrimaryKey;
     }
 
+    /*
+     * (non-Javadoc)
+     *
+     * @see com.amazon.carbonado.synthetic.SyntheticBuilder#addAlternateKey()
+     */
+    public SyntheticKey addAlternateKey() {
+        SyntheticKey alternateKey = new SyntheticKey();
+        mAlternateKeys.add(alternateKey);
+        return alternateKey;
+    }
+
     /*
      * (non-Javadoc)
      *
@@ -339,32 +360,52 @@ public class SyntheticStorableBuilder
         }
     }
 
+    /**
+     * Decorate a classfile with the @AlternateKeys for this synthetic storable.
+     *
+     * @param cf ClassFile to decorate
+     */
+    private void defineAlternateKeys(ClassFile cf) {
+        // Add alternate keys annotation
+        //
+        // @AlternateKeys(value={
+        //     @Key(value={"+/-propName", "+/-propName", ...})
+        // })
+        defineIndexes(cf, mAlternateKeys, AlternateKeys.class, Key.class);
+    }
+
     /**
      * Decorate a classfile with the @Indexes for this synthetic storable.
      *
      * @param cf ClassFile to decorate
      */
     private void defineIndexes(ClassFile cf) {
-        if (mExtraIndexes.size() == 0) {
-            return;
-        }
-
         // Add indexes annotation
         //
         // @Indexes(value={
         //     @Index(value={"+/-propName", "+/-propName", ...})
         // })
+        defineIndexes(cf, mExtraIndexes, Indexes.class, Index.class);
+    }
+
+    private void defineIndexes(ClassFile cf,
+                               List<? extends SyntheticPropertyList> definedIndexes,
+                               Class annotationGroupClass,
+                               Class annotationClass) {
+        if (definedIndexes.size() == 0) {
+            return;
+        }
 
-        Annotation indexSet = cf.addRuntimeVisibleAnnotation(TypeDesc.forClass(Indexes.class));
+        Annotation indexSet = cf.addRuntimeVisibleAnnotation(TypeDesc.forClass(annotationGroupClass));
 
-        Annotation.MemberValue[] indexes = new Annotation.MemberValue[mExtraIndexes.size()];
+        Annotation.MemberValue[] indexes = new Annotation.MemberValue[definedIndexes.size()];
 
         // indexSet.value -> indexes
         indexSet.putMemberValue("value", indexes);
 
         int position = 0;
-        for (SyntheticIndex extraIndex : mExtraIndexes) {
-            Annotation index = addIndex(indexSet, indexes, position++);
+        for (SyntheticPropertyList extraIndex : definedIndexes) {
+            Annotation index = addIndex(indexSet, indexes, position++, annotationClass);
 
             Annotation.MemberValue[] indexProps =
                 new Annotation.MemberValue[extraIndex.getPropertyCount()];
@@ -384,16 +425,18 @@ public class SyntheticStorableBuilder
      *            source of annotation (eg, makeAnnotation and makeMemberValue)
      * @param indexes
      * @param position
+     * @param annotationClass TODO
      * @return
      */
     private Annotation addIndex(Annotation annotator,
                                 Annotation.MemberValue[] indexes,
-                                int position)
+                                int position,
+                                Class annotationClass)
     {
         assert (indexes.length > position);
 
         Annotation index = annotator.makeAnnotation();
-        index.setType(TypeDesc.forClass(Index.class));
+        index.setType(TypeDesc.forClass(annotationClass));
         indexes[position] = annotator.makeMemberValue(index);
         return index;
     }
diff --git a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java
index 0832aa9..f9db620 100644
--- a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java
+++ b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java
@@ -65,6 +65,7 @@ import org.cojen.util.BeanComparator;
  *
  * @author Brian S O'Neill
  * @author Don Schneider
+ * @author David Rosenstrauch
  */
 public class SyntheticStorableReferenceBuilder<S extends Storable>
         implements SyntheticBuilder {
@@ -303,6 +304,17 @@ public class SyntheticStorableReferenceBuilder<S extends Storable>
         return mBuilder.addPrimaryKey();
     }
 
+    /*
+     * (non-Javadoc)
+     *
+     * @see com.amazon.carbonado.synthetic.SyntheticBuilder#addAlternateKey() Note that
+     *      using this method for a SyntheticReference being used as an alternate key is
+     *      not well defined.
+     */
+    public SyntheticKey addAlternateKey() {
+        return mBuilder.addAlternateKey();
+    }
+
     /*
      * (non-Javadoc)
      *
-- 
cgit v1.2.3