From 5403ce66194832e9887cc0d0222ff449464e041f Mon Sep 17 00:00:00 2001
From: "Brian S. O'Neill" <bronee@gmail.com>
Date: Fri, 18 Apr 2008 20:23:47 +0000
Subject: Support renamed properties in indexes and keys.

---
 .../com/amazon/carbonado/cursor/SortedCursor.java  | 69 +++++++++++++++++-----
 .../com/amazon/carbonado/info/ChainedProperty.java |  5 +-
 .../carbonado/info/StorableIntrospector.java       | 12 +++-
 .../amazon/carbonado/info/StorableProperty.java    | 11 +++-
 .../repo/jdbc/JDBCStorableIntrospector.java        |  4 ++
 .../synthetic/SyntheticStorableBuilder.java        |  8 +++
 6 files changed, 85 insertions(+), 24 deletions(-)

(limited to 'src')

diff --git a/src/main/java/com/amazon/carbonado/cursor/SortedCursor.java b/src/main/java/com/amazon/carbonado/cursor/SortedCursor.java
index 3c26caa..2a05493 100644
--- a/src/main/java/com/amazon/carbonado/cursor/SortedCursor.java
+++ b/src/main/java/com/amazon/carbonado/cursor/SortedCursor.java
@@ -36,8 +36,11 @@ import com.amazon.carbonado.FetchInterruptedException;
 import com.amazon.carbonado.Cursor;
 import com.amazon.carbonado.Storable;
 
+import com.amazon.carbonado.info.ChainedProperty;
 import com.amazon.carbonado.info.Direction;
 import com.amazon.carbonado.info.OrderedProperty;
