1 28 29 package com.caucho.es.wrapper; 30 31 import java.beans.IntrospectionException ; 32 import java.beans.MethodDescriptor ; 33 import java.beans.PropertyDescriptor ; 34 import java.lang.reflect.Constructor ; 35 import java.lang.reflect.Field ; 36 import java.lang.reflect.Method ; 37 import java.lang.reflect.Modifier ; 38 import java.util.ArrayList ; 39 import java.util.HashMap ; 40 import java.util.Iterator ; 41 import java.util.Map ; 42 43 46 public class ESBeanInfo { 47 static String BAD = "bad"; 48 49 Class cl; 50 HashMap <String ,ArrayList <Method >> _methodMap; 51 HashMap <String ,ArrayList <Method >> _staticMethodMap; 52 HashMap propMap; 53 ArrayList nonPkgClasses = new ArrayList (); 54 PropertyDescriptor []propertyDescriptors; 55 ESMethodDescriptor iterator; 56 57 ESBeanInfo(Class cl) 58 { 59 this.cl = cl; 60 _methodMap = new HashMap <String ,ArrayList <Method >>(); 61 _staticMethodMap = new HashMap <String ,ArrayList <Method >>(); 62 propMap = new HashMap (); 63 } 64 65 void addNonPkgClass(String name) 66 { 67 if (name.indexOf('$') >= 0) 68 return; 69 70 if (! nonPkgClasses.contains(name)) 71 nonPkgClasses.add(name); 72 } 73 74 ArrayList getNonPkgClasses() 75 { 76 return nonPkgClasses; 77 } 78 79 82 public PropertyDescriptor []getPropertyDescriptors() 83 { 84 if (propertyDescriptors == null) 85 propertyDescriptors = propMapToArray(propMap); 86 87 return propertyDescriptors; 88 } 89 90 private static PropertyDescriptor []propMapToArray(HashMap props) 91 { 92 int count = 0; 93 Iterator i = props.keySet().iterator(); 94 while (i.hasNext()) { 95 String key = (String ) i.next(); 96 Object value = props.get(key); 97 98 if (value != BAD) 99 count++; 100 } 101 102 PropertyDescriptor []descriptors = new PropertyDescriptor [count]; 103 104 count = 0; 105 i = props.keySet().iterator(); 106 while (i.hasNext()) { 107 String key = (String ) i.next(); 108 Object value = props.get(key); 109 110 if (value != BAD) { 111 descriptors[count] = (PropertyDescriptor ) value; 112 count++; 113 } 114 } 115 116 return descriptors; 117 } 118 119 void addProp(String name, Field field, 120 ESMethodDescriptor getter, 121 ESMethodDescriptor setter, 122 boolean overwrite) 123 throws IntrospectionException 124 { 125 Object value = propMap.get(name); 126 127 if (value instanceof ESPropertyDescriptor && 128 ! (value instanceof ESIndexedPropertyDescriptor) && 129 ! (value instanceof NamedPropertyDescriptor)) { 130 ESPropertyDescriptor prop = (ESPropertyDescriptor) value; 131 132 133 if (field != null) 134 prop.field = field; 135 if (getter != null) 136 prop.getter = getter; 137 if (setter != null) 138 prop.setter = setter; 139 140 propMap.put(name, prop); 141 } else if (value == null || overwrite) { 142 propMap.put(name, new ESPropertyDescriptor(name, field, getter, setter)); 143 } else { 144 propMap.put(name, BAD); 145 } 146 } 147 148 void addProp(String name, Field field, ESMethodDescriptor getter, ESMethodDescriptor setter) 149 throws IntrospectionException 150 { 151 addProp(name, field, getter, setter, false); 152 } 153 154 void addIndexedProp(String name, ESMethodDescriptor getter, ESMethodDescriptor setter, ESMethodDescriptor size, 155 boolean overwrite) 156 throws IntrospectionException 157 { 158 Object value = propMap.get(name); 159 160 if (value instanceof ESIndexedPropertyDescriptor) { 161 ESIndexedPropertyDescriptor prop = (ESIndexedPropertyDescriptor) value; 162 163 if (getter != null) 164 prop.getter = getter; 165 if (setter != null) 166 prop.setter = setter; 167 if (size != null) 168 prop.size = size; 169 170 propMap.put(name, prop); 171 } else if (value == null || overwrite) { 172 propMap.put(name, new ESIndexedPropertyDescriptor(name, getter, setter, 173 size)); 174 } else 175 propMap.put(name, BAD); 176 } 177 178 void addIndexedProp(String name, ESMethodDescriptor getter, ESMethodDescriptor setter, ESMethodDescriptor size) 179 throws IntrospectionException 180 { 181 addIndexedProp(name, getter, setter, size, false); 182 } 183 184 void addNamedProp(String name, 185 ESMethodDescriptor getter, 186 ESMethodDescriptor setter, 187 ESMethodDescriptor remover, 188 ESMethodDescriptor iterator, 189 boolean overwrite) 190 throws IntrospectionException 191 { 192 Object value = propMap.get(name); 193 194 if (value instanceof NamedPropertyDescriptor) { 195 NamedPropertyDescriptor prop = (NamedPropertyDescriptor) value; 196 197 if (getter != null) 198 prop.namedGetter = getter; 199 if (setter != null) 200 prop.namedSetter = setter; 201 if (remover != null) 202 prop.namedRemover = remover; 203 if (iterator != null) 204 prop.namedIterator = iterator; 205 } else if (value == null || overwrite) { 206 propMap.put(name, new NamedPropertyDescriptor(name, null, null, 207 getter, setter, 208 remover, iterator)); 209 } else 210 propMap.put(name, BAD); 211 } 212 213 void addNamedProp(String name, ESMethodDescriptor getter, 214 ESMethodDescriptor setter, 215 ESMethodDescriptor remover, 216 ESMethodDescriptor iterator) 217 throws IntrospectionException 218 { 219 addNamedProp(name, getter, setter, remover, iterator, false); 220 } 221 222 225 public ArrayList <Method > getMethods(String name) 226 { 227 return _methodMap.get(name); 228 } 229 230 233 public ArrayList <Method > getStaticMethods(String name) 234 { 235 return _staticMethodMap.get(name); 236 } 237 238 public ArrayList getConstructors() 239 { 240 ArrayList overload = new ArrayList (); 241 if (! Modifier.isPublic(cl.getModifiers())) 242 return overload; 243 244 if (cl.getDeclaringClass() != null && 246 ! Modifier.isStatic(cl.getModifiers())) 247 return overload; 248 249 Constructor []constructors = cl.getConstructors(); 250 for (int i = 0; i < constructors.length; i++) { 251 if (! Modifier.isPublic(constructors[i].getModifiers())) 252 continue; 253 254 if (Modifier.isPublic(constructors[i].getModifiers())) 255 addConstructor(overload, constructors[i]); 256 } 257 258 return overload; 259 } 260 261 private void addConstructor(ArrayList overload, 262 Constructor constructor) 263 { 264 int modifiers = constructor.getModifiers(); 265 266 if (! Modifier.isPublic(modifiers)) 267 return; 268 269 Class []params = constructor.getParameterTypes(); 270 for (int i = 0; i < params.length; i++) { 271 if (! Modifier.isPublic(params[i].getModifiers())) 272 return; 273 if (! params[i].isPrimitive() && ! params[i].isArray() && 274 params[i].getName().indexOf('.') < 0) 275 addNonPkgClass(params[i].getName()); 276 } 277 int length = params.length; 278 279 Object oldConstructor; 280 if (length < overload.size() && 281 (oldConstructor = overload.get(length)) != null) { 282 overload.set(length, BAD); 283 } 284 else { 285 while (overload.size() <= length) 286 overload.add(null); 287 overload.set(length, constructor); 288 } 289 } 290 291 294 ESMethodDescriptor createMethodDescriptor(Method method, boolean overwrite) 295 throws IntrospectionException 296 { 297 boolean staticVirtual = isStaticVirtual(cl, method); 298 299 return new ESMethodDescriptor(method, overwrite, staticVirtual); 300 } 301 302 310 private static boolean isStaticVirtual(Class cl, Method method) 311 { 312 int modifiers = method.getModifiers(); 313 314 if (! Modifier.isStatic(modifiers)) 315 return false; 316 317 if (method.getName().equals("<init>")) 318 return false; 319 320 if (! method.getDeclaringClass().getName().endsWith("EcmaWrap")) 321 return false; 322 323 Class []params = method.getParameterTypes(); 324 325 boolean result = params.length > 0 && params[0].equals(cl); 326 327 return result; 328 } 329 330 336 void addMethod(MethodDescriptor oldMd, boolean overwrite) 337 throws IntrospectionException 338 { 339 ESMethodDescriptor md = createMethodDescriptor(oldMd.getMethod(), 340 overwrite); 341 md.setName(oldMd.getName()); 342 addMethod(_methodMap, md, false); 343 addMethod(_staticMethodMap, md, true); 344 } 345 346 351 void addMethod(ESMethodDescriptor md) 352 throws IntrospectionException 353 { 354 addMethod(_methodMap, md, false); 355 addMethod(_staticMethodMap, md, true); 356 } 357 358 void addMethods(ESBeanInfo info) 359 throws IntrospectionException 360 { 361 if (info.iterator != null) { 362 iterator = info.iterator; 363 } 364 addMap(_methodMap, info._methodMap, false); 365 addMap(_staticMethodMap, info._staticMethodMap, true); 366 } 367 368 371 private void addMap(HashMap newMap, HashMap oldMap, boolean isStatic) 372 { 373 Iterator i = oldMap.entrySet().iterator(); 374 375 while (i.hasNext()) { 376 Map.Entry entry = (Map.Entry ) i.next(); 377 ArrayList overload = (ArrayList ) entry.getValue(); 378 379 for (int j = 0; j < overload.size(); j++) { 380 ESMethodDescriptor []mds = (ESMethodDescriptor []) overload.get(j); 381 382 if (mds != null) { 383 for (int k = 0; k < mds.length; k++) 384 addMethod(newMap, mds[k], isStatic); 385 } 386 } 387 } 388 } 389 390 397 private void addMethod(HashMap map, 398 ESMethodDescriptor md, boolean isStatic) 399 { 400 Method method = md.getMethod(); 401 int modifiers = method.getModifiers(); 402 boolean staticVirtual = md.isStaticVirtual(); 403 boolean overwrite = md.isOverwrite(); 404 405 if (! Modifier.isPublic(modifiers)) 406 return; 407 if (isStatic && ! md.isStatic()) 408 return; 409 410 Class []params = md.getParameterTypes(); 411 for (int i = 0; i < params.length; i++) { 412 if (! Modifier.isPublic(params[i].getModifiers())) 413 return; 414 if (! params[i].isPrimitive() && ! params[i].isArray() && 415 params[i].getName().indexOf('.') < 0) 416 addNonPkgClass(params[i].getName()); 417 } 418 419 ArrayList overload = (ArrayList ) map.get(md.getName()); 420 if (overload == null) { 421 overload = new ArrayList (); 422 map.put(md.getName(), overload); 423 } 424 425 int length = params.length; 426 427 if (length >= overload.size()) { 428 while (overload.size() <= length) 429 overload.add(null); 430 } 431 432 ESMethodDescriptor []oldMethods; 433 oldMethods = (ESMethodDescriptor []) overload.get(length); 434 435 if (oldMethods == null) { 436 overload.set(length, new ESMethodDescriptor[] { md }); 437 return; 438 } 439 440 for (int i = 0; i < oldMethods.length; i++) { 441 ESMethodDescriptor testMd = oldMethods[i]; 442 443 if (testMd.overwrites(md)) 444 return; 445 else if (md.overwrites(testMd)) { 446 oldMethods[i] = md; 447 return; 448 } 449 450 Class []oldParams = testMd.getParameterTypes(); 451 452 int j = 0; 453 for (; j < length; j++) { 454 if (! params[j].equals(oldParams[j])) 455 break; 456 } 457 458 if (j == length && md.isOverwrite()) { 460 oldMethods[i] = md; 461 return; 462 } else if (j == length) { 463 return; 464 } 465 } 466 467 ESMethodDescriptor []newMethods; 468 newMethods = new ESMethodDescriptor[oldMethods.length + 1]; 469 System.arraycopy(oldMethods, 0, newMethods, 0, oldMethods.length); 470 newMethods[oldMethods.length] = md; 471 overload.set(length, newMethods); 472 } 473 474 private void addPropMap(HashMap oldMap) 475 throws IntrospectionException 476 { 477 Iterator i = oldMap.entrySet().iterator(); 478 479 while (i.hasNext()) { 480 Map.Entry entry = (Map.Entry ) i.next(); 481 Object value = entry.getValue(); 482 483 if (value == BAD) { 484 continue; 486 } 487 488 if (value instanceof NamedPropertyDescriptor) { 489 NamedPropertyDescriptor pd = (NamedPropertyDescriptor) value; 490 491 addNamedProp(pd.getName(), pd.namedGetter, pd.namedSetter, 492 pd.namedRemover, pd.namedIterator); 493 } else if (value instanceof ESIndexedPropertyDescriptor) { 494 ESIndexedPropertyDescriptor pd = (ESIndexedPropertyDescriptor) value; 495 496 addIndexedProp(pd.getName(), pd.getESReadMethod(), 497 pd.getESWriteMethod(), pd.getESSizeMethod()); 498 } else if (value instanceof ESPropertyDescriptor) { 499 ESPropertyDescriptor pd = (ESPropertyDescriptor) value; 500 501 addProp(pd.getName(), pd.field, pd.getter, pd.setter); 502 } 503 } 505 } 506 507 void addField(Field field) 508 throws IntrospectionException 509 { 510 int modifiers = field.getModifiers(); 511 if (! Modifier.isPublic(modifiers)) 512 return; 513 514 addProp(field.getName(), field, null, null); 515 } 516 517 void addProps(ESBeanInfo info) 518 throws IntrospectionException 519 { 520 addPropMap(info.propMap); 521 } 522 } 523 | Popular Tags |