1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.socialsignin.spring.data.dynamodb.repository.support;
17
18 import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
19 import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIndexRangeKey;
20 import org.springframework.data.annotation.Id;
21 import org.springframework.util.Assert;
22 import org.springframework.util.ReflectionUtils;
23
24 import java.lang.reflect.Field;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.util.HashSet;
28 import java.util.Set;
29
30
31
32
33
34 public class DynamoDBHashAndRangeKeyExtractingEntityMetadataImpl<T, ID> extends DynamoDBEntityMetadataSupport<T, ID>
35 implements
36 DynamoDBHashAndRangeKeyExtractingEntityMetadata<T, ID> {
37
38 private DynamoDBHashAndRangeKeyMethodExtractor<T> hashAndRangeKeyMethodExtractor;
39
40 private Method hashKeySetterMethod;
41 private Field hashKeyField;
42
43 public DynamoDBHashAndRangeKeyExtractingEntityMetadataImpl(final Class<T> domainType) {
44 super(domainType);
45 this.hashAndRangeKeyMethodExtractor = new DynamoDBHashAndRangeKeyMethodExtractorImpl<T>(getJavaType());
46 ReflectionUtils.doWithMethods(domainType, method -> {
47 if (method.getAnnotation(DynamoDBHashKey.class) != null) {
48 String setterMethodName = toSetterMethodNameFromAccessorMethod(method);
49 if (setterMethodName != null) {
50 hashKeySetterMethod = ReflectionUtils.findMethod(domainType, setterMethodName,
51 method.getReturnType());
52 }
53 }
54 });
55 ReflectionUtils.doWithFields(domainType, field -> {
56 if (field.getAnnotation(DynamoDBHashKey.class) != null) {
57
58 hashKeyField = ReflectionUtils.findField(domainType, field.getName());
59
60 }
61 });
62 Assert.isTrue(hashKeySetterMethod != null || hashKeyField != null,
63 "Unable to find hash key field or setter method on " + domainType + "!");
64 Assert.isTrue(hashKeySetterMethod == null || hashKeyField == null,
65 "Found both hash key field and setter method on " + domainType + "!");
66
67 }
68
69 @Override
70 public <H> HashAndRangeKeyExtractor<ID, H> getHashAndRangeKeyExtractor(Class<ID> idClass) {
71 return new CompositeIdHashAndRangeKeyExtractor<>(idClass);
72 }
73
74 @Override
75 public String getRangeKeyPropertyName() {
76 return getPropertyNameForAccessorMethod(hashAndRangeKeyMethodExtractor.getRangeKeyMethod());
77 }
78
79 @Override
80 public Set<String> getIndexRangeKeyPropertyNames() {
81 final Set<String> propertyNames = new HashSet<>();
82 ReflectionUtils.doWithMethods(getJavaType(), method -> {
83 if (method.getAnnotation(DynamoDBIndexRangeKey.class) != null) {
84 if ((method.getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexName() != null && method
85 .getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexName().trim().length() > 0)
86 || (method.getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexNames() != null
87 && method.getAnnotation(DynamoDBIndexRangeKey.class)
88 .localSecondaryIndexNames().length > 0)) {
89 propertyNames.add(getPropertyNameForAccessorMethod(method));
90 }
91 }
92 });
93 ReflectionUtils.doWithFields(getJavaType(), field -> {
94 if (field.getAnnotation(DynamoDBIndexRangeKey.class) != null) {
95 if ((field.getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexName() != null && field
96 .getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexName().trim().length() > 0)
97 || (field.getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexNames() != null && field
98 .getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexNames().length > 0)) {
99 propertyNames.add(getPropertyNameForField(field));
100 }
101 }
102 });
103 return propertyNames;
104 }
105
106 public T getHashKeyPropotypeEntityForHashKey(Object hashKey) {
107
108 try {
109 T entity = getJavaType().getDeclaredConstructor().newInstance();
110 if (hashKeySetterMethod != null) {
111 ReflectionUtils.invokeMethod(hashKeySetterMethod, entity, hashKey);
112 } else {
113 ReflectionUtils.setField(hashKeyField, entity, hashKey);
114 }
115
116 return entity;
117 } catch (InstantiationException | IllegalAccessException | NoSuchMethodException
118 | InvocationTargetException e) {
119 throw new RuntimeException(e);
120 }
121 }
122
123 @Override
124 public boolean isCompositeHashAndRangeKeyProperty(String propertyName) {
125 return isFieldAnnotatedWith(propertyName, Id.class);
126 }
127
128 }