1 28 29 package com.caucho.es.wrapper; 30 31 import com.caucho.server.util.CauchoSystem; 32 import com.caucho.util.WeakLruCache; 33 34 import java.beans.BeanInfo ; 35 import java.beans.IntrospectionException ; 36 import java.beans.Introspector ; 37 import java.beans.MethodDescriptor ; 38 import java.beans.PropertyDescriptor ; 39 import java.lang.ref.SoftReference ; 40 import java.lang.reflect.Field ; 41 import java.lang.reflect.Method ; 42 import java.lang.reflect.Modifier ; 43 44 50 public class ESIntrospector { 51 54 static WeakLruCache<Class ,SoftReference <ESBeanInfo>> _beanMap = 55 new WeakLruCache<Class ,SoftReference <ESBeanInfo>>(256); 56 57 static Integer NULL = new Integer (0); 58 final static int METHOD = 1; 59 final static int PROPERTY = 2; 60 final static int MASK = 3; 61 62 static String []path = new String [] {"", "com.caucho.eswrap"}; 63 64 70 public static ESBeanInfo getBeanInfo(Class cl) 71 throws IntrospectionException 72 { 73 ESBeanInfo info; 74 75 SoftReference <ESBeanInfo> infoRef = _beanMap.get(cl); 76 77 info = infoRef != null ? infoRef.get() : null; 78 79 if (info != null) 80 return info; 81 82 info = new ESBeanInfo(cl); 83 84 getMethods(info, cl); 85 86 _beanMap.put(cl, new SoftReference <ESBeanInfo>(info)); 87 88 return info; 89 } 90 91 108 private static void 109 analyzeProperty(ESBeanInfo info, Class cl, ESMethodDescriptor md, 110 boolean overwrite) 111 throws IntrospectionException 112 { 113 Method method = md.getMethod(); 114 int modifiers = method.getModifiers(); 115 116 if (! Modifier.isPublic(modifiers)) 117 return; 118 119 String name = method.getName(); 120 String propName; 121 Class returnType = method.getReturnType(); 122 String returnName = returnType.getName(); 123 Class []params = md.getParameterTypes(); 124 125 if (name.equals("keys") && params.length == 0 && 126 (returnName.equals("java.util.Iterator") || 127 (returnName.equals("java.util.Enumeration")))) { 128 info.iterator = md; 129 } 130 else if (name.equals("iterator") && params.length == 0 && 131 (returnName.equals("java.util.Iterator") || 132 (returnName.equals("java.util.Enumeration")))) { 133 if (info.iterator == null) 135 info.iterator = md; 136 } 137 else if (name.startsWith("get") && ! name.equals("get")) { 138 propName = Introspector.decapitalize(name.substring(3)); 139 140 if (returnName.equals("void") && params.length < 2) { 142 return; 144 } 145 146 if (params.length == 0 && 148 (propName.endsWith("Keys") && ! propName.equals("Keys") || 149 propName.endsWith("Names") && ! propName.equals("Names")) && 150 (returnName.equals("java.util.Iterator") || 151 (returnName.equals("java.util.Enumeration")))) { 152 if (propName.endsWith("Keys")) 153 info.addNamedProp(propName.substring(0, propName.length() - 4), 154 null, null, null, md); 155 else 156 info.addNamedProp(propName.substring(0, propName.length() - 5), 157 null, null, null, md); 158 } 159 else if (params.length == 0 && 161 (propName.endsWith("Size") && ! propName.equals("Size") || 162 propName.endsWith("Length") && ! propName.equals("Length")) && 163 (returnName.equals("int"))) { 164 info.addProp(propName, null, md, null); 165 if (propName.endsWith("Size")) 166 info.addIndexedProp(propName.substring(0, propName.length() - 4), 167 null, null, md); 168 else 169 info.addIndexedProp(propName.substring(0, propName.length() - 6), 170 null, null, md); 171 } 172 else if (params.length == 0) 173 info.addProp(propName, null, md, null); 174 else if (params.length == 1 && 175 params[0].getName().equals("java.lang.String")) { 176 info.addNamedProp(propName, md, null, null, null); 177 } else if (params.length == 1 && 178 params[0].getName().equals("int")) { 179 info.addIndexedProp(propName, md, null, null); 180 } else if (params.length == 1) { 181 } 183 } else if (name.startsWith("set") && ! name.equals("set")) { 184 propName = Introspector.decapitalize(name.substring(3)); 185 186 if (params.length == 0) 187 return; 188 189 if (! returnType.getName().equals("void") && params.length < 3) { 191 return; 193 } 194 195 if (params.length == 1) 196 info.addProp(propName, null, null, md); 197 else if (params.length == 2 && 198 params[0].getName().equals("java.lang.String")) { 199 info.addNamedProp(propName, null, md, null, null); 200 } else if (params.length == 2 && 201 params[0].getName().equals("int")) { 202 info.addIndexedProp(propName, null, md, null); 203 } else if (params.length == 2) { 204 } 206 } else if (name.startsWith("remove") && ! name.equals("remove") || 207 name.startsWith("delete") && ! name.equals("remove")) { 208 propName = Introspector.decapitalize(name.substring(6)); 209 210 if (params.length == 0) 211 return; 212 213 if (! returnType.getName().equals("void") && params.length < 2) { 215 return; 217 } 218 219 if (params.length == 1 && 222 params[0].getName().equals("java.lang.String")) { 223 info.addNamedProp(propName, null, null, md, null); 224 } 225 233 } 234 } 235 236 239 static void addEcmaMethods(ESBeanInfo info, Class cl, Class wrapCl, int mask) 240 throws IntrospectionException 241 { 242 Method []methods = wrapCl.getDeclaredMethods(); 243 244 for (int i = 0; i < methods.length; i++) { 245 int modifiers = methods[i].getModifiers(); 246 247 if (! Modifier.isStatic(modifiers)) 248 continue; 249 250 ESMethodDescriptor md = info.createMethodDescriptor(methods[i], true); 251 252 if ((mask & METHOD) != 0) 253 info.addMethod(md); 254 if ((mask & PROPERTY) != 0) 255 analyzeProperty(info, cl, md, true); 256 } 257 } 258 259 266 static void addEcmaWrap(ESBeanInfo info, Class cl, int mask) 267 throws IntrospectionException 268 { 269 String name = cl.getName(); 270 int lastDot = name.lastIndexOf('.'); 271 String prefix = lastDot == -1 ? "" : name.substring(0, lastDot); 272 String tail = lastDot == -1 ? name : name.substring(lastDot + 1); 273 274 ClassLoader loader = cl.getClassLoader(); 275 276 for (int i = 0; i < path.length; i++) { 277 String testName; 278 279 if (path[i].equals("")) 280 testName = name + "EcmaWrap"; 281 else 282 testName = path[i] + "." + name + "EcmaWrap"; 283 284 try { 285 Class wrapCl = CauchoSystem.loadClass(testName, false, loader); 286 287 if (wrapCl != null) { 288 addEcmaMethods(info, cl, wrapCl, mask); 289 return; 290 } 291 } catch (ClassNotFoundException e) { 292 } 293 294 if (path[i].equals("")) 295 testName = tail + "EcmaWrap"; 296 else 297 testName = path[i] + "." + tail + "EcmaWrap"; 298 299 try { 300 Class wrapCl = CauchoSystem.loadClass(testName, false, loader); 301 302 if (wrapCl != null) { 303 addEcmaMethods(info, cl, wrapCl, mask); 304 return; 305 } 306 } catch (ClassNotFoundException e) { 307 } 308 } 309 } 310 311 319 static int getBeanInfo(ESBeanInfo info, Class cl) 320 { 321 try { 322 String name = cl.getName() + "BeanInfo"; 323 324 Class beanClass = CauchoSystem.loadClass(name, false, cl.getClassLoader()); 325 if (beanClass == null) 326 return MASK; 327 BeanInfo beanInfo = (BeanInfo ) beanClass.newInstance(); 328 329 MethodDescriptor []mds = beanInfo.getMethodDescriptors(); 330 if (mds == null) 331 return MASK; 332 333 for (int i = 0; i < mds.length; i++) { 334 Method method = mds[i].getMethod(); 335 int modifiers = method.getModifiers(); 336 337 if (! Modifier.isStatic(modifiers) && 338 ! method.getDeclaringClass().isAssignableFrom(cl)) 339 continue; 340 341 info.addMethod(mds[i], true); 342 } 343 344 return MASK & ~METHOD; 345 } catch (Exception e) { 346 return MASK; 347 } 348 } 349 350 static void getPropBeanInfo(ESBeanInfo info, Class cl) 351 { 352 try { 353 String name = cl.getName() + "BeanInfo"; 354 Class beanClass = CauchoSystem.loadClass(name, false, cl.getClassLoader()); 355 if (beanClass == null) 356 return; 357 BeanInfo beanInfo = (BeanInfo ) beanClass.newInstance(); 358 359 PropertyDescriptor []props = beanInfo.getPropertyDescriptors(); 360 361 for (int i = 0; props != null && i < props.length; i++) { 362 ESMethodDescriptor read; 363 ESMethodDescriptor write; 364 365 read = new ESMethodDescriptor(props[i].getReadMethod(), false, false); 366 write = new ESMethodDescriptor(props[i].getWriteMethod(), 367 false, false); 368 369 info.addProp(props[i].getName(), null, read, write, true); 370 } 371 } catch (Exception e) { 372 } 373 } 374 375 private static void getMethods(ESBeanInfo info, Class cl) 376 throws IntrospectionException 377 { 378 if (! cl.isPrimitive() && ! cl.isArray() && 379 cl.getName().indexOf('.') < 0) 380 info.addNonPkgClass(cl.getName()); 381 382 getPropBeanInfo(info, cl); 383 384 int mask = getBeanInfo(info, cl); 385 386 if (mask == 0) 387 return; 388 389 Class []interfaces = cl.getInterfaces(); 390 for (int i = 0; i < interfaces.length; i++) { 391 ESBeanInfo subInfo = getBeanInfo(interfaces[i]); 392 393 if ((mask & METHOD) != 0) 394 info.addMethods(subInfo); 395 if ((mask & PROPERTY) != 0) 396 info.addProps(subInfo); 397 } 398 399 Class superClass = cl.getSuperclass(); 400 if (superClass != null) { 401 ESBeanInfo subInfo = getBeanInfo(superClass); 402 403 if ((mask & METHOD) != 0) 404 info.addMethods(subInfo); 405 if ((mask & PROPERTY) != 0) 406 info.addProps(subInfo); 407 } 408 409 int modifiers = cl.getModifiers(); 410 if (Modifier.isPublic(modifiers)) { 411 Method []methods = cl.getDeclaredMethods(); 412 int len = methods == null ? 0 : methods.length; 413 for (int i = 0; i < len; i++) { 414 ESMethodDescriptor md = info.createMethodDescriptor(methods[i], false); 415 416 if ((mask & METHOD) != 0) 417 info.addMethod(md); 418 if ((mask & PROPERTY) != 0) 419 analyzeProperty(info, cl, md, false); 420 } 421 422 Field []fields = cl.getDeclaredFields(); 423 for (int i = 0; fields != null && i < fields.length; i++) { 424 info.addField(fields[i]); 425 } 426 } 427 428 addEcmaWrap(info, cl, mask); 429 } 430 } 431 | Popular Tags |