Mercurial > hg > Members > sugi > MessagePack-java
comparison src/main/java/org/msgpack/template/builder/beans/IndexedPropertyDescriptor.java @ 0:cb825acd883a
first commit
author | sugi |
---|---|
date | Sat, 18 Oct 2014 15:06:15 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:cb825acd883a |
---|---|
1 // MODIFIED FOR THE MSGPACK PROJECT | |
2 // Licensed to the Apache Software Foundation (ASF) under one or more | |
3 // contributor license agreements. See the NOTICE file distributed with | |
4 // this work for additional information regarding copyright ownership. | |
5 // The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 // (the "License"); you may not use this file except in compliance with | |
7 // the License. You may obtain a copy of the License at | |
8 // | |
9 // http://www.apache.org/licenses/LICENSE-2.0 | |
10 // | |
11 // Unless required by applicable law or agreed to in writing, software | |
12 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
13 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
14 // License for the specific language governing permissions and limitations under | |
15 // the License. | |
16 // | |
17 | |
18 package org.msgpack.template.builder.beans; | |
19 | |
20 import java.lang.reflect.Method; | |
21 | |
22 import org.apache.harmony.beans.BeansUtils; | |
23 import org.apache.harmony.beans.internal.nls.Messages; | |
24 | |
25 public class IndexedPropertyDescriptor extends PropertyDescriptor { | |
26 | |
27 private Class<?> indexedPropertyType; | |
28 | |
29 private Method indexedGetter; | |
30 | |
31 private Method indexedSetter; | |
32 | |
33 /** | |
34 * Constructs a new instance of <code>IndexedPropertyDescriptor</code>. | |
35 * | |
36 * @param propertyName | |
37 * the specified indexed property's name. | |
38 * @param beanClass | |
39 * the bean class | |
40 * @param getterName | |
41 * the name of the array getter | |
42 * @param setterName | |
43 * the name of the array setter | |
44 * @param indexedGetterName | |
45 * the name of the indexed getter. | |
46 * @param indexedSetterName | |
47 * the name of the indexed setter. | |
48 * @throws IntrospectionException | |
49 */ | |
50 public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass, | |
51 String getterName, String setterName, String indexedGetterName, | |
52 String indexedSetterName) throws IntrospectionException { | |
53 super(propertyName, beanClass, getterName, setterName); | |
54 setIndexedByName(beanClass, indexedGetterName, indexedSetterName); | |
55 } | |
56 | |
57 private void setIndexedByName(Class<?> beanClass, String indexedGetterName, | |
58 String indexedSetterName) throws IntrospectionException { | |
59 | |
60 String theIndexedGetterName = indexedGetterName; | |
61 if (theIndexedGetterName == null) { | |
62 if (indexedSetterName != null) { | |
63 setIndexedWriteMethod(beanClass, indexedSetterName); | |
64 } | |
65 } else { | |
66 if (theIndexedGetterName.length() == 0) { | |
67 theIndexedGetterName = "get" + name; //$NON-NLS-1$ | |
68 } | |
69 setIndexedReadMethod(beanClass, theIndexedGetterName); | |
70 if (indexedSetterName != null) { | |
71 setIndexedWriteMethod(beanClass, indexedSetterName, | |
72 indexedPropertyType); | |
73 } | |
74 } | |
75 | |
76 if (!isCompatible()) { | |
77 // custom.beans.57=Property type is incompatible with the indexed property type | |
78 throw new IntrospectionException(Messages.getString("custom.beans.57")); //$NON-NLS-1$ | |
79 } | |
80 } | |
81 | |
82 private boolean isCompatible() { | |
83 Class<?> propertyType = getPropertyType(); | |
84 | |
85 if (propertyType == null) { | |
86 return true; | |
87 } | |
88 Class<?> componentTypeOfProperty = propertyType.getComponentType(); | |
89 if (componentTypeOfProperty == null) { | |
90 return false; | |
91 } | |
92 if (indexedPropertyType == null) { | |
93 return false; | |
94 } | |
95 | |
96 return componentTypeOfProperty.getName().equals( | |
97 indexedPropertyType.getName()); | |
98 } | |
99 | |
100 /** | |
101 * Constructs a new instance of <code>IndexedPropertyDescriptor</code>. | |
102 * | |
103 * @param propertyName | |
104 * the specified indexed property's name. | |
105 * @param getter | |
106 * the array getter | |
107 * @param setter | |
108 * the array setter | |
109 * @param indexedGetter | |
110 * the indexed getter | |
111 * @param indexedSetter | |
112 * the indexed setter | |
113 * @throws IntrospectionException | |
114 */ | |
115 public IndexedPropertyDescriptor(String propertyName, Method getter, | |
116 Method setter, Method indexedGetter, Method indexedSetter) | |
117 throws IntrospectionException { | |
118 super(propertyName, getter, setter); | |
119 if (indexedGetter != null) { | |
120 internalSetIndexedReadMethod(indexedGetter); | |
121 internalSetIndexedWriteMethod(indexedSetter, true); | |
122 } else { | |
123 internalSetIndexedWriteMethod(indexedSetter, true); | |
124 internalSetIndexedReadMethod(indexedGetter); | |
125 } | |
126 | |
127 if (!isCompatible()) { | |
128 // custom.beans.57=Property type is incompatible with the indexed property type | |
129 throw new IntrospectionException(Messages.getString("custom.beans.57")); //$NON-NLS-1$ | |
130 } | |
131 } | |
132 | |
133 /** | |
134 * Constructs a new instance of <code>IndexedPropertyDescriptor</code>. | |
135 * | |
136 * @param propertyName | |
137 * the specified indexed property's name. | |
138 * @param beanClass | |
139 * the bean class. | |
140 * @throws IntrospectionException | |
141 */ | |
142 public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass) | |
143 throws IntrospectionException { | |
144 super(propertyName, beanClass); | |
145 setIndexedByName(beanClass, "get" //$NON-NLS-1$ | |
146 .concat(initialUpperCase(propertyName)), "set" //$NON-NLS-1$ | |
147 .concat(initialUpperCase(propertyName))); | |
148 } | |
149 | |
150 /** | |
151 * Sets the indexed getter as the specified method. | |
152 * | |
153 * @param indexedGetter | |
154 * the specified indexed getter. | |
155 * @throws IntrospectionException | |
156 */ | |
157 public void setIndexedReadMethod(Method indexedGetter) | |
158 throws IntrospectionException { | |
159 this.internalSetIndexedReadMethod(indexedGetter); | |
160 } | |
161 | |
162 /** | |
163 * Sets the indexed setter as the specified method. | |
164 * | |
165 * @param indexedSetter | |
166 * the specified indexed setter. | |
167 * @throws IntrospectionException | |
168 */ | |
169 public void setIndexedWriteMethod(Method indexedSetter) | |
170 throws IntrospectionException { | |
171 this.internalSetIndexedWriteMethod(indexedSetter, false); | |
172 } | |
173 | |
174 /** | |
175 * Obtains the indexed setter. | |
176 * | |
177 * @return the indexed setter. | |
178 */ | |
179 public Method getIndexedWriteMethod() { | |
180 return indexedSetter; | |
181 } | |
182 | |
183 /** | |
184 * Obtains the indexed getter. | |
185 * | |
186 * @return the indexed getter. | |
187 */ | |
188 public Method getIndexedReadMethod() { | |
189 return indexedGetter; | |
190 } | |
191 | |
192 /** | |
193 * Determines if this <code>IndexedPropertyDescriptor</code> is equal to | |
194 * the specified object. Two <code>IndexedPropertyDescriptor</code> s are | |
195 * equal if the reader, indexed reader, writer, indexed writer, property | |
196 * types, indexed property type, property editor and flags are equal. | |
197 * | |
198 * @param obj | |
199 * @return true if this indexed property descriptor is equal to the | |
200 * specified object. | |
201 */ | |
202 @Override | |
203 public boolean equals(Object obj) { | |
204 if (!(obj instanceof IndexedPropertyDescriptor)) { | |
205 return false; | |
206 } | |
207 | |
208 IndexedPropertyDescriptor other = (IndexedPropertyDescriptor) obj; | |
209 | |
210 return (super.equals(other) | |
211 && (indexedPropertyType == null ? other.indexedPropertyType == null | |
212 : indexedPropertyType.equals(other.indexedPropertyType)) | |
213 && (indexedGetter == null ? other.indexedGetter == null | |
214 : indexedGetter.equals(other.indexedGetter)) && (indexedSetter == null ? other.indexedSetter == null | |
215 : indexedSetter.equals(other.indexedSetter))); | |
216 } | |
217 | |
218 /** | |
219 * HashCode of the IndexedPropertyDescriptor | |
220 */ | |
221 @Override | |
222 public int hashCode() { | |
223 return super.hashCode() + BeansUtils.getHashCode(indexedPropertyType) | |
224 + BeansUtils.getHashCode(indexedGetter) | |
225 + BeansUtils.getHashCode(indexedSetter); | |
226 } | |
227 | |
228 /** | |
229 * Obtains the Class object of the indexed property type. | |
230 * | |
231 * @return the Class object of the indexed property type. | |
232 */ | |
233 public Class<?> getIndexedPropertyType() { | |
234 return indexedPropertyType; | |
235 } | |
236 | |
237 private void setIndexedReadMethod(Class<?> beanClass, String indexedGetterName) | |
238 throws IntrospectionException { | |
239 Method getter; | |
240 try { | |
241 getter = beanClass.getMethod(indexedGetterName, | |
242 new Class[] { Integer.TYPE }); | |
243 } catch (NoSuchMethodException exception) { | |
244 // custom.beans.58=No such indexed read method | |
245 throw new IntrospectionException(Messages.getString("custom.beans.58")); //$NON-NLS-1$ | |
246 } catch (SecurityException exception) { | |
247 // custom.beans.59=Security violation accessing indexed read method | |
248 throw new IntrospectionException(Messages.getString("custom.beans.59")); //$NON-NLS-1$ | |
249 } | |
250 internalSetIndexedReadMethod(getter); | |
251 } | |
252 | |
253 private void internalSetIndexedReadMethod(Method indexGetter) | |
254 throws IntrospectionException { | |
255 // Clearing the indexed read method. | |
256 if (indexGetter == null) { | |
257 if (indexedSetter == null) { | |
258 if (getPropertyType() != null) { | |
259 // custom.beans.5A=Indexed method is not compatible with non indexed method | |
260 throw new IntrospectionException(Messages | |
261 .getString("custom.beans.5A")); //$NON-NLS-1$ | |
262 } | |
263 indexedPropertyType = null; | |
264 } | |
265 this.indexedGetter = null; | |
266 return; | |
267 } | |
268 // Validate the indexed getter. | |
269 if ((indexGetter.getParameterTypes().length != 1) | |
270 || (indexGetter.getParameterTypes()[0] != Integer.TYPE)) { | |
271 // custom.beans.5B=Indexed read method must take a single int argument | |
272 throw new IntrospectionException(Messages.getString("custom.beans.5B")); //$NON-NLS-1$ | |
273 } | |
274 Class<?> indexedReadType = indexGetter.getReturnType(); | |
275 if (indexedReadType == Void.TYPE) { | |
276 // custom.beans.5B=Indexed read method must take a single int argument | |
277 throw new IntrospectionException(Messages.getString("custom.beans.5B")); //$NON-NLS-1$ | |
278 } else if (indexedSetter != null | |
279 && indexGetter.getReturnType() != indexedSetter | |
280 .getParameterTypes()[1]) { | |
281 // custom.beans.5A=Indexed read method is not compatible with indexed write method | |
282 throw new IntrospectionException(Messages.getString("custom.beans.5A")); //$NON-NLS-1$ | |
283 } | |
284 | |
285 // Set the indexed property type if not already set, confirm validity if | |
286 // it is. | |
287 if (this.indexedGetter == null) { | |
288 indexedPropertyType = indexedReadType; | |
289 } else { | |
290 if (indexedPropertyType != indexedReadType) { | |
291 // custom.beans.5A=Indexed read method is not compatible with indexed write method | |
292 throw new IntrospectionException(Messages.getString("custom.beans.5A")); //$NON-NLS-1$ | |
293 } | |
294 } | |
295 | |
296 // Set the indexed getter | |
297 this.indexedGetter = indexGetter; | |
298 } | |
299 | |
300 private void setIndexedWriteMethod(Class<?> beanClass, String indexedSetterName) | |
301 throws IntrospectionException { | |
302 Method setter = null; | |
303 try { | |
304 setter = beanClass.getMethod(indexedSetterName, new Class[] { | |
305 Integer.TYPE, getPropertyType().getComponentType() }); | |
306 } catch (SecurityException e) { | |
307 // custom.beans.5C=Security violation accessing indexed write method | |
308 throw new IntrospectionException(Messages.getString("custom.beans.5C")); //$NON-NLS-1$ | |
309 } catch (NoSuchMethodException e) { | |
310 // custom.beans.5D=No such indexed write method | |
311 throw new IntrospectionException(Messages.getString("custom.beans.5D")); //$NON-NLS-1$ | |
312 } | |
313 internalSetIndexedWriteMethod(setter, true); | |
314 } | |
315 | |
316 private void setIndexedWriteMethod(Class<?> beanClass, | |
317 String indexedSetterName, Class<?> argType) | |
318 throws IntrospectionException { | |
319 try { | |
320 Method setter = beanClass.getMethod(indexedSetterName, new Class[] { | |
321 Integer.TYPE, argType }); | |
322 internalSetIndexedWriteMethod(setter, true); | |
323 } catch (NoSuchMethodException exception) { | |
324 // custom.beans.5D=No such indexed write method | |
325 throw new IntrospectionException(Messages.getString("custom.beans.5D")); //$NON-NLS-1$ | |
326 } catch (SecurityException exception) { | |
327 // custom.beans.5C=Security violation accessing indexed write method | |
328 throw new IntrospectionException(Messages.getString("custom.beans.5C")); //$NON-NLS-1$ | |
329 } | |
330 } | |
331 | |
332 private void internalSetIndexedWriteMethod(Method indexSetter, | |
333 boolean initialize) throws IntrospectionException { | |
334 // Clearing the indexed write method. | |
335 if (indexSetter == null) { | |
336 if (indexedGetter == null) { | |
337 if (getPropertyType() != null) { | |
338 // custom.beans.5E=Indexed method is not compatible with non indexed method | |
339 throw new IntrospectionException(Messages | |
340 .getString("custom.beans.5E")); //$NON-NLS-1$ | |
341 } | |
342 indexedPropertyType = null; | |
343 } | |
344 this.indexedSetter = null; | |
345 return; | |
346 } | |
347 | |
348 // Validate the indexed write method. | |
349 Class<?>[] indexedSetterArgs = indexSetter.getParameterTypes(); | |
350 if (indexedSetterArgs.length != 2) { | |
351 // custom.beans.5F=Indexed write method must take two arguments | |
352 throw new IntrospectionException(Messages.getString("custom.beans.5F")); //$NON-NLS-1$ | |
353 } | |
354 if (indexedSetterArgs[0] != Integer.TYPE) { | |
355 // custom.beans.60=Indexed write method must take an int as its first argument | |
356 throw new IntrospectionException(Messages.getString("custom.beans.60")); //$NON-NLS-1$ | |
357 } | |
358 | |
359 // Set the indexed property type if not already set, confirm validity if | |
360 // it is. | |
361 Class<?> indexedWriteType = indexedSetterArgs[1]; | |
362 if (initialize && indexedGetter == null) { | |
363 indexedPropertyType = indexedWriteType; | |
364 } else { | |
365 if (indexedPropertyType != indexedWriteType) { | |
366 // custom.beans.61=Indexed write method is not compatible with indexed read method | |
367 throw new IntrospectionException(Messages.getString("custom.beans.61")); //$NON-NLS-1$ | |
368 } | |
369 } | |
370 | |
371 // Set the indexed write method. | |
372 this.indexedSetter = indexSetter; | |
373 } | |
374 | |
375 private static String initialUpperCase(String string) { | |
376 if (Character.isUpperCase(string.charAt(0))) { | |
377 return string; | |
378 } | |
379 | |
380 String initial = string.substring(0, 1).toUpperCase(); | |
381 return initial.concat(string.substring(1)); | |
382 } | |
383 } |