Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Copyright 2011-2014 Amazon Technologies, Inc.
    *
    * 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://aws.amazon.com/apache2.0
    *
   * This file 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.amazonaws.services.dynamodbv2.datamodeling;
  
  import java.util.Date;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.UUID;
  
  import  org.apache.http.annotation.GuardedBy;
  
  import  com.amazonaws.services.dynamodbv2.model.AttributeValue;
Reflection assistant for DynamoDBMapper

Deprecated:
These classes have been deprecated, please use the classes in the com.amazonaws.mobileconnectors namespace.
These classes have been deprecated, please use the classes in the com.amazonaws.mobileconnectors namespace.
  
  public class DynamoDBReflector {
  
      /*
       * Several caches for performance. Collectively, they can make this class
       * over twice as fast.
       */
      private final Map<Class<?>, Collection<Method>> getterCache = new HashMap<Class<?>, Collection<Method>>();
      private final Map<Class<?>, MethodprimaryHashKeyGetterCache = new HashMap<Class<?>, Method>();
      private final Map<Class<?>, MethodprimaryRangeKeyGetterCache = new HashMap<Class<?>, Method>();
  
      /*
       * All caches keyed by a Method use the getter for a particular mapped
       * property
       */
      private final Map<MethodMethodsetterCache = new HashMap<MethodMethod>();
  
      @GuardedBy("readWriteLockAttrName")
      private final Map<MethodStringattributeNameCache = new HashMap<MethodString>();
  
      private final Map<MethodBooleanversionAttributeGetterCache = new HashMap<MethodBoolean>();
      private final Map<MethodBooleanautoGeneratedKeyGetterCache = new HashMap<MethodBoolean>();
  
      private final ReadLock readLockAttrName = .readLock();
      private final WriteLock writeLockAttrName = .writeLock();

    
Returns the set of getter methods which are relevant when marshalling or unmarshalling an object.
  
      Collection<MethodgetRelevantGetters(Class<?> clazz) {
          synchronized () {
              if ( !.containsKey(clazz) ) {
                  List<MethodrelevantGetters = new LinkedList<Method>();
                  for ( Method m : clazz.getMethods() ) {
                      if ( isRelevantGetter(m) ) {
                          relevantGetters.add(m);
                      }
                  }
                  .put(clazzrelevantGetters);
             }
             return .get(clazz);
         }
     }

    
Returns whether the method given is a getter method we should serialize / deserialize to the service. The method must begin with "get" or "is", have no arguments, belong to a class that declares its table, and not be marked ignored.
 
     private boolean isRelevantGetter(Method m) {
         return (m.getName().startsWith("get") || m.getName().startsWith("is"))
                 && m.getParameterTypes().length == 0
                 && m.getDeclaringClass().getAnnotation(DynamoDBTable.class) != null
                 && !ReflectionUtils.getterOrFieldHasAnnotation(mDynamoDBIgnore.class);
     }

    
Returns the annotated DynamoDBRangeKey getter for the class given, or null if the class doesn't have one.
 
     <T> Method getPrimaryRangeKeyGetter(Class<T> clazz) {
         synchronized () {
             if ( !.containsKey(clazz) ) {
                 Method rangeKeyMethod = null;
                 for ( Method method : getRelevantGetters(clazz) ) {
                     if ( method.getParameterTypes().length == 0
                             && ReflectionUtils.getterOrFieldHasAnnotation(methodDynamoDBRangeKey.class)) {
                         rangeKeyMethod = method;
                         break;
                     }
                 }
                 .put(clazzrangeKeyMethod);
             }
             return .get(clazz);
         }
     }

    
Returns all annotated DynamoDBHashKey and DynamoDBRangeKey getters for the class given, throwing an exception if there isn't one. TODO: caching
 
     <T> Collection<MethodgetPrimaryKeyGetters(Class<T> clazz) {
         List<MethodkeyGetters = new LinkedList<Method>();
         for (Method getter : getRelevantGetters(clazz)) {
             if (ReflectionUtils.getterOrFieldHasAnnotation(getterDynamoDBHashKey.class)
                     || ReflectionUtils.getterOrFieldHasAnnotation(getterDynamoDBRangeKey.class)) {
                 keyGetters.add(getter);
             }
         }
 
         return keyGetters;
     }


    
Returns the annotated DynamoDBHashKey getter for the class given, throwing an exception if there isn't one.
 
     <T> Method getPrimaryHashKeyGetter(Class<T> clazz) {
         Method hashKeyMethod;
         synchronized () {
             if ( !.containsKey(clazz) ) {
                 for ( Method method : getRelevantGetters(clazz) ) {
                     if ( method.getParameterTypes().length == 0
                             && ReflectionUtils.getterOrFieldHasAnnotation(methodDynamoDBHashKey.class)) {
                         .put(clazzmethod);
                         break;
                     }
                 }
             }
             hashKeyMethod = .get(clazz);
         }
 
         if ( hashKeyMethod == null ) {
             throw new DynamoDBMappingException("Public, zero-parameter hash key property must be annotated with "
                     + DynamoDBHashKey.class);
         }
         return hashKeyMethod;
     }

    
Returns the DynamoDBTable annotation of the class given, throwing a runtime exception if it isn't annotated.
 
     <T> DynamoDBTable getTable(Class<T> clazz) {
         DynamoDBTable table = clazz.getAnnotation(DynamoDBTable.class);
         if ( table == null )
             throw new DynamoDBMappingException("Class " + clazz + " must be annotated with " + DynamoDBTable.class);
         return table;
     }

    
Returns whether or not this getter has a custom marshaller
 
     private boolean isCustomMarshaller(Method getter) {
         return ReflectionUtils.getterOrFieldHasAnnotation(getterDynamoDBMarshalling.class);
     }

    
Returns the argument unmarshaller used to unmarshall the getter / setter pair given.

Determining how to unmarshall a response, especially a numeric one, requires checking it against all supported types. This is expensive, so we cache a lookup table of getter method to argument unmarhsaller which can be reused.

Parameters:
toReturn The typed domain object being unmarshalled for the client
getter The getter method being considered
setter The corresponding setter method being considered
 
     <T> ArgumentUnmarshaller getArgumentUnmarshaller(final T toReturnfinal Method getterfinal Method setterS3ClientCache s3cc) {
         synchronized () {
             ArgumentUnmarshaller unmarshaller = .get(getter);
             if ( unmarshaller != null ) {
                 return unmarshaller;
             }
             Class<?>[] parameterTypes = setter.getParameterTypes();
             Class<?> paramType = parameterTypes[0];
             if ( parameterTypes.length != 1 ) {
                 throw new DynamoDBMappingException("Expected exactly one agument to " + setter);
             }
 
             if ( isCustomMarshaller(getter) ) {
                 unmarshaller = new SUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return getCustomMarshalledValue(toReturngettervalue);
                     }
                 };
             } else {
                 unmarshaller = computeArgumentUnmarshaller(toReturngettersetterparamTypes3cc);
             }
             .put(getterunmarshaller);
             return unmarshaller;
         }
     }

    
