1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.spi.config.proxy;
17
18 import java.lang.annotation.Annotation;
19 import java.lang.reflect.Method;
20
21 import org.apache.commons.lang.WordUtils;
22
23 import de.smartics.properties.api.core.annotations.PropertyMetaDataMethod;
24
25
26
27
28 public final class PropertyMethodNameUtilities
29 {
30
31
32
33
34
35
36
37
38 private static final String GET_PREFIX = "get";
39
40
41
42
43
44 private static final String PROPERTY_DESCRIPTOR_SUFFIX = "PropertyDescriptor";
45
46
47
48
49
50 private static final String PROPERTY_KEY_SUFFIX = "PropertyKey";
51
52
53
54
55
56
57
58 private PropertyMethodNameUtilities()
59 {
60
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public static Method fetchPropertyMethod(final Method m)
81 {
82 final Method propertyMethod;
83 if (isMethodAnnotatedWithAnnotation(PropertyMetaDataMethod.class, m))
84 {
85 propertyMethod = fetchPropertyMethodUsingAnnotation(m);
86 }
87 else
88 {
89 propertyMethod = fetchPropertyMethodUsingNamingConvention(m);
90 }
91 return propertyMethod;
92 }
93
94
95
96
97
98
99
100
101
102
103
104 public static <T extends Annotation> boolean isMethodAnnotatedWithAnnotation(
105 final Class<T> annotation, final Method m)
106 {
107 return fetchAnnotation(annotation, m) != null;
108 }
109
110 private static Method fetchPropertyMethodUsingNamingConvention(final Method m)
111 {
112
113 final String methodName = m.getName();
114 final String propertyMethodName =
115 calculateMethodNameUsingNamingConvention(methodName);
116 final Class<?> propertyClass = m.getDeclaringClass();
117 Method propertyMethod = null;
118 try
119 {
120 final Method[] methods = propertyClass.getDeclaredMethods();
121 propertyMethod = lookupMethod(propertyMethodName, methods);
122
123 if (propertyMethod == null)
124 {
125 propertyMethod = lookupGetterMethod(propertyMethodName, methods);
126 }
127
128 if (propertyMethod == null)
129 {
130 throw new PropertyMethodNotFoundException(
131 "Method :'"
132 + propertyMethodName
133 + "' or its getter type method could not be found in interface: "
134 + propertyClass.getCanonicalName());
135 }
136 }
137 catch (final SecurityException e)
138 {
139 throw new PropertyMethodNotFoundException(
140 "Method :'" + methodName + "' could not be found in interface: "
141 + propertyClass.getCanonicalName(), e);
142 }
143 return propertyMethod;
144 }
145
146 private static Method lookupGetterMethod(final String propertyMethodName,
147 final Method[] methods)
148 {
149 Method propertyMethod;
150 final String getter = GET_PREFIX + WordUtils.capitalize(propertyMethodName);
151 propertyMethod = lookupMethod(getter, methods);
152 return propertyMethod;
153 }
154
155 private static Method lookupMethod(final String propertyMethodName,
156 final Method[] methods)
157 {
158 for (int i = 0; i < methods.length; i++)
159 {
160 final String name = methods[i].getName();
161 if (name.equals(propertyMethodName))
162 {
163 return methods[i];
164 }
165 }
166 return null;
167 }
168
169 private static String calculateMethodNameUsingNamingConvention(
170 final String methodName)
171 {
172 String propertyMethodName;
173 if (methodName.endsWith(PROPERTY_KEY_SUFFIX))
174 {
175 propertyMethodName = eliminateSuffix(methodName, PROPERTY_KEY_SUFFIX);
176 }
177 else if (methodName.endsWith(PROPERTY_DESCRIPTOR_SUFFIX))
178 {
179 propertyMethodName =
180 eliminateSuffix(methodName, PROPERTY_DESCRIPTOR_SUFFIX);
181 }
182 else
183 {
184 throw new PropertyMethodNotFoundException(
185 "Method :'"
186 + methodName
187 + "' is not a valid name for a property metadata method. "
188 + "Property metadata methods for keys must end with '"
189 + PROPERTY_KEY_SUFFIX + "' and for property descriptors with '"
190 + PROPERTY_DESCRIPTOR_SUFFIX
191 + "'. They may start with \"get\" but must not.");
192 }
193
194 if (propertyMethodName.startsWith(GET_PREFIX))
195 {
196 propertyMethodName = eliminatePrefix(propertyMethodName, GET_PREFIX);
197 }
198 return propertyMethodName;
199 }
200
201 private static String eliminatePrefix(
202 final String propertyMethodNameWithPrefix, final String prefix)
203 {
204 final String methodNameWithoutGet =
205 propertyMethodNameWithPrefix.substring(prefix.length());
206 final String propertyMethodName =
207 WordUtils.uncapitalize(methodNameWithoutGet);
208 return propertyMethodName;
209 }
210
211 private static String eliminateSuffix(final String methodName,
212 final String suffix)
213 {
214 String propertyMethodName;
215 propertyMethodName =
216 methodName.substring(0, methodName.length() - suffix.length());
217 return propertyMethodName;
218 }
219
220 private static Method fetchPropertyMethodUsingAnnotation(final Method m)
221 {
222 final PropertyMetaDataMethod annotation =
223 fetchAnnotation(PropertyMetaDataMethod.class, m);
224 final String methodName = annotation.value();
225 final Method propertyMethod =
226 fetchMethodByName(m.getDeclaringClass(), methodName);
227 return propertyMethod;
228 }
229
230 private static Method fetchMethodByName(final Class<?> class1,
231 final String methodName)
232 {
233 try
234 {
235 return class1.getDeclaredMethod(methodName, (Class<?>[]) null);
236 }
237 catch (final SecurityException e)
238 {
239 throw new PropertyMethodNotFoundException("Method :'" + methodName
240 + "' not found in interface: "
241 + class1.getCanonicalName(), e);
242 }
243 catch (final NoSuchMethodException e)
244 {
245 throw new PropertyMethodNotFoundException("Method :'" + methodName
246 + "' not found in interface: "
247 + class1.getCanonicalName(), e);
248 }
249 }
250
251 private static <T extends Annotation> T fetchAnnotation(
252 final Class<T> annotationClass, final Method m)
253 {
254 final T annotation = m.getAnnotation(annotationClass);
255 return annotation;
256 }
257
258
259
260 }