1 16 package com.ibatis.common.beans; 17 18 import java.lang.reflect.InvocationTargetException ; 19 import java.lang.reflect.Method ; 20 import java.lang.reflect.UndeclaredThrowableException ; 21 import java.math.BigDecimal ; 22 import java.math.BigInteger ; 23 import java.util.*; 24 25 29 public class ClassInfo { 30 31 private static final String [] EMPTY_STRING_ARRAY = new String [0]; 32 private static final Set SIMPLE_TYPE_SET = new HashSet(); 33 private static final Map CLASS_INFO_MAP = Collections.synchronizedMap(new HashMap()); 34 35 private String className; 36 private String [] readablePropertyNames = EMPTY_STRING_ARRAY; 37 private String [] writeablePropertyNames = EMPTY_STRING_ARRAY; 38 private HashMap setMethods = new HashMap(); 39 private HashMap getMethods = new HashMap(); 40 private HashMap setTypes = new HashMap(); 41 private HashMap getTypes = new HashMap(); 42 43 static { 44 SIMPLE_TYPE_SET.add(String .class); 45 SIMPLE_TYPE_SET.add(Byte .class); 46 SIMPLE_TYPE_SET.add(Short .class); 47 SIMPLE_TYPE_SET.add(Character .class); 48 SIMPLE_TYPE_SET.add(Integer .class); 49 SIMPLE_TYPE_SET.add(Long .class); 50 SIMPLE_TYPE_SET.add(Float .class); 51 SIMPLE_TYPE_SET.add(Double .class); 52 SIMPLE_TYPE_SET.add(Boolean .class); 53 SIMPLE_TYPE_SET.add(Date.class); 54 SIMPLE_TYPE_SET.add(Class .class); 55 SIMPLE_TYPE_SET.add(BigInteger .class); 56 SIMPLE_TYPE_SET.add(BigDecimal .class); 57 58 SIMPLE_TYPE_SET.add(Collection.class); 59 SIMPLE_TYPE_SET.add(Set.class); 60 SIMPLE_TYPE_SET.add(Map.class); 61 SIMPLE_TYPE_SET.add(List.class); 62 SIMPLE_TYPE_SET.add(HashMap.class); 63 SIMPLE_TYPE_SET.add(TreeMap.class); 64 SIMPLE_TYPE_SET.add(ArrayList.class); 65 SIMPLE_TYPE_SET.add(LinkedList.class); 66 SIMPLE_TYPE_SET.add(HashSet.class); 67 SIMPLE_TYPE_SET.add(TreeSet.class); 68 SIMPLE_TYPE_SET.add(Vector.class); 69 SIMPLE_TYPE_SET.add(Hashtable.class); 70 SIMPLE_TYPE_SET.add(Enumeration.class); 71 } 72 73 private ClassInfo(Class clazz) { 74 className = clazz.getName(); 75 addMethods(clazz); 76 Class superClass = clazz.getSuperclass(); 77 while (superClass != null) { 78 addMethods(superClass); 79 superClass = superClass.getSuperclass(); 80 } 81 readablePropertyNames = (String []) getMethods.keySet().toArray(new String [getMethods.keySet().size()]); 82 writeablePropertyNames = (String []) setMethods.keySet().toArray(new String [setMethods.keySet().size()]); 83 } 84 85 private void addMethods(Class cls) { 86 Method [] methods = cls.getMethods(); 87 for (int i = 0; i < methods.length; i++) { 88 String name = methods[i].getName(); 89 if (name.startsWith("set") && name.length() > 3) { 90 if (methods[i].getParameterTypes().length == 1) { 91 name = dropCase(name); 92 setMethods.put(name, methods[i]); 93 setTypes.put(name, methods[i].getParameterTypes()[0]); 94 } 95 } else if (name.startsWith("get") && name.length() > 3) { 96 if (methods[i].getParameterTypes().length == 0) { 97 name = dropCase(name); 98 getMethods.put(name, methods[i]); 99 getTypes.put(name, methods[i].getReturnType()); 100 } 101 } else if (name.startsWith("is") && name.length() > 2) { 102 if (methods[i].getParameterTypes().length == 0) { 103 name = dropCase(name); 104 getMethods.put(name, methods[i]); 105 getTypes.put(name, methods[i].getReturnType()); 106 } 107 } 108 name = null; 109 } 110 } 111 112 private static String dropCase(String name) { 113 if (name.startsWith("is")) { 114 name = name.substring(2); 115 } else if (name.startsWith("get") || name.startsWith("set")) { 116 name = name.substring(3); 117 } else { 118 throw new ProbeException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'."); 119 } 120 121 if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) { 122 name = name.substring(0, 1).toLowerCase(Locale.US) + name.substring(1); 123 } 124 125 return name; 126 } 127 128 133 public String getClassName() { 134 return className; 135 } 136 137 143 public Method getSetter(String propertyName) { 144 Method method = (Method ) setMethods.get(propertyName); 145 if (method == null) { 146 throw new ProbeException("There is no WRITEABLE property named '" + propertyName + "' in class '" + className + "'"); 147 } 148 return method; 149 } 150 151 157 public Method getGetter(String propertyName) { 158 Method method = (Method ) getMethods.get(propertyName); 159 if (method == null) { 160 throw new ProbeException("There is no READABLE property named '" + propertyName + "' in class '" + className + "'"); 161 } 162 return method; 163 } 164 165 171 public Class getSetterType(String propertyName) { 172 Class clazz = (Class ) setTypes.get(propertyName); 173 if (clazz == null) { 174 throw new ProbeException("There is no WRITEABLE property named '" + propertyName + "' in class '" + className + "'"); 175 } 176 return clazz; 177 } 178 179 185 public Class getGetterType(String propertyName) { 186 Class clazz = (Class ) getTypes.get(propertyName); 187 if (clazz == null) { 188 throw new ProbeException("There is no READABLE property named '" + propertyName + "' in class '" + className + "'"); 189 } 190 return clazz; 191 } 192 193 198 public String [] getReadablePropertyNames() { 199 return readablePropertyNames; 200 } 201 202 207 public String [] getWriteablePropertyNames() { 208 return writeablePropertyNames; 209 } 210 211 217 public boolean hasWritableProperty(String propertyName) { 218 return setMethods.keySet().contains(propertyName); 219 } 220 221 227 public boolean hasReadableProperty(String propertyName) { 228 return getMethods.keySet().contains(propertyName); 229 } 230 231 237 public static boolean isKnownType(Class clazz) { 238 if (SIMPLE_TYPE_SET.contains(clazz)) { 239 return true; 240 } else if (Collection.class.isAssignableFrom(clazz)) { 241 return true; 242 } else if (Map.class.isAssignableFrom(clazz)) { 243 return true; 244 } else if (List.class.isAssignableFrom(clazz)) { 245 return true; 246 } else if (Set.class.isAssignableFrom(clazz)) { 247 return true; 248 } else if (Iterator.class.isAssignableFrom(clazz)) { 249 return true; 250 } else { 251 return false; 252 } 253 } 254 255 261 public static ClassInfo getInstance(Class clazz) { 262 synchronized (clazz) { 263 ClassInfo cache = (ClassInfo) CLASS_INFO_MAP.get(clazz); 264 if (cache == null) { 265 cache = new ClassInfo(clazz); 266 CLASS_INFO_MAP.put(clazz, cache); 267 } 268 return cache; 269 } 270 } 271 272 278 public static Throwable unwrapThrowable(Throwable t) { 279 Throwable t2 = t; 280 while (true) { 281 if (t2 instanceof InvocationTargetException ) { 282 t2 = ((InvocationTargetException ) t).getTargetException(); 283 } else if (t instanceof UndeclaredThrowableException ) { 284 t2 = ((UndeclaredThrowableException ) t).getUndeclaredThrowable(); 285 } else { 286 return t2; 287 } 288 } 289 } 290 291 292 } 293 294 295 296 | Popular Tags |