Note this method is synchronized on argumentUnmarshallerCache while being executed.
 
         final T toReturnfinal Method getterfinal Method setterClass<?> paramTypeS3ClientCache s3cc)
     {
         ArgumentUnmarshaller unmarshaller = null;
         // If we're dealing with a collection, we need to get the
         // underlying type out of it
         final boolean isCollection = Set.class.isAssignableFrom(paramType);
         if ( isCollection ) {
             Type genericType = setter.getGenericParameterTypes()[0];
             if ( genericType instanceof ParameterizedType ) {
                 if (((ParameterizedTypegenericType).getActualTypeArguments()[0].toString().equals("byte[]")) {
                     paramType = byte[].class;
                 } else {
                     paramType = (Class<?>) ((ParameterizedTypegenericType).getActualTypeArguments()[0];
                 }
             }
         } else if ( Collection.class.isAssignableFrom(paramType) ) {
             throw new DynamoDBMappingException("Only java.util.Set collection types are permitted for "
                     + DynamoDBAttribute.class);
         }
 
         if ( double.class.isAssignableFrom(paramType) || Double.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new NSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         Set<Doubleargument = new HashSet<Double>();
                         for ( String s : value.getNS() ) {
                             argument.add(Double.parseDouble(s));
                         }
                         return argument;
                     }
 
                 };
             } else {
                 unmarshaller = new NUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return Double.parseDouble(value.getN());
                     }
                 };
             }
         } else if ( BigDecimal.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new NSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         Set<BigDecimalargument = new HashSet<BigDecimal>();
                         for ( String s : value.getNS() ) {
                             argument.add(new BigDecimal(s));
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new NUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return new BigDecimal(value.getN());
                     }
                 };
 
             }
         } else if ( BigInteger.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new NSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         Set<BigIntegerargument = new HashSet<BigInteger>();
                         for ( String s : value.getNS() ) {
                             ((Set<BigInteger>) argument).add(new BigInteger(s));
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new NUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return new BigInteger(value.getN());
                     }
                 };
             }
         } else if ( int.class.isAssignableFrom(paramType) || Integer.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new NSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         Set<Integerargument = new HashSet<Integer>();
                         for ( String s : value.getNS() ) {
                             argument.add(Integer.parseInt(s));
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new NUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return Integer.parseInt(value.getN());
                     }
                 };
             }
         } else if ( float.class.isAssignableFrom(paramType) || Float.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new NSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         Set<Floatargument = new HashSet<Float>();
                         for ( String s : value.getNS() ) {
                             argument.add(Float.parseFloat(s));
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new NUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return Float.parseFloat(value.getN());
                     }
                 };
             }
         } else if ( byte.class.isAssignableFrom(paramType) || Byte.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new NSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         Set<Byteargument = new HashSet<Byte>();
                         for ( String s : value.getNS() ) {
                             argument.add(Byte.parseByte(s));
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new NUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return Byte.parseByte(value.getN());
                     }
                 };
             }
         } else if ( long.class.isAssignableFrom(paramType) || Long.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new NSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         Set<Longargument = new HashSet<Long>();
                         for ( String s : value.getNS() ) {
                             argument.add(Long.parseLong(s));
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new NUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return Long.parseLong(value.getN());
                     }
                 };
             }
         } else if ( short.class.isAssignableFrom(paramType) || Short.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new NSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         Set<Shortargument = new HashSet<Short>();
                         for ( String s : value.getNS() ) {
                             argument.add(Short.parseShort(s));
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new NUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return Short.parseShort(value.getN());
                     }
                 };
             }
         } else if ( boolean.class.isAssignableFrom(paramType) || Boolean.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new NSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         Set<Booleanargument = new HashSet<Boolean>();
                         for ( String s : value.getNS() ) {
                             argument.add(parseBoolean(s));
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new NUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         return parseBoolean(value.getN());
                     }
                 };
             }
         } else if ( Date.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new SSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue valuethrows ParseException {
                         Set<Dateargument = new HashSet<Date>();
                         for ( String s : value.getSS() ) {
                             argument.add(DateUtils.parseISO8601Date(s));
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new SUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue valuethrows ParseException {
                         return DateUtils.parseISO8601Date(value.getS());
                     }
                 };
             }
         } else if ( Calendar.class.isAssignableFrom(paramType) ) {
             if ( isCollection ) {
                 unmarshaller = new SSUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue valuethrows ParseException {
                         Set<Calendarargument = new HashSet<Calendar>();
                         for ( String s : value.getSS() ) {
                             Calendar cal = GregorianCalendar.getInstance();
                             cal.setTime(DateUtils.parseISO8601Date(s));
                             argument.add(cal);
                         }
                         return argument;
                     }
                 };
             } else {
                 unmarshaller = new SUnmarshaller() {
 
                     @Override
                     public Object unmarshall(AttributeValue valuethrows ParseException {
                         Calendar cal = GregorianCalendar.getInstance();
                         cal.setTime(DateUtils.parseISO8601Date(value.getS()));
                         return cal;
                     }
                 };
             }
         } else if (ByteBuffer.class.isAssignableFrom(paramType)) {
               if ( isCollection ) {
                   unmarshaller = new BSUnmarshaller() {
 
                       @Override
                       public Object unmarshall(AttributeValue valuethrows ParseException {
                          Set<ByteBufferargument = new HashSet<ByteBuffer>();
                          for (ByteBuffer b : value.getBS()) {
                          argument.add(b);
                          }
                          return argument;
                       }
                   };
               } else {
                   unmarshaller = new BUnmarshaller() {
 
                       @Override
                       public Object unmarshall(AttributeValue valuethrows ParseException {
                           return value.getB();
                       }
                   };
               }
         } else if (byte[].class.isAssignableFrom(paramType)) {
              if ( isCollection ) {
               unmarshaller = new BSUnmarshaller() {
 
                      @Override
                      public Object unmarshall(AttributeValue valuethrows ParseException {
                      Set<byte[]> argument = new HashSet<byte[]>();
                      for (ByteBuffer b : value.getBS()) {
                          byte[] bytes = null;
                         if (b.hasArray()) {
                             bytes = b.array();
                         } else {
                             bytes = new byte[b.limit()];
                             b.get(bytes, 0, bytes.length);
                         }
                         argument.add(bytes);
                      }
                         return argument;
                      }
                  };
           } else {
               unmarshaller = new BUnmarshaller() {
 
                      @Override
                      public Object unmarshall(AttributeValue valuethrows ParseException {
                          ByteBuffer byteBuffer = value.getB();
                          byte[] bytes = null;
                          if (byteBuffer.hasArray()) {
                                 bytes = byteBuffer.array();
                             } else {
                                 bytes = new byte[byteBuffer.limit()];
                                 byteBuffer.get(bytes, 0, bytes.length);
                             }
                          return bytes;
                      }
                  };
           }
         } else {
             unmarshaller = defaultArgumentUnmarshaller(paramTypeisCollections3cc);
         }
         return unmarshaller;
     }

    
Note this method is synchronized on argumentUnmarshallerCache while being executed.

Parameters:
paramType the parameter type or the element type if the parameter is a collection
isCollection true if the parameter is a collection; false otherwise.
Returns:
the default unmarshaller
 
         (Class<?> paramTypeboolean isCollectionfinal S3ClientCache s3cc)
     {
         if (S3Link.class.isAssignableFrom(paramType)) {
             if ( isCollection ) {
                 throw new DynamoDBMappingException("Collection types are not permitted for " + S3Link.class);
             } else {
                 return new SUnmarshaller() {
                     @Override
                     public Object unmarshall(AttributeValue value) {
                         if ( s3cc == null ) {
                             throw new IllegalStateException("Mapper must be constructed with S3 AWS Credentials to load S3Link");
                         }
                         // value should never be null
                         String json = value.getS();
                         return S3Link.fromJson(s3ccjson);
                     }
                 };
             }
         } else {
             if ( !String.class.isAssignableFrom(paramType) ) {
                 throw new DynamoDBMappingException("Expected a String, but was " + paramType);
             } else {
                 if ( isCollection ) {
                     return new SSUnmarshaller() {
 
                         @Override
                         public Object unmarshall(AttributeValue value) {
                             Set<Stringargument = new HashSet<String>();
                             for ( String s : value.getSS() ) {
                                 argument.add(s);
                             }
                             return argument;
                         }
                     };
                 } else {
                     return new SUnmarshaller() {
 
                         @Override
                         public Object unmarshall(AttributeValue value) {
                             return value.getS();
                         }
                     };
                 }
             }
         }
     }

    
Marshalls the custom value given into the proper return type.
 
     @SuppressWarnings({ "rawtypes""unchecked" })
     private <T> T getCustomMarshalledValue(T toReturnMethod getter, AttributeValue value) {
         DynamoDBMarshalling annotation = ReflectionUtils.getAnnotationFromGetterOrField(getterDynamoDBMarshalling.class);
         Class<? extends DynamoDBMarshaller<? extends Object>> marshallerClass = annotation.marshallerClass();
 
         DynamoDBMarshaller marshaller;
         try {
             marshaller = marshallerClass.newInstance();
         } catch ( InstantiationException e ) {
             throw new DynamoDBMappingException("Couldn't instantiate marshaller of class " + marshallerClasse);
         } catch ( IllegalAccessException e ) {
             throw new DynamoDBMappingException("Couldn't instantiate marshaller of class " + marshallerClasse);
         }
 
         return (T) marshaller.unmarshall(getter.getReturnType(), value.getS());
     }

    
Returns an attribute value for the getter method with a custom marshaller. Directly returns null when the custom marshaller returns a null String.
 
     @SuppressWarnings({ "rawtypes""unchecked" })
     private AttributeValue getCustomerMarshallerAttributeValue(Method getterObject getterReturnResult) {
         DynamoDBMarshalling annotation = ReflectionUtils.getAnnotationFromGetterOrField(getterDynamoDBMarshalling.class);
         Class<? extends DynamoDBMarshaller<? extends Object>> marshallerClass = annotation.marshallerClass();
 
         DynamoDBMarshaller marshaller;
         try {
             marshaller = marshallerClass.newInstance();
         } catch ( InstantiationException e ) {
             throw new DynamoDBMappingException("Failed to instantiate custom marshaller for class " + marshallerClass,
                     e);
         } catch ( IllegalAccessException e ) {
             throw new DynamoDBMappingException("Failed to instantiate custom marshaller for class " + marshallerClass,
                     e);
         }
         String stringValue = marshaller.marshall(getterReturnResult);
 
         if(stringValue == null) {
             return null;
         } else {
             return new AttributeValue().withS(stringValue);
         }
     }

    
Returns a marshaller that knows how to provide an AttributeValue for the result of the getter given.
 
     ArgumentMarshaller getArgumentMarshaller(final Method getter) {
         synchronized () {
             ArgumentMarshaller marshaller = .get(getter);
             if ( marshaller != null ) {
                 return marshaller;
             }
             if ( isCustomMarshaller(getter) ) {
                 // Custom marshaller always returns String attribute value.
                 marshaller = new StringAttributeMarshaller() {
                     @Override public AttributeValue marshall(Object obj) {
                         return getCustomerMarshallerAttributeValue(getterobj);
                     }
                 };
             } else {
                 marshaller = computeArgumentMarshaller(getter);
             }
             .put(gettermarshaller);
             return marshaller;
         }
     }

    
Note this method is synchronized on argumentMarshallerCache while being executed.
 
     private ArgumentMarshaller computeArgumentMarshaller(final Method getter) {
         ArgumentMarshaller marshaller;
         Class<?> returnType = getter.getReturnType();
         if ( Set.class.isAssignableFrom(returnType) ) {
             Type genericType = getter.getGenericReturnType();
             if ( genericType instanceof ParameterizedType ) {
                 if ( ((ParameterizedTypegenericType).getActualTypeArguments()[0].toString().equals("byte[]") ) {
                     returnType = byte[].class;
                 } else {
                     returnType = (Class<?>) ((ParameterizedTypegenericType).getActualTypeArguments()[0];
                 }
             }
 
             if ( Date.class.isAssignableFrom(returnType) ) {
                 marshaller = new StringSetAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         List<Stringtimestamps = new LinkedList<String>();
                         for ( Object o : (Set<?>) obj ) {
                             timestamps.add(DateUtils.formatISO8601Date((Dateo));
                         }
                         return new AttributeValue().withSS(timestamps);
                     }
                 };
             } else if ( Calendar.class.isAssignableFrom(returnType) ) {
                 marshaller = new StringSetAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         List<Stringtimestamps = new LinkedList<String>();
                         for ( Object o : (Set<?>) obj ) {
                             timestamps.add(DateUtils.formatISO8601Date(((Calendaro).getTime()));
                         }
                         return new AttributeValue().withSS(timestamps);
                     }
                 };
             } else if ( boolean.class.isAssignableFrom(returnType)
                     || Boolean.class.isAssignableFrom(returnType) ) {
                 marshaller = new NumberSetAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         List<StringbooleanAttributes = new ArrayList<String>();
                         for ( Object b : (Set<?>) obj ) {
                             if ( b == null || !(Booleanb ) {
                                 booleanAttributes.add("0");
                             } else {
                                 booleanAttributes.add("1");
                             }
                         }
                         return new AttributeValue().withNS(booleanAttributes);
                     }
                 };
             } else if ( returnType.isPrimitive() || Number.class.isAssignableFrom(returnType) ) {
                 marshaller = new NumberSetAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         List<Stringattributes = new ArrayList<String>();
                         for ( Object o : (Set<?>) obj ) {
                             attributes.add(String.valueOf(o));
                         }
                         return new AttributeValue().withNS(attributes);
                     }
                 };
             } else if (ByteBuffer.class.isAssignableFrom(returnType)) {
                  marshaller = new BinarySetAttributeMarshaller() {
 
                      @Override
                      public AttributeValue marshall(Object obj) {
                          List<ByteBufferattributes = new ArrayList<ByteBuffer>();
                          for ( Object o : (Set<?>) obj ) {
                              attributes.add((ByteBuffero);
                          }
                          return new AttributeValue().withBS(attributes);
                      }
                  };
             } else if (byte[].class.isAssignableFrom(returnType)) {
                  marshaller = new BinarySetAttributeMarshaller() {
 
                      @Override
                      public AttributeValue marshall(Object obj) {
                          List<ByteBufferattributes = new ArrayList<ByteBuffer>();
                          for ( Object o : (Set<?>) obj ) {
                              attributes.add(ByteBuffer.wrap((byte[])o));
                          }
                          return new AttributeValue().withBS(attributes);
                      }
                  };
             } else {
                 // subclass may extend the behavior by overriding the
                 // defaultCollectionArgumentMarshaller method
                 marshaller = defaultCollectionArgumentMarshaller(returnType);
             }
         } else if ( Collection.class.isAssignableFrom(returnType) ) {
             throw new DynamoDBMappingException("Non-set collections aren't supported: "
                     + (getter.getDeclaringClass() + "." + getter.getName()));
         } else { // Non-set return type
             if ( Date.class.isAssignableFrom(returnType) ) {
                 marshaller = new StringAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         return new AttributeValue().withS(DateUtils.formatISO8601Date((Dateobj));
                     }
                 };
             } else if ( Calendar.class.isAssignableFrom(returnType) ) {
                 marshaller = new StringAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         return new AttributeValue().withS(DateUtils
                                 .formatISO8601Date(((Calendarobj).getTime()));
                     }
                 };
             } else if ( boolean.class.isAssignableFrom(returnType)
                     || Boolean.class.isAssignableFrom(returnType) ) {
                 marshaller = new NumberAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         if ( obj == null || !(Booleanobj ) {
                             return new AttributeValue().withN("0");
                         } else {
                             return new AttributeValue().withN("1");
                         }
                     }
                 };
             } else if ( returnType.isPrimitive() || Number.class.isAssignableFrom(returnType) ) {
                 marshaller = new NumberAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         return new AttributeValue().withN(String.valueOf(obj));
                     }
                 };
             } else if ( returnType == String.class ) {
                 marshaller = new StringAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         if ( ((Stringobj).length() == 0 )
                             return null;
                         return new AttributeValue().withS(String.valueOf(obj));
                     }
                 };
             } else if ( returnType == ByteBuffer.class ) {
                 marshaller = new BinaryAttributeMarshaller() {
 
                     @Override
                     public AttributeValue marshall(Object obj) {
                         return new AttributeValue().withB((ByteBuffer)obj);
                     }
                 };
             } else if ( returnType == byte[].class) {
                  marshaller = new BinaryAttributeMarshaller() {
 
                      @Override
                      public AttributeValue marshall(Object obj) {
                          return new AttributeValue().withB(ByteBuffer.wrap((byte[])obj));
                      }
                  };
             } else {
                 marshaller = defaultArgumentMarshaller(returnTypegetter);
             }
         }
         return marshaller;
     }

    