+import com.amazon.carbonado.info.StorableInfo;
+import com.amazon.carbonado.info.StorableIntrospector;
 
 /**
  * Wraps another Cursor and ensures the results are sorted. If the elements in
@@ -62,17 +65,26 @@ public class SortedCursor<S> extends AbstractCursor<S> {
      */
     public static <S> Comparator<S> createComparator(Class<S> type, String... orderProperties) {
         BeanComparator bc = BeanComparator.forClass(type);
-        for (String property : orderProperties) {
-            Class propertyType;
-            {
-                String name = property;
-                if (name.startsWith("+") || name.startsWith("-")) {
-                    name = name.substring(1);
+
+        if (Storable.class.isAssignableFrom(type)) {
+            StorableInfo info = StorableIntrospector.examine((Class) type);
+            for (String property : orderProperties) {
+                bc = orderBy(bc, OrderedProperty.parse(info, property));
+            }
+        } else {
+            for (String property : orderProperties) {
+                Class propertyType;
+                {
+                    String name = property;
+                    if (name.startsWith("+") || name.startsWith("-")) {
+                        name = name.substring(1);
+                    }
+                    propertyType = propertyType(type, name);
                 }
-                propertyType = propertyType(type, name);
+                bc = orderBy(bc, property, propertyType, Direction.ASCENDING);
             }
-            bc = orderBy(bc, property, propertyType, Direction.ASCENDING);
         }
+
         return bc;
     }
 
@@ -117,8 +129,7 @@ public class SortedCursor<S> extends AbstractCursor<S> {
             if (property == null) {
                 throw new IllegalArgumentException();
             }
-            bc = orderBy(bc, property.getChainedProperty().toString(),
-                         property.getChainedProperty().getType(), property.getDirection());
+            bc = orderBy(bc, property);
         }
 
         return bc;
@@ -148,15 +159,21 @@ public class SortedCursor<S> extends AbstractCursor<S> {
             if (property == null) {
                 throw new IllegalArgumentException();
             }
-            bc = orderBy(bc, property.getChainedProperty().toString(),
-                         property.getChainedProperty().getType(), property.getDirection());
+            bc = orderBy(bc, property);
         }
 
         return bc;
     }
 
-    private static BeanComparator orderBy(BeanComparator bc, String property,
-                                          Class type, Direction direction)
+    private static BeanComparator orderBy(BeanComparator bc, OrderedProperty property) {
+        ChainedProperty chained = property.getChainedProperty();
+        return orderBy(bc, chainToBeanString(chained), chained.getType(), property.getDirection());
+    }
+
+    private static BeanComparator orderBy(BeanComparator bc,
+                                          String property,
+                                          Class type,
+                                          Direction direction)
     {
         bc = bc.orderBy(property);
 
@@ -165,11 +182,12 @@ public class SortedCursor<S> extends AbstractCursor<S> {
             if (td.getRootComponentType() == TypeDesc.BYTE) {
                 bc = bc.using(Comparators.arrayComparator(type, true));
             } else {
-                bc = bc.using(Comparators.arrayComparator(type, false));
-                if (bc == null) {
+                Comparator c = Comparators.arrayComparator(type, false);
+                if (c == null) {
                     throw new IllegalArgumentException("Cannot sort by property type of " +
                                                        type.getName() + " for " + property);
                 }
+                bc = bc.using(c);
             }
         } else {
             bc = bc.caseSensitive();
@@ -182,6 +200,25 @@ public class SortedCursor<S> extends AbstractCursor<S> {
         return bc;
     }
 
+    /**
+     * Creates a dotted name string using the bean property names.
+     */
+    private static String chainToBeanString(ChainedProperty property) {
+        int count = property.getChainCount();
+        if (count <= 0) {
+            return property.getPrimeProperty().getBeanName();
+        }
+
+        StringBuilder b = new StringBuilder();
+        b.append(property.getPrimeProperty().getBeanName());
+        for (int i=0; i<count; i++) {
+            b.append('.');
+            b.append(property.getChainedProperty(i).getBeanName());
+        }
+
+        return b.toString();
+    }
+
     /** Wrapped cursor */
     private final Cursor<S> mCursor;
     /** Buffer to store and sort results */
diff --git a/src/main/java/com/amazon/carbonado/info/ChainedProperty.java b/src/main/java/com/amazon/carbonado/info/ChainedProperty.java
index 65151e8..24a30cf 100644
--- a/src/main/java/com/amazon/carbonado/info/ChainedProperty.java
+++ b/src/main/java/com/amazon/carbonado/info/ChainedProperty.java
@@ -562,11 +562,8 @@ public class ChainedProperty<S extends Storable> implements Serializable, Append
         appendPropTo(app, mPrime.getName(), isOuterJoin(0));
         StorableProperty<?>[] chain = mChain;
         if (chain != null) {
-            app.append('.');
             for (int i=0; i<chain.length; i++) {
-                if (i > 0) {
-                    app.append('.');
-                }
+                app.append('.');
                 appendPropTo(app, chain[i].getName(), isOuterJoin(i + 1));
             }
         }
diff --git a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java
index fdfb51f..94b391e 100644
--- a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java
+++ b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java
@@ -624,7 +624,7 @@ public class StorableIntrospector {
                 String sig = createSig(readMethod);
                 if (storableProp.isDerived() || methods.containsKey(sig)) {
                     methods.remove(sig);
-                    properties.put(property.getName(), storableProp);
+                    properties.put(storableProp.getName(), storableProp);
                 } else {
                     continue;
                 }
@@ -634,7 +634,7 @@ public class StorableIntrospector {
                 String sig = createSig(writeMethod);
                 if (storableProp.isDerived() || methods.containsKey(sig)) {
                     methods.remove(sig);
-                    properties.put(property.getName(), storableProp);
+                    properties.put(storableProp.getName(), storableProp);
                 } else {
                     continue;
                 }
@@ -1594,6 +1594,7 @@ public class StorableIntrospector {
         private final boolean mAutomatic;
         private final boolean mIsDerived;
         private final String mName;
+        private final String mBeanName;
 
         // Temporary reference until derived from is resolved.
         private Derived mDerived;
@@ -1635,13 +1636,18 @@ public class StorableIntrospector {
             mAutomatic = automatic;
             mIsDerived = derived != null;
             mDerived = derived;
-            mName = name == null ? mBeanProperty.getName() : name;
+            mBeanName = mBeanProperty.getName();
+            mName = name == null ? mBeanName : name;
         }
 
         public final String getName() {
             return mName;
         }
 
+        public final String getBeanName() {
+            return mBeanName;
+        }
+
         public final Class<?> getType() {
             return mBeanProperty.getType();
         }
diff --git a/src/main/java/com/amazon/carbonado/info/StorableProperty.java b/src/main/java/com/amazon/carbonado/info/StorableProperty.java
index 0d77481..38418ec 100644
--- a/src/main/java/com/amazon/carbonado/info/StorableProperty.java
+++ b/src/main/java/com/amazon/carbonado/info/StorableProperty.java
@@ -31,10 +31,19 @@ import com.amazon.carbonado.util.Appender;
  */
 public interface StorableProperty<S extends Storable> extends Serializable, Appender {
     /**
-     * Returns the name of this property.
+     * Returns the name of this property, which is the same as the bean name
+     * unless it has been {@link com.amazon.carbonado.Name renamed}.
      */
     String getName();
 
+    /**
+     * Returns the bean name of this property, which is derived from the read
+     * and write method names.
+     *
+     * @since 1.2
+     */
+    String getBeanName();
+
     /**
      * Returns the type of this property.
      */
diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java
index d14818a..e775cc9 100644
--- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java
+++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java
@@ -1183,6 +1183,10 @@ public class JDBCStorableIntrospector extends StorableIntrospector {
             return mMainProperty.getName();
         }
 
+        public String getBeanName() {
+            return mMainProperty.getBeanName();
+        }
+
         public Class<?> getType() {
             return mMainProperty.getType();
         }
diff --git a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableBuilder.java b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableBuilder.java
index 98b7dad..2a58f93 100644
--- a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableBuilder.java
+++ b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableBuilder.java
@@ -34,6 +34,7 @@ import com.amazon.carbonado.AlternateKeys;
 import com.amazon.carbonado.Index;
 import com.amazon.carbonado.Indexes;
 import com.amazon.carbonado.Key;
+import com.amazon.carbonado.Name;
 import com.amazon.carbonado.Nullable;
 import com.amazon.carbonado.PrimaryKey;
 import com.amazon.carbonado.Storable;
@@ -455,6 +456,13 @@ public class SyntheticStorableBuilder
                                            property.getReadMethodName(),
                                            propertyType,
                                            null);
+
+        if (property.getName() != null) {
+            // Define @Name
+            Annotation ann = mi.addRuntimeVisibleAnnotation(TypeDesc.forClass(Name.class));
+            ann.putMemberValue("value", property.getName());
+        }
+
         if (property.isNullable()) {
             mi.addRuntimeVisibleAnnotation(TypeDesc.forClass(Nullable.class));
         }
-- 
cgit v1.2.3