1 23 package com.sun.enterprise.util; 24 25 import java.util.List ; 26 import java.util.LinkedList ; 27 import java.lang.reflect.Field ; 28 import java.lang.reflect.Method ; 29 import java.lang.reflect.Modifier ; 30 import java.lang.reflect.InvocationTargetException ; 31 import java.util.logging.*; 32 33 import com.sun.enterprise.InvocationManager; 34 import com.sun.enterprise.Switch; 35 import com.sun.enterprise.InjectionManager; 36 import com.sun.enterprise.InjectionException; 37 import com.sun.enterprise.ComponentInvocation; 38 import javax.naming.InitialContext ; 39 import javax.naming.NamingException ; 40 41 import com.sun.enterprise.deployment.JndiNameEnvironment; 42 import com.sun.enterprise.deployment.InjectionCapable; 43 import com.sun.enterprise.deployment.InjectionInfo; 44 import com.sun.enterprise.deployment.InjectionTarget; 45 import com.sun.logging.*; 46 47 52 public class InjectionManagerImpl implements InjectionManager { 53 54 static Logger _logger=LogDomains.getLogger(LogDomains.UTIL_LOGGER); 55 56 static private LocalStringManagerImpl localStrings = 57 new LocalStringManagerImpl(InjectionManagerImpl.class); 58 59 private Switch theSwitch; 60 private InvocationManager invocationMgr; 61 private InitialContext namingCtx; 62 63 public InjectionManagerImpl() { 64 65 theSwitch = Switch.getSwitch(); 66 invocationMgr = theSwitch.getInvocationManager(); 67 68 try { 69 namingCtx = new InitialContext (); 70 } catch(NamingException ne) { 71 throw new RuntimeException (ne); 72 } 73 74 } 75 76 public void injectInstance(Object instance) 77 throws InjectionException { 78 79 ComponentInvocation inv = invocationMgr.getCurrentInvocation(); 80 81 if( inv != null ) { 82 83 JndiNameEnvironment componentEnv = (JndiNameEnvironment) 84 theSwitch.getDescriptorFor(inv.getContainerContext()); 85 86 if( componentEnv != null ) { 87 inject(instance.getClass(), instance, componentEnv, true); 88 } else { 89 throw new InjectionException("No descriptor registered for " + 90 " current invocation : " + inv); 91 } 92 93 } else { 94 throw new InjectionException("null invocation context"); 95 } 96 97 } 98 99 public void injectInstance(Object instance, 100 JndiNameEnvironment componentEnv) 101 throws InjectionException 102 { 103 104 inject(instance.getClass(), instance, componentEnv, true); 105 106 } 107 108 public void injectInstance(Object instance, 109 JndiNameEnvironment componentEnv, 110 boolean invokePostConstruct) 111 throws InjectionException 112 { 113 114 inject(instance.getClass(), instance, componentEnv, 115 invokePostConstruct); 116 117 } 118 119 public void injectClass(Class clazz, 120 JndiNameEnvironment componentEnv) 121 throws InjectionException 122 { 123 injectClass(clazz, componentEnv, true); 124 } 125 126 public void injectClass(Class clazz, 127 JndiNameEnvironment componentEnv, 128 boolean invokePostConstruct) 129 throws InjectionException 130 { 131 inject(clazz, null, componentEnv, invokePostConstruct); 132 } 133 134 public void invokeInstancePreDestroy(Object instance, 135 JndiNameEnvironment componentEnv) 136 throws InjectionException 137 { 138 invokePreDestroy(instance.getClass(), instance, componentEnv); 139 } 140 141 public void invokeInstancePreDestroy(Object instance) 142 throws InjectionException { 143 144 ComponentInvocation inv = invocationMgr.getCurrentInvocation(); 145 146 if( inv != null ) { 147 148 JndiNameEnvironment componentEnv = (JndiNameEnvironment) 149 theSwitch.getDescriptorFor(inv.getContainerContext()); 150 151 if( componentEnv != null ) { 152 invokePreDestroy(instance.getClass(), instance, componentEnv); 153 } else { 154 throw new InjectionException("No descriptor registered for " + 155 " current invocation : " + inv); 156 } 157 158 } else { 159 throw new InjectionException("null invocation context"); 160 } 161 } 162 163 public void invokeClassPreDestroy(Class clazz, 164 JndiNameEnvironment componentEnv) 165 throws InjectionException 166 { 167 invokePreDestroy(clazz, null, componentEnv); 168 } 169 170 175 private void inject(final Class clazz, final Object instance, 176 JndiNameEnvironment envDescriptor, 177 boolean invokePostConstruct) 178 throws InjectionException 179 { 180 181 LinkedList <Method > postConstructMethods = new LinkedList <Method >(); 182 183 Class nextClass = clazz; 184 185 while((nextClass != Object .class) && (nextClass != null)) { 188 189 InjectionInfo injInfo = 190 envDescriptor.getInjectionInfoByClass(nextClass.getName()); 191 192 if( injInfo.getInjectionResources().size() > 0 ) { 193 _inject(nextClass, instance, injInfo.getInjectionResources()); 194 } 195 196 if( invokePostConstruct ) { 197 198 if( injInfo.getPostConstructMethodName() != null ) { 199 200 Method postConstructMethod = getPostConstructMethod 201 (injInfo, nextClass); 202 203 postConstructMethods.addFirst(postConstructMethod); 208 } 209 } 210 211 nextClass = nextClass.getSuperclass(); 212 } 213 214 215 for(Method postConstructMethod : postConstructMethods) { 216 217 invokeLifecycleMethod(postConstructMethod, instance); 218 219 } 220 221 } 222 223 227 private void invokePreDestroy(final Class clazz, final Object instance, 228 JndiNameEnvironment envDescriptor) 229 throws InjectionException 230 { 231 232 LinkedList <Method > preDestroyMethods = new LinkedList <Method >(); 233 234 Class nextClass = clazz; 235 236 while((nextClass != Object .class) && (nextClass != null)) { 239 240 InjectionInfo injInfo = 241 envDescriptor.getInjectionInfoByClass(nextClass.getName()); 242 243 if( injInfo.getPreDestroyMethodName() != null ) { 244 245 Method preDestroyMethod = getPreDestroyMethod 246 (injInfo, nextClass); 247 248 preDestroyMethods.addFirst(preDestroyMethod); 251 } 252 253 nextClass = nextClass.getSuperclass(); 254 } 255 256 for(Method preDestroyMethod : preDestroyMethods) { 257 258 invokeLifecycleMethod(preDestroyMethod, instance); 259 260 } 261 262 } 263 264 265 private void _inject(final Class clazz, final Object instance, 266 List <InjectionCapable> injectableResources) 267 throws InjectionException 268 { 269 270 for (InjectionCapable next : injectableResources ) { 271 272 try { 273 274 final Object value = namingCtx.lookup("java:comp/env/" + 275 next.getComponentEnvName()); 276 277 for (InjectionTarget target : next.getInjectionTargets()) { 280 281 if (!clazz.getName().equals(target.getClassName())) 284 continue; 285 286 if( target.isFieldInjectable() ) { 287 288 final Field f = getField(target, clazz); 289 290 if( Modifier.isStatic(f.getModifiers()) && 291 (instance != null) ) { 292 throw new InjectionException 293 ("Illegal use of static field " + f + 294 " on class that only supports instance-based" 295 + " injection"); 296 } 297 298 if( (instance == null) && 299 !Modifier.isStatic(f.getModifiers()) ) { 300 throw new InjectionException 301 ("Injected field " + f + 302 " on Application Client class " + clazz + 303 " must be declared static"); 304 } 305 306 307 if(_logger.isLoggable(Level.FINE)) { 308 _logger.fine("Injecting dependency with logical name " 309 + next.getComponentEnvName() + 310 " into field " + f + " on class " + 311 clazz); 312 } 313 314 java.security.AccessController.doPrivileged( 317 new java.security.PrivilegedExceptionAction () { 318 public java.lang.Object run() throws Exception { 319 if( !f.isAccessible() ) { 320 f.setAccessible(true); 321 } 322 f.set(instance, value); 323 return null; 324 } 325 }); 326 } else if( target.isMethodInjectable() ) { 327 328 final Method m = getMethod(next, target, clazz); 329 330 if( Modifier.isStatic(m.getModifiers()) && 331 (instance != null) ) { 332 throw new InjectionException 333 ("Illegal use of static method " + m + 334 " on class that only supports instance-based" 335 + " injection"); 336 } 337 338 if( (instance == null) && 339 !Modifier.isStatic(m.getModifiers()) ) { 340 throw new InjectionException 341 ("Injected method " + m + 342 " on Application Client class " + clazz + 343 " must be declared static"); 344 } 345 346 if(_logger.isLoggable(Level.FINE)) { 347 _logger.fine("Injecting dependency with logical name " 348 + next.getComponentEnvName() + 349 " into method " + m + " on class " + 350 clazz); 351 } 352 353 java.security.AccessController.doPrivileged( 356 new java.security.PrivilegedExceptionAction () { 357 public java.lang.Object run() throws Exception { 358 if( !m.isAccessible() ) { 359 m.setAccessible(true); 360 } 361 m.invoke(instance, new Object [] { value }); 362 return null; 363 } 364 }); 365 366 } 367 } 368 } catch(Throwable t) { 369 370 String msg = "Exception attempting to inject " 371 + next + " into " + clazz; 372 _logger.log(Level.FINE, msg, t); 373 InjectionException ie = new InjectionException(msg); 374 Throwable cause = (t instanceof InvocationTargetException ) ? 375 ((InvocationTargetException )t).getCause() : t; 376 ie.initCause( cause ); 377 throw ie; 378 379 } 380 } 381 } 382 383 private void invokeLifecycleMethod(final Method lifecycleMethod, 384 final Object instance) 385 throws InjectionException { 386 387 try { 388 389 if(_logger.isLoggable(Level.FINE)) { 390 _logger.fine("Calling lifeccle method " + 391 lifecycleMethod + " on class " + 392 lifecycleMethod.getDeclaringClass()); 393 } 394 395 java.security.AccessController.doPrivileged( 398 new java.security.PrivilegedExceptionAction () { 399 public java.lang.Object run() throws Exception { 400 if( !lifecycleMethod.isAccessible() ) { 401 lifecycleMethod.setAccessible(true); 402 } 403 lifecycleMethod.invoke(instance); 404 return null; 405 } 406 }); 407 } catch( Throwable t) { 408 409 String msg = "Exception attempting invoke lifecycle " 410 + " method " + lifecycleMethod; 411 _logger.log(Level.FINE, msg, t); 412 InjectionException ie = new InjectionException(msg); 413 Throwable cause = (t instanceof InvocationTargetException ) ? 414 ((InvocationTargetException )t).getCause() : t; 415 ie.initCause( cause ); 416 throw ie; 417 418 } 419 420 return; 421 422 } 423 424 private Field getField(InjectionTarget target, 425 Class resourceClass) throws Exception { 426 427 Field f = target.getField(); 428 429 if( f == null ) { 430 try { 431 f = resourceClass.getDeclaredField 434 (target.getFieldName()); 435 } catch(java.lang.NoSuchFieldException nsfe) {} 436 if( f != null ) { 437 target.setField(f); 438 } 439 } 440 441 if( f == null ) { 442 throw new Exception ("InjectionManager exception. Field " + 443 target.getFieldName() + 444 " not found in Class " + resourceClass); 445 } 446 447 return f; 448 } 449 450 private Method getMethod(InjectionCapable resource, InjectionTarget target, 451 Class resourceClass) throws Exception { 452 453 Method m = target.getMethod(); 454 455 if( m == null ) { 456 for(Method next : resourceClass.getDeclaredMethods()) { 459 if(next.getName().equals(target.getMethodName())) { 462 m = next; 463 target.setMethod(m); 464 break; 465 } 466 } 467 } 468 469 if( m == null ) { 470 throw new Exception ("InjectionManager exception. Method " + 471 "void " + target.getMethodName() + 472 "(" + resource.getInjectResourceType() + ")" + 473 " not found in Class " + resourceClass); 474 } 475 476 return m; 477 } 478 479 480 private Method getPostConstructMethod(InjectionInfo injInfo, 481 Class resourceClass) 482 throws InjectionException { 483 484 Method m = injInfo.getPostConstructMethod(); 485 486 if( m == null ) { 487 String postConstructMethodName = 488 injInfo.getPostConstructMethodName(); 489 490 for(Method next : resourceClass.getDeclaredMethods()) { 493 if( next.getName().equals(postConstructMethodName) && 496 (next.getParameterTypes().length == 0) ) { 497 m = next; 498 injInfo.setPostConstructMethod(m); 499 break; 500 } 501 } 502 } 503 504 if( m == null ) { 505 throw new InjectionException 506 ("InjectionManager exception. PostConstruct method " + 507 injInfo.getPostConstructMethodName() + 508 " could not be found in class " + 509 injInfo.getClassName()); 510 } 511 512 return m; 513 } 514 515 private Method getPreDestroyMethod(InjectionInfo injInfo, 516 Class resourceClass) 517 throws InjectionException { 518 519 Method m = injInfo.getPreDestroyMethod(); 520 521 if( m == null ) { 522 String preDestroyMethodName = injInfo.getPreDestroyMethodName(); 523 524 for(Method next : resourceClass.getDeclaredMethods()) { 527 if( next.getName().equals(preDestroyMethodName) && 530 (next.getParameterTypes().length == 0) ) { 531 m = next; 532 injInfo.setPreDestroyMethod(m); 533 break; 534 } 535 } 536 } 537 538 if( m == null ) { 539 throw new InjectionException 540 ("InjectionManager exception. PreDestroy method " + 541 injInfo.getPreDestroyMethodName() + 542 " could not be found in class " + 543 injInfo.getClassName()); 544 } 545 546 return m; 547 } 548 549 } 550 | Popular Tags |