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 }