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.DynamoDBRangeKey;
20  import org.springframework.util.Assert;
21  import org.springframework.util.ReflectionUtils;
22  import org.springframework.util.ReflectionUtils.FieldCallback;
23  import org.springframework.util.ReflectionUtils.MethodCallback;
24  
25  import java.lang.reflect.Field;
26  import java.lang.reflect.Method;
27  
28  
29  
30  
31  
32  public class DynamoDBHashAndRangeKeyMethodExtractorImpl<T> implements DynamoDBHashAndRangeKeyMethodExtractor<T> {
33  
34  	private final Class<T> idType;
35  	private Method hashKeyMethod;
36  	private Method rangeKeyMethod;
37  
38  	private Field hashKeyField;
39  	private Field rangeKeyField;
40  
41  	
42  
43  
44  
45  
46  
47  
48  	public DynamoDBHashAndRangeKeyMethodExtractorImpl(final Class<T> idType) {
49  
50  		Assert.notNull(idType, "Id type must not be null!");
51  		this.idType = idType;
52  		ReflectionUtils.doWithMethods(idType, new MethodCallback() {
53  			@Override
54  			public void doWith(Method method) {
55  				if (method.getAnnotation(DynamoDBHashKey.class) != null) {
56  					Assert.isNull(hashKeyMethod,
57  							"Multiple methods annotated by @DynamoDBHashKey within type " + idType.getName() + "!");
58  					ReflectionUtils.makeAccessible(method);
59  					hashKeyMethod = method;
60  				}
61  			}
62  		});
63  		ReflectionUtils.doWithFields(idType, new FieldCallback() {
64  			@Override
65  			public void doWith(Field field) {
66  				if (field.getAnnotation(DynamoDBHashKey.class) != null) {
67  					Assert.isNull(hashKeyField,
68  							"Multiple fields annotated by @DynamoDBHashKey within type " + idType.getName() + "!");
69  					ReflectionUtils.makeAccessible(field);
70  
71  					hashKeyField = field;
72  				}
73  			}
74  		});
75  		ReflectionUtils.doWithMethods(idType, new MethodCallback() {
76  			@Override
77  			public void doWith(Method method) {
78  				if (method.getAnnotation(DynamoDBRangeKey.class) != null) {
79  					Assert.isNull(rangeKeyMethod,
80  							"Multiple methods annotated by @DynamoDBRangeKey within type " + idType.getName() + "!");
81  					ReflectionUtils.makeAccessible(method);
82  					rangeKeyMethod = method;
83  				}
84  			}
85  		});
86  		ReflectionUtils.doWithFields(idType, new FieldCallback() {
87  			@Override
88  			public void doWith(Field field) {
89  				if (field.getAnnotation(DynamoDBRangeKey.class) != null) {
90  					Assert.isNull(rangeKeyField,
91  							"Multiple fields annotated by @DynamoDBRangeKey within type " + idType.getName() + "!");
92  					ReflectionUtils.makeAccessible(field);
93  					rangeKeyField = field;
94  				}
95  			}
96  		});
97  		if (hashKeyMethod == null && hashKeyField == null) {
98  			throw new IllegalArgumentException(
99  					"No method or field annotated by @DynamoDBHashKey within type " + idType.getName() + "!");
100 		}
101 		if (rangeKeyMethod == null && rangeKeyField == null) {
102 			throw new IllegalArgumentException(
103 					"No method or field annotated by @DynamoDBRangeKey within type " + idType.getName() + "!");
104 		}
105 		if (hashKeyMethod != null && hashKeyField != null) {
106 			throw new IllegalArgumentException(
107 					"Both method and field annotated by @DynamoDBHashKey within type " + idType.getName() + "!");
108 		}
109 		if (rangeKeyMethod != null && rangeKeyField != null) {
110 			throw new IllegalArgumentException(
111 					"Both method and field annotated by @DynamoDBRangeKey within type " + idType.getName() + "!");
112 		}
113 	}
114 
115 	@Override
116 	public Class<T> getJavaType() {
117 		return idType;
118 	}
119 
120 	@Override
121 	public Method getHashKeyMethod() {
122 
123 		return hashKeyMethod;
124 	}
125 
126 	@Override
127 	public Method getRangeKeyMethod() {
128 		return rangeKeyMethod;
129 	}
130 
131 	@Override
132 	public Field getHashKeyField() {
133 
134 		return hashKeyField;
135 	}
136 
137 	@Override
138 	public Field getRangeKeyField() {
139 		return rangeKeyField;
140 	}
141 
142 }