1 16 package com.ibatis.common.beans; 17 18 import java.lang.reflect.Method ; 19 import java.util.Map ; 20 import java.util.StringTokenizer ; 21 22 33 public class ComplexBeanProbe extends BaseProbe { 34 35 private static final Object [] NO_ARGUMENTS = new Object [0]; 36 37 protected ComplexBeanProbe() { 38 } 39 40 46 public String [] getReadablePropertyNames(Object object) { 47 return ClassInfo.getInstance(object.getClass()).getReadablePropertyNames(); 48 } 49 50 56 public String [] getWriteablePropertyNames(Object object) { 57 return ClassInfo.getInstance(object.getClass()).getReadablePropertyNames(); 58 } 59 60 68 public Class getPropertyTypeForSetter(Object object, String name) { 69 Class type = object.getClass(); 70 71 if (object instanceof Class ) { 72 type = getClassPropertyTypeForSetter((Class ) object, name); 73 } else if (object instanceof Map ) { 74 Map map = (Map ) object; 75 Object value = map.get(name); 76 if (value == null) { 77 type = Object .class; 78 } else { 79 type = value.getClass(); 80 } 81 } else { 82 if (name.indexOf('.') > -1) { 83 StringTokenizer parser = new StringTokenizer (name, "."); 84 while (parser.hasMoreTokens()) { 85 name = parser.nextToken(); 86 type = ClassInfo.getInstance(type).getSetterType(name); 87 } 88 } else { 89 type = ClassInfo.getInstance(type).getSetterType(name); 90 } 91 } 92 93 return type; 94 } 95 96 103 public Class getPropertyTypeForGetter(Object object, String name) { 104 Class type = object.getClass(); 105 106 if (object instanceof Class ) { 107 type = getClassPropertyTypeForGetter((Class ) object, name); 108 } else if (object instanceof Map ) { 109 Map map = (Map ) object; 110 Object value = map.get(name); 111 if (value == null) { 112 type = Object .class; 113 } else { 114 type = value.getClass(); 115 } 116 } else { 117 if (name.indexOf('.') > -1) { 118 StringTokenizer parser = new StringTokenizer (name, "."); 119 while (parser.hasMoreTokens()) { 120 name = parser.nextToken(); 121 type = ClassInfo.getInstance(type).getGetterType(name); 122 } 123 } else { 124 type = ClassInfo.getInstance(type).getGetterType(name); 125 } 126 } 127 128 return type; 129 } 130 131 138 private Class getClassPropertyTypeForGetter(Class type, String name) { 139 140 if (name.indexOf('.') > -1) { 141 StringTokenizer parser = new StringTokenizer (name, "."); 142 while (parser.hasMoreTokens()) { 143 name = parser.nextToken(); 144 type = ClassInfo.getInstance(type).getGetterType(name); 145 } 146 } else { 147 type = ClassInfo.getInstance(type).getGetterType(name); 148 } 149 150 return type; 151 } 152 153 161 private Class getClassPropertyTypeForSetter(Class type, String name) { 162 163 if (name.indexOf('.') > -1) { 164 StringTokenizer parser = new StringTokenizer (name, "."); 165 while (parser.hasMoreTokens()) { 166 name = parser.nextToken(); 167 type = ClassInfo.getInstance(type).getSetterType(name); 168 } 169 } else { 170 type = ClassInfo.getInstance(type).getSetterType(name); 171 } 172 173 return type; 174 } 175 176 183 public Object getObject(Object object, String name) { 184 if (name.indexOf('.') > -1) { 185 StringTokenizer parser = new StringTokenizer (name, "."); 186 Object value = object; 187 while (parser.hasMoreTokens()) { 188 value = getProperty(value, parser.nextToken()); 189 190 if (value == null) { 191 break; 192 } 193 194 } 195 return value; 196 } else { 197 return getProperty(object, name); 198 } 199 } 200 201 208 public void setObject(Object object, String name, Object value) { 209 if (name.indexOf('.') > -1) { 210 StringTokenizer parser = new StringTokenizer (name, "."); 211 String property = parser.nextToken(); 212 Object child = object; 213 while (parser.hasMoreTokens()) { 214 Class type = getPropertyTypeForSetter(child, property); 215 Object parent = child; 216 child = getProperty(parent, property); 217 if (child == null) { 218 if (value == null) { 219 return; } else { 221 try { 222 child = type.newInstance(); 223 setObject(parent, property, child); 224 } catch (Exception e) { 225 throw new ProbeException("Cannot set value of property '" + name + "' because '" + property + "' is null and cannot be instantiated on instance of " + type.getName() + ". Cause:" + e.toString(), e); 226 } 227 } 228 } 229 property = parser.nextToken(); 230 } 231 setProperty(child, property, value); 232 } else { 233 setProperty(object, name, value); 234 } 235 } 236 237 238 245 public boolean hasWritableProperty(Object object, String propertyName) { 246 boolean hasProperty = false; 247 if (object instanceof Map ) { 248 hasProperty = true; } else { 250 if (propertyName.indexOf('.') > -1) { 251 StringTokenizer parser = new StringTokenizer (propertyName, "."); 252 Class type = object.getClass(); 253 while (parser.hasMoreTokens()) { 254 propertyName = parser.nextToken(); 255 type = ClassInfo.getInstance(type).getGetterType(propertyName); 256 hasProperty = ClassInfo.getInstance(type).hasWritableProperty(propertyName); 257 } 258 } else { 259 hasProperty = ClassInfo.getInstance(object.getClass()).hasWritableProperty(propertyName); 260 } 261 } 262 return hasProperty; 263 } 264 265 272 public boolean hasReadableProperty(Object object, String propertyName) { 273 boolean hasProperty = false; 274 if (object instanceof Map ) { 275 hasProperty = true; } else { 277 if (propertyName.indexOf('.') > -1) { 278 StringTokenizer parser = new StringTokenizer (propertyName, "."); 279 Class type = object.getClass(); 280 while (parser.hasMoreTokens()) { 281 propertyName = parser.nextToken(); 282 type = ClassInfo.getInstance(type).getGetterType(propertyName); 283 hasProperty = ClassInfo.getInstance(type).hasReadableProperty(propertyName); 284 } 285 } else { 286 hasProperty = ClassInfo.getInstance(object.getClass()).hasReadableProperty(propertyName); 287 } 288 } 289 return hasProperty; 290 } 291 292 protected Object getProperty(Object object, String name) { 293 ClassInfo classCache = ClassInfo.getInstance(object.getClass()); 294 try { 295 Object value = null; 296 if (name.indexOf("[") > -1) { 297 value = getIndexedProperty(object, name); 298 } else { 299 if (object instanceof Map ) { 300 value = ((Map ) object).get(name); 301 } else { 302 Method method = classCache.getGetter(name); 303 if (method == null) { 304 throw new NoSuchMethodException ("No GET method for property " + name + " on instance of " + object.getClass().getName()); 305 } 306 try { 307 value = method.invoke(object, NO_ARGUMENTS); 308 } catch (Throwable t) { 309 throw ClassInfo.unwrapThrowable(t); 310 } 311 } 312 } 313 return value; 314 } catch (ProbeException e) { 315 throw e; 316 } catch (Throwable t) { 317 if (object == null) { 318 throw new ProbeException("Could not get property '" + name + "' from null reference. Cause: " + t.toString(), t); 319 } else { 320 throw new ProbeException("Could not get property '" + name + "' from " + object.getClass().getName() + ". Cause: " + t.toString(), t); 321 } 322 } 323 } 324 325 protected void setProperty(Object object, String name, Object value) { 326 ClassInfo classCache = ClassInfo.getInstance(object.getClass()); 327 try { 328 if (name.indexOf("[") > -1) { 329 setIndexedProperty(object, name, value); 330 } else { 331 if (object instanceof Map ) { 332 ((Map ) object).put(name, value); 333 } else { 334 Method method = classCache.getSetter(name); 335 if (method == null) { 336 throw new NoSuchMethodException ("No SET method for property " + name + " on instance of " + object.getClass().getName()); 337 } 338 Object [] params = new Object [1]; 339 params[0] = value; 340 try { 341 method.invoke(object, params); 342 } catch (Throwable t) { 343 throw ClassInfo.unwrapThrowable(t); 344 } 345 } 346 } 347 } catch (ProbeException e) { 348 throw e; 349 } catch (Throwable t) { 350 if (object == null) { 351 throw new ProbeException("Could not set property '" + name + "' for null reference. Cause: " + t.toString(), t); 352 } else { 353 throw new ProbeException("Could not set property '" + name + "' for " + object.getClass().getName() + ". Cause: " + t.toString(), t); 354 } 355 } 356 } 357 358 } 359 360 361 | Popular Tags |