40
40
import org .springframework .util .LinkedMultiValueMap ;
41
41
import org .springframework .util .MultiValueMap ;
42
42
43
+ import com .amazonaws .services .dynamodbv2 .datamodeling .DynamoDBMapperFieldModel ;
44
+ import com .amazonaws .services .dynamodbv2 .datamodeling .DynamoDBMapperTableModel ;
43
45
import com .amazonaws .services .dynamodbv2 .datamodeling .DynamoDBMarshaller ;
44
46
import com .amazonaws .services .dynamodbv2 .datamodeling .DynamoDBQueryExpression ;
45
47
import com .amazonaws .services .dynamodbv2 .model .AttributeValue ;
@@ -56,6 +58,7 @@ public abstract class AbstractDynamoDBQueryCriteria<T, ID extends Serializable>
56
58
protected Class <T > clazz ;
57
59
private DynamoDBEntityInformation <T , ID > entityInformation ;
58
60
private Map <String , String > attributeNamesByPropertyName ;
61
+ private final DynamoDBMapperTableModel <T > tableModel ;
59
62
private String hashKeyPropertyName ;
60
63
61
64
protected MultiValueMap <String , Condition > attributeConditions ;
@@ -211,14 +214,15 @@ protected List<Condition> getHashKeyConditions() {
211
214
return hashKeyConditions ;
212
215
}
213
216
214
- public AbstractDynamoDBQueryCriteria (DynamoDBEntityInformation <T , ID > dynamoDBEntityInformation ) {
217
+ public AbstractDynamoDBQueryCriteria (DynamoDBEntityInformation <T , ID > dynamoDBEntityInformation , final DynamoDBMapperTableModel < T > tableModel ) {
215
218
this .clazz = dynamoDBEntityInformation .getJavaType ();
216
219
this .attributeConditions = new LinkedMultiValueMap <String , Condition >();
217
220
this .propertyConditions = new LinkedMultiValueMap <String , Condition >();
218
221
this .hashKeyPropertyName = dynamoDBEntityInformation .getHashKeyPropertyName ();
219
222
this .entityInformation = dynamoDBEntityInformation ;
220
223
this .attributeNamesByPropertyName = new HashMap <String , String >();
221
-
224
+ // TODO consider adding the DynamoDBMapper table model to DynamoDBEntityInformation instead
225
+ this .tableModel = tableModel ;
222
226
}
223
227
224
228
private String getFirstDeclaredIndexNameForAttribute (Map <String ,String []> indexNamesByAttributeName ,List <String > indexNamesToCheck ,String attributeName )
@@ -479,16 +483,22 @@ public DynamoDBQueryCriteria<T, ID> withCondition(String propertyName, Condition
479
483
return this ;
480
484
}
481
485
482
- @ SuppressWarnings ("unchecked" )
483
- protected <V > Object getPropertyAttributeValue (String propertyName , Object value ) {
484
- DynamoDBMarshaller <V > marshaller = (DynamoDBMarshaller <V >) entityInformation .getMarshallerForProperty (propertyName );
486
+ @ SuppressWarnings ({"deprecation" , "unchecked" })
487
+ protected <V extends Object > Object getPropertyAttributeValue (final String propertyName , final V value ) {
488
+ // TODO consider removing DynamoDBMarshaller code altogether as table model will handle accordingly
489
+ final DynamoDBMarshaller <V > marshaller = (DynamoDBMarshaller <V >) entityInformation .getMarshallerForProperty (propertyName );
485
490
486
- if (marshaller != null ) {
487
- return marshaller .marshall ((V ) value );
488
- } else {
489
- return value ;
490
- }
491
- }
491
+ if (marshaller != null ) {
492
+ return marshaller .marshall (value );
493
+ } else if (tableModel != null ) { // purely here for testing as DynamoDBMapperTableModel cannot be mocked using Mockito
494
+ DynamoDBMapperFieldModel <T ,Object > fieldModel = tableModel .field (propertyName );
495
+ if (fieldModel != null ) {
496
+ return fieldModel .convert (value );
497
+ }
498
+ }
499
+
500
+ return value ;
501
+ }
492
502
493
503
protected <V > Condition createNoValueCondition (String propertyName , ComparisonOperator comparisonOperator ) {
494
504
@@ -626,16 +636,19 @@ protected Condition createSingleValueCondition(String propertyName, ComparisonOp
626
636
Assert .notNull (o , "Creating conditions on null property values not supported: please specify a value for '"
627
637
+ propertyName + "'" );
628
638
639
+ List <AttributeValue > attributeValueList = new ArrayList <AttributeValue >();
629
640
Object attributeValue = !alreadyMarshalledIfRequired ? getPropertyAttributeValue (propertyName , o ) : o ;
641
+ if (ClassUtils .isAssignableValue (AttributeValue .class , attributeValue )) {
642
+ attributeValueList .add ((AttributeValue ) attributeValue );
643
+ } else {
644
+ boolean marshalled = !alreadyMarshalledIfRequired && attributeValue != o
645
+ && !entityInformation .isCompositeHashAndRangeKeyProperty (propertyName );
630
646
631
- boolean marshalled = !alreadyMarshalledIfRequired && attributeValue != o
632
- && !entityInformation .isCompositeHashAndRangeKeyProperty (propertyName );
647
+ Class <?> targetPropertyType = marshalled ? String .class : propertyType ;
648
+ attributeValueList = addAttributeValue (attributeValueList , attributeValue , propertyName , targetPropertyType , true );
649
+ }
633
650
634
- Class <?> targetPropertyType = marshalled ? String .class : propertyType ;
635
- List <AttributeValue > attributeValueList = new ArrayList <AttributeValue >();
636
- attributeValueList = addAttributeValue (attributeValueList , attributeValue , propertyName , targetPropertyType , true );
637
651
return new Condition ().withComparisonOperator (comparisonOperator ).withAttributeValueList (attributeValueList );
638
-
639
652
}
640
653
641
654
protected Condition createCollectionCondition (String propertyName , ComparisonOperator comparisonOperator , Iterable <?> o ,
@@ -647,12 +660,15 @@ protected Condition createCollectionCondition(String propertyName, ComparisonOpe
647
660
boolean marshalled = false ;
648
661
for (Object object : o ) {
649
662
Object attributeValue = getPropertyAttributeValue (propertyName , object );
650
- if (attributeValue != null ) {
651
- marshalled = attributeValue != object && !entityInformation .isCompositeHashAndRangeKeyProperty (propertyName );
652
- }
653
- Class <?> targetPropertyType = marshalled ? String .class : propertyType ;
654
- attributeValueList = addAttributeValue (attributeValueList , attributeValue , propertyName , targetPropertyType , false );
655
-
663
+ if (ClassUtils .isAssignableValue (AttributeValue .class , attributeValue )) {
664
+ attributeValueList .add ((AttributeValue ) attributeValue );
665
+ } else {
666
+ if (attributeValue != null ) {
667
+ marshalled = attributeValue != object && !entityInformation .isCompositeHashAndRangeKeyProperty (propertyName );
668
+ }
669
+ Class <?> targetPropertyType = marshalled ? String .class : propertyType ;
670
+ attributeValueList = addAttributeValue (attributeValueList , attributeValue , propertyName , targetPropertyType , false );
671
+ }
656
672
}
657
673
658
674
return new Condition ().withComparisonOperator (comparisonOperator ).withAttributeValueList (attributeValueList );
0 commit comments