001: /*
002: * Copyright 2005-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005: * in compliance with the License. You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software distributed under the License
010: * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011: * or implied. See the License for the specific language governing permissions and limitations under
012: * the License.
013: */
014:
015: package org.strecks.util;
016:
017: import java.lang.reflect.GenericArrayType;
018: import java.lang.reflect.Method;
019: import java.lang.reflect.ParameterizedType;
020: import java.lang.reflect.Type;
021: import java.lang.reflect.TypeVariable;
022: import java.util.HashMap;
023: import java.util.List;
024: import java.util.Map;
025:
026: import org.strecks.converter.BindableBean;
027: import org.strecks.converter.Converter;
028: import org.strecks.converter.DatePatternConverter;
029: import org.strecks.exceptions.ApplicationRuntimeException;
030: import org.strecks.util.impl.ArrayConverter;
031: import org.strecks.util.impl.ClassWithNoArgMethod;
032: import org.strecks.util.impl.ClassWithNullMethod;
033: import org.strecks.util.impl.ClassWithPrivateMethod;
034: import org.strecks.util.impl.ClassWithVoidMethod;
035: import org.strecks.util.impl.ClassWithWildcardTypes;
036: import org.strecks.util.impl.ComparableIntegerSubclass;
037: import org.strecks.util.impl.GenericClass;
038: import org.strecks.util.impl.JavaBean;
039: import org.strecks.util.impl.MapContainingList;
040: import org.strecks.util.impl.MyClass;
041: import org.strecks.util.impl.MyClass.AbstractClass;
042: import org.strecks.util.impl.MyClass.PublicClass;
043: import org.strecks.validator.internal.impl.BeanWithGetterValidator;
044: import org.testng.Assert;
045: import org.testng.annotations.Test;
046:
047: /**
048: * @author Phil Zoio
049: */
050: public class TestReflectHelper {
051:
052: @Test(expectedExceptions=ApplicationRuntimeException.class)
053: public void testGetMethodWithArg() throws Exception {
054: JavaBean bean = new JavaBean();
055: assert null != ReflectHelper.getMethod(bean,
056: "setBooleanProperty");
057: }
058:
059: @Test
060: public void testGetNoArgMethod() throws Exception {
061: JavaBean bean = new JavaBean();
062: assert null != ReflectHelper.getMethod(bean,
063: "isBooleanProperty");
064: }
065:
066: @Test
067: public void testGetPropertyName() throws Exception {
068: Assert.assertEquals(ReflectHelper
069: .getPropertyName("setBooleanProperty"),
070: "booleanProperty");
071: }
072:
073: @Test
074: public void testGetGetterName() throws Exception {
075: Assert.assertEquals(ReflectHelper
076: .getPropertyName("setBooleanProperty"),
077: "booleanProperty");
078: }
079:
080: @Test
081: public void testGetSetter() throws Exception {
082: Method getter = BeanWithGetterValidator.class
083: .getMethod("getProperty");
084: Assert.assertEquals(ReflectHelper.getSetter(getter).getName(),
085: "setProperty");
086: }
087:
088: @Test
089: public void testCheckSetterMethodName() throws Exception {
090: Method setter = BeanWithGetterValidator.class.getMethod(
091: "setProperty", new Class[] { String.class });
092: Assert.assertEquals(
093: ReflectHelper.checkSetterMethodName(setter),
094: "setProperty");
095: }
096:
097: @Test
098: public void testCheckInvalidSetterMethodName() throws Exception {
099: Method setter = BeanWithGetterValidator.class
100: .getMethod("getProperty");
101:
102: try {
103: ReflectHelper.checkSetterMethodName(setter);
104: } catch (ApplicationRuntimeException e) {
105: Assert
106: .assertEquals(
107: e.getMessage(),
108: "Method public java.lang.String org.strecks.validator.internal.impl.BeanWithGetterValidator.getProperty() "
109: + "declared in class org.strecks.validator.internal.impl.BeanWithGetterValidator is not a setter method");
110: }
111: }
112:
113: @Test
114: public void testParameterLength() throws Exception {
115: Class c = MyClass.class;
116: Method method = c.getMethod("methodWithOneParam",
117: new Class[] { String.class });
118: ReflectHelper.checkParameterTypeLength(method, 1);
119: }
120:
121: @Test(expectedExceptions=ApplicationRuntimeException.class)
122: public void testParameterLength2() throws Exception {
123: Class c = MyClass.class;
124: Method method = c.getMethod("methodWithTwoParams", new Class[] {
125: String.class, String.class });
126: ReflectHelper.checkParameterTypeLength(method, 1);
127: }
128:
129: @Test
130: public void testIsGetter() throws SecurityException,
131: NoSuchMethodException {
132: BindableBean bean = new BindableBean();
133: Class<? extends BindableBean> clazz = bean.getClass();
134:
135: Method method = clazz.getMethod("isBoolValue");
136: assert ReflectHelper.isGetter(method);
137:
138: method = clazz.getMethod("getBooleanValue");
139: assert ReflectHelper.isGetter(method);
140:
141: method = clazz.getMethod("getDateValue");
142: assert ReflectHelper.isGetter(method);
143: }
144:
145: @Test
146: public void testIsSetter() throws SecurityException,
147: NoSuchMethodException {
148: BindableBean bean = new BindableBean();
149: Class<? extends BindableBean> clazz = bean.getClass();
150:
151: Method method = clazz.getMethod("setBoolValue",
152: new Class[] { Boolean.TYPE });
153: assert ReflectHelper.isSetter(method);
154:
155: method = clazz.getMethod("setDateValue",
156: new Class[] { String.class });
157: assert ReflectHelper.isSetter(method);
158: }
159:
160: @Test
161: public void testInvokeMethod1() throws Exception {
162: ClassWithVoidMethod instance = new ClassWithVoidMethod();
163: ReflectHelper.invokeMethod(instance, "method");
164: Assert.assertEquals(instance.getInvokeCount(), 1);
165: }
166:
167: @Test
168: public void testInvokeMethodNull() throws Exception {
169: ClassWithVoidMethod instance = new ClassWithVoidMethod();
170: ReflectHelper.invokeMethod(instance, "method", Void.TYPE);
171: Assert.assertEquals(instance.getInvokeCount(), 1);
172: }
173:
174: @Test
175: public void testInvokeReturnNull() throws Exception {
176: ClassWithNullMethod instance = new ClassWithNullMethod();
177: assert null == ReflectHelper.invokeMethod(instance, "method",
178: String.class);
179: Assert.assertEquals(instance.getInvokeCount(), 1);
180: }
181:
182: @Test
183: public void testInvokeMethod2() throws Exception {
184: ClassWithNoArgMethod instance = new ClassWithNoArgMethod();
185: Object invokeVoidMethod = ReflectHelper.invokeMethod(instance,
186: "method");
187: Assert.assertEquals(invokeVoidMethod, "hello");
188: }
189:
190: @Test
191: public void testInvokeMethodWithNullArg() throws Exception {
192: ClassWithNoArgMethod instance = new ClassWithNoArgMethod();
193: Object invokeVoidMethod = ReflectHelper.invokeMethod(instance,
194: "method", null);
195: Assert.assertEquals(invokeVoidMethod, "hello");
196: }
197:
198: @Test
199: public void testInvokeMethodWithClassCheck() throws Exception {
200: ClassWithNoArgMethod instance = new ClassWithNoArgMethod();
201: String invokeVoidMethod = ReflectHelper.invokeMethod(instance,
202: "method", String.class);
203: Assert.assertEquals(invokeVoidMethod, "hello");
204: }
205:
206: @Test
207: public void testInvokeMethodWithFailedClassCheck() throws Exception {
208: try {
209: ClassWithNoArgMethod instance = new ClassWithNoArgMethod();
210: Object invokeVoidMethod = ReflectHelper.invokeMethod(
211: instance, "method", Integer.class);
212: Assert.assertEquals(invokeVoidMethod, "hello");
213: } catch (ApplicationRuntimeException e) {
214: Assert
215: .assertEquals(
216: e.getMessage(),
217: "Unable to cast result hello of method method() of class org.strecks.util.impl.ClassWithNoArgMethod "
218: + "to return type class java.lang.Integer");
219: }
220: }
221:
222: @Test
223: public void testInvokeNonexistentMethod() throws Exception {
224: try {
225: ClassWithNoArgMethod instance = new ClassWithNoArgMethod();
226: Object invokeVoidMethod = ReflectHelper.invokeMethod(
227: instance, "nonexistent", String.class);
228: Assert.assertEquals(invokeVoidMethod, "hello");
229: } catch (ApplicationRuntimeException e) {
230: Assert
231: .assertEquals(e.getMessage(),
232: "No method nonexistent() of class org.strecks.util.impl.ClassWithNoArgMethod");
233: }
234: }
235:
236: @Test
237: public void testInvokePrivateMethod() throws Exception {
238: try {
239: ClassWithPrivateMethod instance = new ClassWithPrivateMethod();
240: Object invokeVoidMethod = ReflectHelper.invokeMethod(
241: instance, "method", String.class);
242: Assert.assertEquals(invokeVoidMethod, "hello");
243: } catch (ApplicationRuntimeException e) {
244: Assert
245: .assertEquals(e.getMessage(),
246: "No method method() of class org.strecks.util.impl.ClassWithPrivateMethod");
247: }
248: }
249:
250: @Test
251: public void testNewInstance() {
252: assert null != ReflectHelper.createInstance(
253: "org.strecks.util.impl.MyClass", MyClass.class);
254: assert null != ReflectHelper.createInstance(
255: "org.strecks.util.impl.MyClass$PublicClass",
256: PublicClass.class);
257: }
258:
259: @Test
260: public void testClassNotFound() {
261: try {
262: ReflectHelper.createInstance(
263: "org.strecks.util.impl.NoClassHere", null);
264: Assert.fail();
265: } catch (ApplicationRuntimeException e) {
266: Assert
267: .assertEquals(
268: e.getMessage(),
269: "Unable to create new instance of org.strecks.util.impl.NoClassHere as class cannot be located");
270: }
271: }
272:
273: @Test
274: public void testPrivateClass() {
275: try {
276: assert null != ReflectHelper.createInstance(
277: "org.strecks.util.impl.MyClass$PrivateClass", null);
278: Assert.fail();
279: } catch (ApplicationRuntimeException e) {
280: Assert
281: .assertEquals(
282: e.getMessage(),
283: "Illegal access in attempting to create instance of class org.strecks.util.impl.MyClass$PrivateClass");
284: }
285: }
286:
287: @Test
288: public void testAbstractClass() {
289: try {
290: assert null != ReflectHelper.createInstance(
291: "org.strecks.util.impl.MyClass$AbstractClass",
292: AbstractClass.class);
293: Assert.fail();
294: } catch (ApplicationRuntimeException e) {
295: Assert
296: .assertEquals(
297: e.getMessage(),
298: "Unable to create new instance of class org.strecks.util.impl.MyClass$AbstractClass as class cannot be instantiated");
299: }
300: }
301:
302: @Test
303: public void testDuffType() {
304: try {
305: ReflectHelper.createInstance(
306: "org.strecks.util.impl.MyClass", Integer.class);
307: Assert.fail();
308: } catch (ApplicationRuntimeException e) {
309: Assert
310: .assertEquals(
311: e.getMessage(),
312: "Class org.strecks.util.impl.MyClass was instantiated but was not an instance of the type class java.lang.Integer");
313: }
314: }
315:
316: @Test
317: public void testCheckGenericType1() {
318: assert ReflectHelper.checkGenericType(GenericClass.class,
319: Comparable.class, Integer.class);
320: assert !ReflectHelper.checkGenericType(GenericClass.class,
321: Comparable.class, String.class);
322: assert ReflectHelper.checkGenericType(GenericClass.class,
323: List.class, String.class);
324:
325: // check a class which has no generic interfaces
326: assert ReflectHelper.checkGenericType(String.class, List.class,
327: String.class);
328: }
329:
330: @Test
331: public void testGenericType() {
332: assert Integer.class == ReflectHelper.getGenericType(
333: GenericClass.class, Comparable.class);
334:
335: // check a class which does not have a generic implementation of the given interfaces
336: assert null == ReflectHelper.getGenericType(GenericClass.class,
337: List.class);
338:
339: // check a class which has no generic interfaces
340: assert null == ReflectHelper.getGenericType(String.class,
341: List.class);
342:
343: assert String.class == ReflectHelper.getGenericType(
344: DatePatternConverter.class, Converter.class);
345:
346: // this one goes down a hierarchy 3 deep to find the generic type
347: assert Integer.class == ReflectHelper.getGenericType(
348: ComparableIntegerSubclass.class, Comparable.class);
349:
350: }
351:
352: @Test
353: public void testGenericTypes() {
354:
355: Type[] genericTypes = ReflectHelper.getGenericTypes(
356: MapContainingList.class, Map.class);
357: assert genericTypes[0].equals(String.class);
358: assert genericTypes[1] instanceof ParameterizedType;
359:
360: Assert.assertEquals(ReflectHelper
361: .getTypeDescription(genericTypes[0]),
362: "class java.lang.String");
363: Assert
364: .assertEquals(ReflectHelper
365: .getTypeDescription(genericTypes[1]),
366: "parameterized interface java.util.List (class java.lang.String)");
367:
368: genericTypes = ReflectHelper.getGenericTypes(
369: ArrayConverter.class, Converter.class);
370: assert genericTypes[0] instanceof GenericArrayType;
371: assert genericTypes[1] instanceof ParameterizedType;
372:
373: Assert.assertEquals(ReflectHelper
374: .getTypeDescription(genericTypes[0]),
375: "array of class java.lang.String");
376: Assert
377: .assertEquals(ReflectHelper
378: .getTypeDescription(genericTypes[1]),
379: "parameterized interface java.util.List (class java.lang.Integer)");
380:
381: genericTypes = ReflectHelper.getGenericTypes(HashMap.class,
382: Map.class);
383: assert genericTypes[0] instanceof TypeVariable;
384: assert genericTypes[1] instanceof TypeVariable;
385:
386: Assert
387: .assertEquals(ReflectHelper
388: .getTypeDescription(genericTypes[0]),
389: "type variable named K bounded by (class java.lang.Object)");
390: Assert
391: .assertEquals(ReflectHelper
392: .getTypeDescription(genericTypes[1]),
393: "type variable named V bounded by (class java.lang.Object)");
394:
395: }
396:
397: @Test
398: public void testWildCardType() throws SecurityException,
399: NoSuchMethodException {
400:
401: Method method = getWildcardMethod("setUpperValue");
402:
403: Assert
404: .assertEquals(
405: ReflectHelper.getTypeDescription(method
406: .getGenericParameterTypes()[0]),
407: "parameterized interface java.util.Collection (wildcard generic type with upper bound (interface java.util.List))");
408:
409: method = getWildcardMethod("setLowerValue");
410:
411: Assert
412: .assertEquals(
413: ReflectHelper.getTypeDescription(method
414: .getGenericParameterTypes()[0]),
415: "parameterized interface java.util.Collection (wildcard generic type with upper bound (class java.lang.Object) and lower bound (class java.util.ArrayList))");
416:
417: }
418:
419: private Method getWildcardMethod(String methodName) {
420: Method[] methods = ClassWithWildcardTypes.class.getMethods();
421:
422: Method method = null;
423:
424: for (int i = 0; i < methods.length; i++) {
425: String name = methods[i].getName();
426: if (name.startsWith(methodName)) {
427: method = methods[i];
428: break;
429: }
430: }
431: Assert.assertNotNull(method);
432: return method;
433: }
434:
435: @Test
436: public void testGetBeanPropertyType() {
437: JavaBean bean = new JavaBean();
438: Class<?> beanPropertyType = ReflectHelper.getBeanPropertyType(
439: bean, "booleanProperty");
440: Assert.assertEquals(beanPropertyType, Boolean.TYPE);
441: }
442:
443: @Test
444: public void testUnknownGetBeanPropertyType() {
445: JavaBean bean = new JavaBean();
446: try {
447: ReflectHelper.getBeanPropertyType(bean, "unknownProperty");
448: } catch (ApplicationRuntimeException e) {
449: Assert
450: .assertEquals(
451: e.getMessage(),
452: "Unable to read property descriptor for bean org.strecks.util.impl.JavaBean, property unknownProperty");
453: }
454: }
455:
456: }
|