1 29 30 package com.caucho.config.j2ee; 31 32 import com.caucho.config.BuilderProgram; 33 import com.caucho.config.ConfigException; 34 import com.caucho.util.L10N; 35 import com.caucho.util.Log; 36 37 import javax.annotation.Resource; 38 import javax.annotation.Resources; 39 import javax.ejb.EJB ; 40 import javax.naming.InitialContext ; 41 import javax.naming.NameClassPair ; 42 import javax.naming.NamingEnumeration ; 43 import javax.persistence.PersistenceContext; 44 import javax.persistence.PersistenceUnit; 45 import javax.transaction.UserTransaction ; 46 import javax.xml.ws.Service; 47 import javax.xml.ws.WebServiceRef; 48 import java.beans.Introspector ; 49 import java.lang.reflect.AccessibleObject ; 50 import java.lang.reflect.Field ; 51 import java.lang.reflect.Method ; 52 import java.util.ArrayList ; 53 import java.util.logging.Level ; 54 import java.util.logging.Logger ; 55 56 59 public class InjectIntrospector { 60 private static final L10N L = new L10N(InjectIntrospector.class); 61 private static final Logger log = Log.open(InjectIntrospector.class); 62 63 66 public static void configure(Object obj) 67 throws Throwable 68 { 69 if (obj != null) { 70 for (BuilderProgram program : introspect(obj.getClass())) { 71 program.configure(obj); 72 } 73 } 74 } 75 76 79 public static InjectProgram introspectProgram(Class type) 80 throws ConfigException 81 { 82 return new InjectProgram(introspect(type)); 83 } 84 85 88 public static ArrayList <BuilderProgram> introspectStatic(Class type) 89 throws ConfigException 90 { 91 return introspect(type); 92 } 93 94 97 public static ArrayList <BuilderProgram> introspect(Class type) 98 throws ConfigException 99 { 100 ArrayList <BuilderProgram> initList = new ArrayList <BuilderProgram>(); 101 102 try { 103 introspectImpl(initList, type); 104 } catch (ClassNotFoundException e) { 105 } catch (Error e) { 106 } 107 108 return initList; 109 } 110 111 private static void introspectImpl(ArrayList <BuilderProgram> initList, 112 Class type) 113 throws ConfigException, ClassNotFoundException 114 { 115 if (type == null || type.equals(Object .class)) 116 return; 117 118 introspectImpl(initList, type.getSuperclass()); 119 120 configureClassResources(initList, type); 121 122 for (Method method : type.getDeclaredMethods()) { 123 String fieldName = method.getName(); 124 Class []param = method.getParameterTypes(); 125 126 if (param.length != 1) 127 continue; 128 129 if (fieldName.startsWith("set") && fieldName.length() > 3) { 130 fieldName = fieldName.substring(3); 131 132 char ch = fieldName.charAt(0); 133 134 if (Character.isUpperCase(ch) && 135 (fieldName.length() == 1 || 136 Character.isLowerCase(fieldName.charAt(1)))) { 137 fieldName = Character.toLowerCase(ch) + fieldName.substring(1); 138 } 139 } 140 141 configure(initList, method, fieldName, param[0]); 142 } 143 } 144 145 public static void 146 configureClassResources(ArrayList <BuilderProgram> initList, 147 Class type) 148 throws ConfigException 149 { 150 Resources resources = (Resources) type.getAnnotation(Resources.class); 151 if (resources != null) { 152 for (Resource resource : resources.value()) { 153 introspectClassResource(initList, type, resource); 154 } 155 } 156 157 Resource resource = (Resource) type.getAnnotation(Resource.class); 158 if (resource != null) { 159 introspectClassResource(initList, type, resource); 160 } 161 162 for (Field field : type.getDeclaredFields()) { 163 configure(initList, field, field.getName(), field.getType()); 164 } 165 } 166 167 private static void 168 introspectClassResource(ArrayList <BuilderProgram> initList, 169 Class type, 170 Resource resource) 171 throws ConfigException 172 { 173 String name = resource.name(); 174 175 Field field = findField(type, name); 176 177 if (field != null) { 178 initList.add(configureResource(field, field.getName(), field.getType(), 179 resource.name(), 180 resource.type().getName(), 181 resource.name())); 182 183 return; 184 } 185 186 Method method = findMethod(type, name); 187 188 if (method != null) { 189 initList.add(configureResource(method, method.getName(), 190 method.getParameterTypes()[0], 191 resource.name(), 192 resource.type().getName(), 193 resource.name())); 194 195 return; 196 } 197 } 198 199 private static Field findField(Class type, String name) 200 { 201 for (Field field : type.getDeclaredFields()) { 202 if (field.getName().equals(name)) 203 return field; 204 } 205 206 return null; 207 } 208 209 private static Method findMethod(Class type, String name) 210 { 211 for (Method method : type.getDeclaredMethods()) { 212 if (method.getParameterTypes().length != 1) 213 continue; 214 215 String methodName = method.getName(); 216 if (! methodName.startsWith("set")) 217 continue; 218 219 methodName = Introspector.decapitalize(methodName.substring(3)); 220 221 if (name.equals(methodName)) 222 return method; 223 } 224 225 return null; 226 } 227 228 public static void configure(ArrayList <BuilderProgram> initList, 229 AccessibleObject field, 230 String fieldName, 231 Class fieldType) 232 throws ConfigException 233 { 234 if (field.isAnnotationPresent(Resource.class)) 235 configureResource(initList, field, fieldName, fieldType); 236 else if (field.isAnnotationPresent(EJB .class)) 237 configureEJB(initList, field, fieldName, fieldType); 238 else if (field.isAnnotationPresent(PersistenceUnit.class)) 239 configurePersistenceUnit(initList, field, fieldName, fieldType); 240 else if (field.isAnnotationPresent(PersistenceContext.class)) 241 configurePersistenceContext(initList, field, fieldName, fieldType); 242 else if (field.isAnnotationPresent(WebServiceRef.class)) 243 configureWebServiceRef(initList, field, fieldName, fieldType); 244 } 245 246 private static void configureResource(ArrayList <BuilderProgram> initList, 247 AccessibleObject field, 248 String fieldName, 249 Class fieldType) 250 throws ConfigException 251 { 252 Resource resource = field.getAnnotation(Resource.class); 253 254 initList.add(configureResource(field, 255 fieldName, fieldType, 256 resource.name(), 257 resource.type().getName(), 258 resource.name())); 259 } 260 261 public static BuilderProgram 262 introspectResource(AccessibleObject field, 263 String fieldName, 264 Class fieldType) 265 throws ConfigException 266 { 267 Resource resource = field.getAnnotation(Resource.class); 268 269 if (resource != null) 270 return configureResource(field, 271 fieldName, fieldType, 272 resource.name(), 273 resource.type().getName(), 274 resource.name()); 275 else 276 return null; 277 } 278 279 private static void configureEJB(ArrayList <BuilderProgram> initList, 280 AccessibleObject field, 281 String fieldName, 282 Class fieldType) 283 throws ConfigException 284 { 285 EJB ejb = (EJB ) field.getAnnotation(javax.ejb.EJB .class); 286 287 initList.add(configureResource(field, fieldName, fieldType, 288 ejb.beanName(), 289 "javax.ejb.EJBLocalObject", 290 ejb.name())); 291 } 292 293 private static void 294 configureWebServiceRef(ArrayList <BuilderProgram> initList, 295 AccessibleObject field, 296 String fieldName, 297 Class fieldType) 298 throws ConfigException 299 { 300 WebServiceRef ref 301 = (WebServiceRef) field.getAnnotation(WebServiceRef.class); 302 303 String name = ref.name(); 304 name = ref.name(); 305 306 if ("".equals(name)) 307 name = fieldName; 308 309 name = toFullName(name); 310 312 AccessibleInject inject; 313 314 if (field instanceof Field ) 315 inject = new FieldInject((Field ) field); 316 else 317 inject = new PropertyInject((Method ) field); 318 319 BuilderProgram program; 320 321 if (Service.class.isAssignableFrom(fieldType)) { 322 program = new ServiceInjectProgram(name, 323 fieldType, 324 inject); 325 } 326 else { 327 program = new ServiceProxyInjectProgram(name, 328 fieldType, 329 inject); 330 } 331 332 initList.add(program); 333 } 334 335 private static void configurePersistenceUnit(ArrayList <BuilderProgram> initList, 336 AccessibleObject field, 337 String fieldName, 338 Class fieldType) 339 throws ConfigException 340 { 341 PersistenceUnit pUnit = field.getAnnotation(PersistenceUnit.class); 342 343 String jndiPrefix = "java:comp/env/persistence/_amber_PersistenceUnit"; 344 345 String jndiName = null; 346 String unitName = pUnit.unitName(); 347 348 try { 349 if (! unitName.equals("")) 350 jndiName = jndiPrefix + '/' + unitName; 351 else { 352 InitialContext ic = new InitialContext (); 353 354 NamingEnumeration <NameClassPair > iter = ic.list(jndiPrefix); 355 356 if (iter == null) { 357 log.warning("Can't find configured PersistenceUnit"); 358 return; } 360 361 String ejbJndiName = null; 362 while (iter.hasMore()) { 363 NameClassPair pair = iter.next(); 364 365 if (pair.getName().equals("resin-ejb")) 366 ejbJndiName = jndiPrefix + '/' + pair.getName(); 367 else { 368 jndiName = jndiPrefix + '/' + pair.getName(); 369 break; 370 } 371 } 372 373 if (jndiName == null) 374 jndiName = ejbJndiName; 375 } 376 377 initList.add(configureResource(field, fieldName, fieldType, 378 unitName, 379 "javax.persistence.EntityManagerFactory", 380 jndiName)); 381 } catch (Throwable e) { 382 log.log(Level.WARNING, e.toString(), e); 383 } 384 } 385 386 private static void configurePersistenceContext(ArrayList <BuilderProgram> initList, 387 AccessibleObject field, 388 String fieldName, 389 Class fieldType) 390 throws ConfigException 391 { 392 PersistenceContext pContext = field.getAnnotation(PersistenceContext.class); 393 394 String jndiPrefix = "java:comp/env/persistence"; 395 396 String jndiName = null; 397 String unitName = pContext.unitName(); 398 399 try { 400 if (! unitName.equals("")) 401 jndiName = jndiPrefix + '/' + unitName; 402 else { 403 InitialContext ic = new InitialContext (); 404 405 NamingEnumeration <NameClassPair > iter = ic.list(jndiPrefix); 406 407 if (iter == null) { 408 log.warning("Can't find configured PersistenceContext"); 409 return; } 411 412 String ejbJndiName = null; 413 while (iter.hasMore()) { 414 NameClassPair pair = iter.next(); 415 416 if (pair.getName().startsWith("_amber")) 419 continue; 420 421 if (pair.getName().equals("resin-ejb")) 422 ejbJndiName = jndiPrefix + '/' + pair.getName(); 423 else { 424 jndiName = jndiPrefix + '/' + pair.getName(); 425 break; 426 } 427 } 428 429 if (jndiName == null) 430 jndiName = ejbJndiName; 431 } 432 433 initList.add(configureResource(field, fieldName, fieldType, 434 unitName, 435 "javax.persistence.EntityManager", 436 jndiName)); 437 } catch (Throwable e) { 438 log.log(Level.WARNING, e.toString(), e); 439 } 440 } 441 442 private static 443 BuilderProgram configureResource(AccessibleObject field, 444 String fieldName, 445 Class fieldType, 446 String name, 447 String resourceType, 448 String jndiName) 449 throws ConfigException 450 { 451 String prefix = ""; 452 453 if (name.equals("")) 454 name = fieldName; 455 456 if (resourceType.equals("") || resourceType.equals("java.lang.Object")) 457 resourceType = fieldType.getName(); 458 459 if (resourceType.equals("javax.sql.DataSource")) 460 prefix = "jdbc/"; 461 else if (resourceType.startsWith("javax.jms.")) 462 prefix = "jms/"; 463 else if (resourceType.startsWith("javax.mail.")) 464 prefix = "mail/"; 465 else if (resourceType.equals("java.net.URL")) 466 prefix = "url/"; 467 else if (resourceType.startsWith("javax.ejb.")) 468 prefix = "ejb/"; 469 470 if (! jndiName.equals("")) { 471 } 472 else if (UserTransaction .class.equals(fieldType)) { 473 jndiName = "java:comp/UserTransaction"; 474 } 475 else if ("java.util.concurrent.Executor".equals(resourceType)) { 476 jndiName = "java:comp/ThreadPool"; 477 } 478 else { 479 jndiName = prefix + name; 480 } 481 482 int colon = jndiName.indexOf(':'); 483 int slash = jndiName.indexOf('/'); 484 485 if (colon < 0 || slash > 0 && slash < colon) 486 jndiName = "java:comp/env/" + jndiName; 487 488 BuilderProgram program; 489 490 if (field instanceof Method ) 491 program = new JndiInjectProgram(jndiName, (Method ) field); 492 else 493 program = new JndiFieldInjectProgram(jndiName, (Field ) field); 494 495 if (log.isLoggable(Level.FINEST)) 496 log.log(Level.FINEST, String.valueOf(program)); 497 498 return program; 499 } 500 501 private static String toFullName(String jndiName) 502 { 503 int colon = jndiName.indexOf(':'); 504 int slash = jndiName.indexOf('/'); 505 506 if (colon < 0 || slash > 0 && slash < colon) 507 jndiName = "java:comp/env/" + jndiName; 508 509 return jndiName; 510 } 511 } 512 | Popular Tags |