001 package org.springframework.richclient.widget.table; 002 003 import java.lang.reflect.Method; 004 005 import org.apache.commons.beanutils.MethodUtils; 006 007 /** 008 * A number of helper classes to retrieve getter and setter methods. 009 * 010 * @author Jan Hoskens 011 * @since 0.5.0 012 */ 013 public class ClassUtils 014 { 015 016 /** 017 * No instantiation possible. 018 */ 019 private ClassUtils() 020 { 021 } 022 023 /** 024 * Lookup the getter method for the given property. This can be a getXXX() or a isXXX() method. 025 * 026 * @param clazz 027 * type which contains the property. 028 * @param propertyName 029 * name of the property. 030 * @return a Method with read-access for the property. 031 */ 032 public static Method getReadMethod(Class<?> clazz, String propertyName) throws NoSuchMethodError 033 { 034 String propertyNameCapitalized = capitalize(propertyName); 035 try 036 { 037 return clazz.getMethod("get" + propertyNameCapitalized); 038 } 039 catch (Exception e) 040 { 041 try 042 { 043 return clazz.getMethod("is" + propertyNameCapitalized); 044 } 045 catch (Exception e1) 046 { 047 throw new NoSuchMethodError("Could not find getter (getXX or isXXX) for property: " 048 + propertyName); 049 } 050 } 051 } 052 053 /** 054 * Returns the type of the property checking if it actually does return something and wrapping primitives 055 * if needed. 056 * 057 * @param getter 058 * the method to access the property. 059 * @return the type of the property. 060 * @throws IllegalArgumentException 061 * if the method has a {@link Void} return type. 062 */ 063 public static Class<?> getTypeForProperty(Method getter) 064 { 065 Class<?> returnType = getter.getReturnType(); 066 if (returnType.equals(Void.TYPE)) 067 throw new IllegalArgumentException("Getter " + getter.toString() + " does not have a returntype."); 068 else if (returnType.isPrimitive()) 069 return MethodUtils.getPrimitiveWrapper(returnType); 070 return returnType; 071 } 072 073 /** 074 * Lookup the setter method for the given property. 075 * 076 * @param clazz 077 * type which contains the property. 078 * @param propertyName 079 * name of the property. 080 * @param propertyType 081 * type of the property. 082 * @return a Method with write-access for the property. 083 */ 084 public static final Method getWriteMethod(Class<?> clazz, String propertyName, Class<?> propertyType) 085 { 086 String propertyNameCapitalized = capitalize(propertyName); 087 try 088 { 089 return clazz.getMethod("set" + propertyNameCapitalized, new Class[]{propertyType}); 090 } 091 catch (Exception e) 092 { 093 return null; 094 } 095 } 096 097 /** 098 * Small helper method to capitalize the first character of the given string. 099 * 100 * @param s 101 * string to capitalize 102 * @return a string starting with a capital character. 103 */ 104 public static String capitalize(String s) 105 { 106 if (s == null || s.length() == 0) 107 { 108 return s; 109 } 110 char chars[] = s.toCharArray(); 111 chars[0] = Character.toUpperCase(chars[0]); 112 return new String(chars); 113 } 114 115 /** 116 * Create an {@link Accessor} for the given property. A property may be nested using the dot character. 117 * 118 * @param clazz 119 * the type containing the property. 120 * @param propertyName 121 * the name of the property. 122 * @return an Accessor for the property. 123 */ 124 public static Accessor getAccessorForProperty(final Class<?> clazz, final String propertyName) 125 { 126 int splitPoint = propertyName.indexOf('.'); 127 if (splitPoint > 0) 128 { 129 String firstPart = propertyName.substring(0, splitPoint); 130 String secondPart = propertyName.substring(splitPoint + 1); 131 return new NestedAccessor(clazz, firstPart, secondPart); 132 } 133 return new SimpleAccessor(clazz, propertyName); 134 } 135 136 /** 137 * Create a {@link Writer} for the given property. A property may be nested using the dot character. 138 * 139 * @param clazz 140 * the type containing the property. 141 * @param propertyName 142 * the name of the property. 143 * @return a Writer for the property. 144 */ 145 public static Writer getWriterForProperty(final Class<?> beanClass, final String propertyName) 146 { 147 int splitPoint = propertyName.indexOf('.'); 148 if (splitPoint > 0) 149 { 150 String firstPart = propertyName.substring(0, splitPoint); 151 String secondPart = propertyName.substring(splitPoint + 1); 152 return new NestedWriter(beanClass, firstPart, secondPart); 153 } 154 return new SimpleWriter(beanClass, propertyName); 155 } 156 }