Note this method is synchronized on argumentMarshallerCache while being executed.

Parameters:
returnElementType the element of the return type which is known to be a collection
Returns:
the default argument marshaller for a collection
 
     private ArgumentMarshaller defaultCollectionArgumentMarshaller(final Class<?> returnElementType) {
         if ( S3Link.class.isAssignableFrom(returnElementType) ) {
             throw new DynamoDBMappingException("Collection types not permitted for " + S3Link.class);
         } else {
             return new StringSetAttributeMarshaller() {
                 @Override
                 public AttributeValue marshall(Object obj) {
                     List<Stringattributes = new ArrayList<String>();
                     for ( Object o : (Set<?>) obj ) {
                         attributes.add(String.valueOf(o));
                     }
                     return new AttributeValue().withSS(attributes);
                 }
             };
         }
     }

    
Note this method is synchronized on argumentMarshallerCache while being executed.

Parameters:
returnType the return type
Returns:
the default argument marshaller
 
     private ArgumentMarshaller defaultArgumentMarshaller(final Class<?> returnTypefinal Method getter) {
         if ( returnType == S3Link.class ) {
             return new StringAttributeMarshaller() {
                 @Override
                 public AttributeValue marshall(Object obj) {
                     S3Link s3link = (S3Linkobj;
                     if ( s3link.getBucketName() == null || s3link.getKey() == null ) {
                         // insufficient S3 resource specification
                         return null;
                     }
                     String json = s3link.toJson();
                     return new AttributeValue().withS(json);
                 }
             };
         } else {
             throw new DynamoDBMappingException("Unsupported type: " + returnType + " for " + getter);
         }
     }

    
Attempts to parse the string given as a boolean and return its value. Throws an exception if the value is anything other than 0 or 1.
 
     private boolean parseBoolean(String s) {
         if ( "1".equals(s) ) {
             return true;
         } else if ( "0".equals(s) ) {
             return false;
         } else {
             throw new IllegalArgumentException("Expected 1 or 0 for boolean value, was " + s);
         }
     }

    
Returns the attribute name corresponding to the given getter method.
 
     String getAttributeName(Method getter) {
         String attributeName;
         .lock();
         try {
             attributeName = .get(getter);
         } finally {
             .unlock();
         }
         if ( attributeName != null )
             return attributeName;
         DynamoDBHashKey hashKeyAnnotation = ReflectionUtils.getAnnotationFromGetterOrField(getterDynamoDBHashKey.class);
         if ( hashKeyAnnotation != null ) {
             attributeName = hashKeyAnnotation.attributeName();
             if ( attributeName != null && attributeName.length() > 0 )
                 return cacheAttributeName(getterattributeName); 
         }
         DynamoDBIndexHashKey indexHashKey = ReflectionUtils.getAnnotationFromGetterOrField(getterDynamoDBIndexHashKey.class);
         if ( indexHashKey != null ) {
             attributeName = indexHashKey.attributeName();
             if ( attributeName != null && attributeName.length() > 0 )
                 return cacheAttributeName(getterattributeName); 
         }
         DynamoDBRangeKey rangeKey = ReflectionUtils.getAnnotationFromGetterOrField(getterDynamoDBRangeKey.class);
         if ( rangeKey != null ) {
             attributeName = rangeKey.attributeName();
             if ( attributeName != null && attributeName.length() > 0 )
                 return cacheAttributeName(getterattributeName); 
         }
         DynamoDBIndexRangeKey indexRangeKey = ReflectionUtils.getAnnotationFromGetterOrField(getterDynamoDBIndexRangeKey.class);
         if ( indexRangeKey != null ) {
             attributeName = indexRangeKey.attributeName();
             if ( attributeName != null && attributeName.length() > 0 )
                 return cacheAttributeName(getterattributeName); 
         }
         DynamoDBAttribute attribute = ReflectionUtils.getAnnotationFromGetterOrField(getterDynamoDBAttribute.class);
         if ( attribute != null ) {
             attributeName = attribute.attributeName();
             if ( attributeName != null && attributeName.length() > 0 )
                 return cacheAttributeName(getterattributeName); 
         }
         DynamoDBVersionAttribute version = ReflectionUtils.getAnnotationFromGetterOrField(getterDynamoDBVersionAttribute.class);
         if ( version != null ) {
             attributeName = version.attributeName();
             if ( attributeName != null && attributeName.length() > 0 )
                 return cacheAttributeName(getterattributeName); 
         }
         // Default to the camel-cased field name of the getter method, inferred
         // according to the Java naming convention.
         attributeName = ReflectionUtils.getFieldNameByGetter(gettertrue);
         return cacheAttributeName(getterattributeName); 
     }
 
     private String cacheAttributeName(Method getterString attributeName) {
        .lock();
        try {
            .put(getterattributeName);
        } finally {
            .unlock();
        }
        return attributeName;
    }

    
Returns the setter corresponding to the getter given, or null if no such setter exists.
    Method getSetter(Method getter) {
        synchronized () {
            if ( !.containsKey(getter) ) {
                String fieldName = ReflectionUtils.getFieldNameByGetter(getterfalse);
                String setterName = "set" + fieldName;
                Method setter = null;
                try {
                    setter = getter.getDeclaringClass().getMethod(setterNamegetter.getReturnType());
                } catch ( NoSuchMethodException e ) {
                    throw new DynamoDBMappingException("Expected a public, one-argument method called " + setterName
                            + " on class " + getter.getDeclaringClass(), e);
                } catch ( SecurityException e ) {
                    throw new DynamoDBMappingException("No access to public, one-argument method called " + setterName
                            + " on class " + getter.getDeclaringClass(), e);
                }
                .put(gettersetter);
            }
            return .get(getter);
        }
    }

    
Returns a marshaller that knows how to provide an AttributeValue for the getter method given. Also increments the value of the getterReturnResult given.
    ArgumentMarshaller getVersionedArgumentMarshaller(final Method getterObject getterReturnResult) {
        synchronized () {
            if ( !.containsKey(getter) ) {
                ArgumentMarshaller marshaller = null;
                final Class<?> returnType = getter.getReturnType();
                if ( BigInteger.class.isAssignableFrom(returnType) ) {
                    marshaller = new ArgumentMarshaller() {
                        @Override
                        public AttributeValue marshall(Object obj) {
                            if ( obj == null )
                                obj = .;
                            Object newValue = ((BigIntegerobj).add(.);
                            return getArgumentMarshaller(getter).marshall(newValue);
                        }
                    };
                } else if ( Integer.class.isAssignableFrom(returnType) ) {
                    marshaller = new ArgumentMarshaller() {
                        @Override
                        public AttributeValue marshall(Object obj) {
                            if ( obj == null )
                                obj = new Integer(0);
                            Object newValue = ((Integerobj).intValue() + 1;
                            return getArgumentMarshaller(getter).marshall(newValue);
                        }
                    };
                } else if ( Byte.class.isAssignableFrom(returnType) ) {
                    marshaller = new ArgumentMarshaller() {
                        @Override
                        public AttributeValue marshall(Object obj) {
                            if ( obj == null )
                                obj = new Byte((byte) 0);
                            Object newValue = (byte) ((((Byteobj).byteValue() + 1) % .);
                            return getArgumentMarshaller(getter).marshall(newValue);
                        }
                    };
                } else if ( Long.class.isAssignableFrom(returnType) ) {
                    marshaller = new ArgumentMarshaller() {
                        @Override
                        public AttributeValue marshall(Object obj) {
                            if ( obj == null )
                                obj = new Long(0);