From 718eb5e99395f3c9f216fb7421d33a6a58cca4c6 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Wed, 17 Feb 2010 18:14:17 +0000 Subject: Add PartitionKey annotation. --- .../java/com/amazon/carbonado/PartitionKey.java | 51 +++++++ .../com/amazon/carbonado/info/StorableInfo.java | 8 +- .../carbonado/info/StorableIntrospector.java | 158 ++++++++++++++++----- .../com/amazon/carbonado/info/StorableKey.java | 6 +- .../amazon/carbonado/info/StorableProperty.java | 10 +- .../repo/jdbc/JDBCStorableIntrospector.java | 11 +- .../SyntheticStorableReferenceBuilder.java | 6 +- 7 files changed, 205 insertions(+), 45 deletions(-) create mode 100644 src/main/java/com/amazon/carbonado/PartitionKey.java diff --git a/src/main/java/com/amazon/carbonado/PartitionKey.java b/src/main/java/com/amazon/carbonado/PartitionKey.java new file mode 100644 index 0000000..588ae62 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/PartitionKey.java @@ -0,0 +1,51 @@ +/* + * Copyright 2006-2010 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.amazon.carbonado; + +import java.lang.annotation.*; + +/** + * Identifies a {@link Storable} property as being a member of the partition key. + * This key is ignored if the underlying repository lacks support for partitioning. + * + *

Example:

+ * @PrimaryKey("userInfoID")
+ * @PartitionKey("userInfoGroup")
+ * public interface UserInfo extends Storable<UserInfo> {
+ *     long getUserInfoID();
+ *     void setUserInfoID(long id);
+ *
+ *     String getUserInfoGroup();
+ *     void setUserInfoGroup(String group);
+ *
+ *     ...
+ * }
+ * 
+ * + * @author Archit Shivaprakash + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface PartitionKey { + /** + * A list of property names. + */ + String[] value() default {}; +} diff --git a/src/main/java/com/amazon/carbonado/info/StorableInfo.java b/src/main/java/com/amazon/carbonado/info/StorableInfo.java index 796efb4..0655908 100644 --- a/src/main/java/com/amazon/carbonado/info/StorableInfo.java +++ b/src/main/java/com/amazon/carbonado/info/StorableInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Copyright 2006-2010 Amazon Technologies, Inc. or its affiliates. * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks * of Amazon Technologies, Inc. or its affiliates. All rights reserved. * @@ -26,6 +26,7 @@ import com.amazon.carbonado.Storable; * Contains all the metadata describing a specific {@link Storable} type. * * @author Brian S O'Neill + * @author Archit Shivaprakash * @see StorableIntrospector */ public interface StorableInfo { @@ -92,6 +93,11 @@ public interface StorableInfo { */ StorableKey[] getAlternateKeys(); + /** + * Returns the partition key for the Storable, or null if none exists. + */ + StorableKey getPartitionKey(); + /** * Returns the count of aliases for the Storable. */ diff --git a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java index 06218a4..26b8cf6 100644 --- a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java +++ b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java @@ -1,5 +1,5 @@ /* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Copyright 2006-2010 Amazon Technologies, Inc. or its affiliates. * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks * of Amazon Technologies, Inc. or its affiliates. All rights reserved. * @@ -66,6 +66,7 @@ import com.amazon.carbonado.MalformedTypeException; import com.amazon.carbonado.Name; import com.amazon.carbonado.Nullable; import com.amazon.carbonado.Independent; +import com.amazon.carbonado.PartitionKey; import com.amazon.carbonado.PrimaryKey; import com.amazon.carbonado.Query; import com.amazon.carbonado.Sequence; @@ -86,6 +87,7 @@ import com.amazon.carbonado.util.ThrowUnchecked; * @author Brian S O'Neill * @author Fang Chen * @author Tobias Holgers + * @author Archit Shivaprakash */ public class StorableIntrospector { // Weakly maps Class objects to softly referenced StorableInfo objects. @@ -173,24 +175,30 @@ public class StorableIntrospector { List primaryKeyProps; List> alternateKeyProps; List> indexProps; + List partitionKeyProps; { try { - primaryKeyProps = gatherListProperties - (errorMessages, null, null, type.getAnnotation(PrimaryKey.class)).get(0); + primaryKeyProps = gatherListProperties(errorMessages, + type.getAnnotation(PrimaryKey.class)); } catch (IndexOutOfBoundsException e) { errorMessages.add("No primary key defined"); primaryKeyProps = Collections.emptyList(); } - alternateKeyProps = gatherListProperties - (errorMessages, null, type.getAnnotation(AlternateKeys.class), null); - indexProps = gatherListProperties - (errorMessages, type.getAnnotation(Indexes.class), null, null); + + alternateKeyProps = gatherListProperties(errorMessages, + type.getAnnotation(AlternateKeys.class)); + + indexProps = gatherListProperties(errorMessages, + type.getAnnotation(Indexes.class)); + + partitionKeyProps = gatherListProperties(errorMessages, + type.getAnnotation(PartitionKey.class)); } // Get all the properties. Map> properties = - examineProperties(type, primaryKeyProps, alternateKeyProps); + examineProperties(type, primaryKeyProps, alternateKeyProps, partitionKeyProps); // Resolve keys and indexes. @@ -212,6 +220,13 @@ public class StorableIntrospector { } } + StorableKey partitionKey = null; + if (partitionKeyProps != null) { + Set> propSet = + resolveKey(errorMessages, type, properties, "partition key", partitionKeyProps); + partitionKey = new SKey(false, propSet); + } + StorableIndex[] indexes; { indexes = new StorableIndex[indexProps.size()]; @@ -281,7 +296,7 @@ public class StorableIntrospector { } info = new Info(type, aliases, indexes, properties, - primaryKey, alternateKeys, + primaryKey, alternateKeys, partitionKey, type.getAnnotation(Independent.class) != null, type.getAnnotation(Authoritative.class) != null); @@ -426,21 +441,17 @@ public class StorableIntrospector { } /** - * @param indexes pass in just this for gathering index properties - * @param keys pass in just this for gathering alternate key properties - * @param primaryKey pass in just this for gathering primary key properties + * @param indexes pass in for gathering index properties */ private static List> gatherListProperties(List errorMessages, - Indexes indexes, - AlternateKeys keys, - PrimaryKey primaryKey) + Indexes indexes) { List> listlist = new ArrayList>(); if (indexes != null) { Index[] ixs = indexes.value(); if (ixs != null && ixs.length > 0) { - for (int i=0; i < ixs.length; i++) { + for (int i=0; i 0) { - for (int i=0; i < ixs.length; i++) { - String[] propNames = ixs[i].value(); + } + + return listlist; + } + + /** + * @param alternateKeys pass in for gathering alternate key properties + */ + private static List> gatherListProperties(List errorMessages, + AlternateKeys alternateKeys) + { + List> listlist = new ArrayList>(); + + if (alternateKeys != null) { + Key[] keys = alternateKeys.value(); + if (keys != null && keys.length > 0) { + for (int i=0; i gatherListProperties(List errorMessages, + PrimaryKey primaryKey) + { + List> listlist = new ArrayList>(); + + if (primaryKey != null) { String[] propNames = primaryKey.value(); if (propNames == null || propNames.length == 0) { errorMessages.add("Empty primary key defined"); @@ -470,7 +507,27 @@ public class StorableIntrospector { } } - return listlist; + return listlist.get(0); + } + + /** + * @param partitionKey pass in for gathering partition key properties + */ + private static List gatherListProperties(List errorMessages, + PartitionKey partitionKey) + { + List> listlist = new ArrayList>(); + + if (partitionKey != null) { + String[] propNames = partitionKey.value(); + if (propNames == null || propNames.length == 0) { + errorMessages.add("Empty partition key defined"); + } else { + gatherListProperties(errorMessages, "partition key", propNames, listlist); + } + } + + return listlist.size() > 0 ? listlist.get(0) : null; } private static void gatherListProperties(List errorMessages, @@ -569,7 +626,8 @@ public class StorableIntrospector { private static Map> examineProperties(Class type, List primaryKeyProps, - List> alternateKeyProps) + List> alternateKeyProps, + List partitionKeyProps) throws MalformedTypeException { if (Storable.class.isAssignableFrom(type)) { @@ -654,11 +712,12 @@ public class StorableIntrospector { } } - // Identify which properties are members of a primary or alternate key. - Set pkPropertyNames, altKeyPropertyNames; + // Identify which properties are members of a primary, alternate or partition key. + Set pkPropertyNames, altKeyPropertyNames, parKeyPropertyNames; { pkPropertyNames = new HashSet(); altKeyPropertyNames = new HashSet(); + parKeyPropertyNames = new HashSet(); for (NameAndDirection nameAndDir : primaryKeyProps) { pkPropertyNames.add(nameAndDir.name); } @@ -667,6 +726,11 @@ public class StorableIntrospector { altKeyPropertyNames.add(nameAndDir.name); } } + if (partitionKeyProps != null) { + for (NameAndDirection nameAndDir : partitionKeyProps) { + parKeyPropertyNames.add(nameAndDir.name); + } + } } Map allProperties = BeanIntrospector.getAllProperties(type); @@ -698,8 +762,9 @@ public class StorableIntrospector { continue; } - StorableProperty storableProp = makeStorableProperty - (errorMessages, property, type, pkPropertyNames, altKeyPropertyNames); + StorableProperty storableProp + = makeStorableProperty(errorMessages, property, type, + pkPropertyNames, altKeyPropertyNames, parKeyPropertyNames); if (storableProp == null) { // Errors. @@ -911,8 +976,9 @@ public class StorableIntrospector { * @param errorMessages error messages go here * @param property property to examine * @param enclosing enclosing class - * @param pk true if member of primary key - * @param altKey true if member of alternate key + * @param pkPropertyNames primary key property names + * @param altKeyPropertyNames alternate key property names + * @param parKeyPropertyNames partition key property names */ @SuppressWarnings("unchecked") private static StorableProperty makeStorableProperty @@ -920,7 +986,8 @@ public class StorableIntrospector { BeanProperty property, Class enclosing, Set pkPropertyNames, - Set altKeyPropertyNames) + Set altKeyPropertyNames, + Set parKeyPropertyNames) { Nullable nullable = null; Alias alias = null; @@ -981,6 +1048,7 @@ public class StorableIntrospector { boolean pk = pkPropertyNames.contains(propertyName); boolean altKey = altKeyPropertyNames.contains(propertyName); + boolean parKey = parKeyPropertyNames.contains(propertyName); if (writeMethod == null) { if (readMethod == null || Modifier.isAbstract(readMethod.getModifiers())) { @@ -1047,6 +1115,10 @@ public class StorableIntrospector { errorMessages.add("Derived properties cannot be a member of primary key: " + propertyName); } + if (parKey) { + errorMessages.add("Derived properties cannot be a member of partition key: " + + propertyName); + } if (sequence != null) { errorMessages.add("Derived properties cannot have a Sequence annotation: " + propertyName); @@ -1165,7 +1237,7 @@ public class StorableIntrospector { return null; } return new SimpleProperty - (property, enclosing, nullable != null, pk, altKey, + (property, enclosing, nullable != null, pk, altKey, parKey, aliases, constraints, adapters == null ? null : adapters[0], version != null, sequenceName, independent != null, automatic != null, derived, propertyName); @@ -1530,6 +1602,7 @@ public class StorableIntrospector { private final Map> mAllProperties; private final StorableKey mPrimaryKey; private final StorableKey[] mAltKeys; + private final StorableKey mPartitionKey; private final boolean mIndependent; private final boolean mAuthoritative; @@ -1542,6 +1615,7 @@ public class StorableIntrospector { Map> properties, StorableKey primaryKey, StorableKey[] altKeys, + StorableKey partitionKey, boolean independent, boolean authoritative) { @@ -1551,6 +1625,7 @@ public class StorableIntrospector { mAllProperties = properties; mPrimaryKey = primaryKey; mAltKeys = altKeys; + mPartitionKey = partitionKey; mIndependent = independent; mAuthoritative = authoritative; } @@ -1692,6 +1767,10 @@ public class StorableIntrospector { } } + public StorableKey getPartitionKey() { + return mPartitionKey; + } + public final boolean isIndependent() { return mIndependent; } @@ -1779,6 +1858,7 @@ public class StorableIntrospector { private final boolean mNullable; private final boolean mPrimaryKey; private final boolean mAlternateKey; + private final boolean mPartitionKey; private final String[] mAliases; private final StorablePropertyConstraint[] mConstraints; private final StorablePropertyAdapter mAdapter; @@ -1808,8 +1888,8 @@ public class StorableIntrospector { // reference from a property exists. protected StorableInfo mEnclosingInfo; - SimpleProperty(BeanProperty property, Class enclosing, - boolean nullable, boolean primaryKey, boolean alternateKey, + SimpleProperty(BeanProperty property, Class enclosing, boolean nullable, + boolean primaryKey, boolean alternateKey, boolean partitionKey, String[] aliases, StorablePropertyConstraint[] constraints, StorablePropertyAdapter adapter, boolean isVersion, String sequence, @@ -1822,6 +1902,7 @@ public class StorableIntrospector { mNullable = property.getType().isPrimitive() ? false : nullable; mPrimaryKey = primaryKey; mAlternateKey = alternateKey; + mPartitionKey = partitionKey; mAliases = aliases; mConstraints = constraints; mAdapter = adapter; @@ -1899,6 +1980,10 @@ public class StorableIntrospector { return mAlternateKey; } + public final boolean isPartitionKeyMember() { + return mPartitionKey; + } + public final int getAliasCount() { String[] aliases = mAliases; return aliases == null ? 0 : aliases.length; @@ -2359,8 +2444,9 @@ public class StorableIntrospector { Class joinedType, String[] internal, String[] external, String name) { - super(property, enclosing, nullable, false, false, - aliases, constraints, adapter, false, sequence, independent, automatic, derived, name); + super(property, enclosing, nullable, false, false, false, + aliases, constraints, adapter, + false, sequence, independent, automatic, derived, name); mJoinedType = joinedType; int length = internal.length; diff --git a/src/main/java/com/amazon/carbonado/info/StorableKey.java b/src/main/java/com/amazon/carbonado/info/StorableKey.java index a6e5582..a203c42 100644 --- a/src/main/java/com/amazon/carbonado/info/StorableKey.java +++ b/src/main/java/com/amazon/carbonado/info/StorableKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Copyright 2006-2010 Amazon Technologies, Inc. or its affiliates. * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks * of Amazon Technologies, Inc. or its affiliates. All rights reserved. * @@ -24,14 +24,14 @@ import com.amazon.carbonado.Storable; import com.amazon.carbonado.util.Appender; /** - * Represents a primary or alternate key of a specific {@link Storable} type. + * Represents a primary, alternate or partition key of a specific {@link Storable} type. * * @author Brian S O'Neill * @see StorableIntrospector */ public interface StorableKey extends Appender { /** - * Returns true if this key is primary, false if an alternate. + * Returns true if this key is primary, false otherwise. */ boolean isPrimary(); diff --git a/src/main/java/com/amazon/carbonado/info/StorableProperty.java b/src/main/java/com/amazon/carbonado/info/StorableProperty.java index aadc623..d8f3f8b 100644 --- a/src/main/java/com/amazon/carbonado/info/StorableProperty.java +++ b/src/main/java/com/amazon/carbonado/info/StorableProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Copyright 2006-2010 Amazon Technologies, Inc. or its affiliates. * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks * of Amazon Technologies, Inc. or its affiliates. All rights reserved. * @@ -28,6 +28,7 @@ import com.amazon.carbonado.util.Appender; * * @author Brian S O'Neill * @author Tobias Holgers + * @author Archit Shivaprakash * @see StorableIntrospector */ public interface StorableProperty extends Serializable, Appender { @@ -120,6 +121,13 @@ public interface StorableProperty extends Serializable, Appe */ boolean isAlternateKeyMember(); + /** + * Returns true if this property is a member of a partition key. + * + * @see com.amazon.carbonado.PartitionKey + */ + boolean isPartitionKeyMember(); + /** * Returns the count of aliases for 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 cecd7a9..336f111 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java @@ -1,5 +1,5 @@ /* - * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Copyright 2006-2010 Amazon Technologies, Inc. or its affiliates. * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks * of Amazon Technologies, Inc. or its affiliates. All rights reserved. * @@ -74,6 +74,7 @@ import com.amazon.carbonado.info.StorablePropertyConstraint; * @author Brian S O'Neill * @author Adam D Bradley * @author Tobias Holgers + * @author Archit Shivaprakash */ public class JDBCStorableIntrospector extends StorableIntrospector { // Maps compound keys to softly referenced JDBCStorableInfo objects. @@ -1061,6 +1062,10 @@ public class JDBCStorableIntrospector extends StorableIntrospector { return mMainInfo.getAlternateKeys(); } + public StorableKey getPartitionKey() { + return mMainInfo.getPartitionKey(); + } + public int getAliasCount() { return mMainInfo.getAliasCount(); } @@ -1302,6 +1307,10 @@ public class JDBCStorableIntrospector extends StorableIntrospector { return mMainProperty.isAlternateKeyMember(); } + public boolean isPartitionKeyMember() { + return mMainProperty.isPartitionKeyMember(); + } + public int getAliasCount() { return mMainProperty.getAliasCount(); } diff --git a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java index 9a44574..69b2a9c 100644 --- a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java +++ b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java @@ -110,7 +110,7 @@ public class SyntheticStorableReferenceBuilder String mCopyToMasterPkMethodName; // The result of building. - private SyntheticStorableReferenceAccess mReferenceAccess; + private SyntheticStorableReferenceAccess mReferenceAccess; /** * @param storableClass @@ -206,10 +206,10 @@ public class SyntheticStorableReferenceBuilder * * @since 1.2.1 */ - public SyntheticStorableReferenceAccess getReferenceAccess() { + public SyntheticStorableReferenceAccess getReferenceAccess() { if (mReferenceAccess == null) { Class referenceClass = mBuilder.getStorableClass(); - mReferenceAccess = new SyntheticStorableReferenceAccess + mReferenceAccess = new SyntheticStorableReferenceAccess (mMasterStorableClass, referenceClass, this); } return mReferenceAccess; -- cgit v1.2.3