1 25 26 package org.objectweb.easybeans.container; 27 28 import static org.objectweb.easybeans.container.mdb.MDBMessageEndPointFactory.DEFAULT_ACTIVATION_SPEC_NAME; 29 30 import java.net.URL ; 31 import java.util.Collection ; 32 import java.util.HashMap ; 33 import java.util.List ; 34 import java.util.Map ; 35 36 import javax.naming.Context ; 37 import javax.naming.InitialContext ; 38 import javax.naming.NamingException ; 39 import javax.resource.ResourceException ; 40 import javax.resource.spi.ActivationSpec ; 41 import javax.resource.spi.ResourceAdapter ; 42 43 import org.objectweb.easybeans.api.EZBArchive; 44 import org.objectweb.easybeans.api.EZBArchiveException; 45 import org.objectweb.easybeans.api.EZBContainer; 46 import org.objectweb.easybeans.api.EZBContainerCallbackInfo; 47 import org.objectweb.easybeans.api.EZBContainerConfig; 48 import org.objectweb.easybeans.api.EZBContainerException; 49 import org.objectweb.easybeans.api.EZBContainerLifeCycleCallback; 50 import org.objectweb.easybeans.api.EZBPermissionManager; 51 import org.objectweb.easybeans.api.EZBServer; 52 import org.objectweb.easybeans.api.Factory; 53 import org.objectweb.easybeans.api.FactoryException; 54 import org.objectweb.easybeans.api.PermissionManagerException; 55 import org.objectweb.easybeans.api.bean.info.IBeanInfo; 56 import org.objectweb.easybeans.api.bean.info.IEJBJarInfo; 57 import org.objectweb.easybeans.container.info.EJBJarInfo; 58 import org.objectweb.easybeans.container.info.MessageDrivenInfo; 59 import org.objectweb.easybeans.container.info.SessionBeanInfo; 60 import org.objectweb.easybeans.container.info.security.SecurityInfoHelper; 61 import org.objectweb.easybeans.container.mdb.MDBMessageEndPointFactory; 62 import org.objectweb.easybeans.container.mdb.MDBResourceAdapterHelper; 63 import org.objectweb.easybeans.container.session.SessionFactory; 64 import org.objectweb.easybeans.container.session.stateful.StatefulSessionFactory; 65 import org.objectweb.easybeans.container.session.stateless.StatelessSessionFactory; 66 import org.objectweb.easybeans.deployment.Deployment; 67 import org.objectweb.easybeans.deployment.annotations.exceptions.AnalyzerException; 68 import org.objectweb.easybeans.deployment.annotations.exceptions.ResolverException; 69 import org.objectweb.easybeans.deployment.annotations.impl.JLocal; 70 import org.objectweb.easybeans.deployment.annotations.impl.JRemote; 71 import org.objectweb.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata; 72 import org.objectweb.easybeans.deployment.annotations.metadata.EjbJarAnnotationMetadata; 73 import org.objectweb.easybeans.deployment.helper.JavaContextHelper; 74 import org.objectweb.easybeans.deployment.helper.JavaContextHelperException; 75 import org.objectweb.easybeans.deployment.resolver.JNDIResolver; 76 import org.objectweb.easybeans.deployment.xml.EJB3DeploymentDescException; 77 import org.objectweb.easybeans.enhancer.Enhancer; 78 import org.objectweb.easybeans.enhancer.EnhancerException; 79 import org.objectweb.easybeans.jmx.MBeansException; 80 import org.objectweb.easybeans.jmx.MBeansHelper; 81 import org.objectweb.easybeans.loader.EasyBeansClassLoader; 82 import org.objectweb.easybeans.log.JLog; 83 import org.objectweb.easybeans.log.JLogFactory; 84 import org.objectweb.easybeans.persistence.PersistenceUnitManager; 85 import org.objectweb.easybeans.persistence.api.EZBPersistenceUnitManager; 86 import org.objectweb.easybeans.persistence.xml.PersistenceXmlFileAnalyzer; 87 import org.objectweb.easybeans.persistence.xml.PersistenceXmlFileAnalyzerException; 88 import org.objectweb.easybeans.rpc.LocalCallRef; 89 import org.objectweb.easybeans.rpc.RemoteCallRef; 90 import org.objectweb.easybeans.security.permissions.PermissionManager; 91 import org.objectweb.easybeans.server.Embedded; 92 93 97 public class JContainer3 implements EZBContainer { 98 99 102 private static JLog logger = JLogFactory.getLog(JContainer3.class); 103 104 107 private String id = null; 108 109 112 private ClassLoader classLoader = null; 113 114 117 private Deployment deployment = null; 118 119 122 private boolean available = false; 123 124 127 private Map <String , Factory> factories = null; 128 129 133 private EZBPersistenceUnitManager persistenceUnitManager = null; 134 135 138 private EZBContainerConfig configuration = null; 139 140 143 private EZBPermissionManager permissionManager = null; 144 145 148 private IEJBJarInfo ejbJarInfo = null; 149 150 155 public JContainer3(final EZBContainerConfig config) { 156 setContainerConfig(config); 157 } 158 159 162 protected JContainer3() {} 163 164 168 protected void setContainerConfig(final EZBContainerConfig config) { 169 if (this.available) { 170 throw new IllegalStateException ("Cannot change the EZBContainer configuration after start()."); 171 } 172 this.configuration = config; 173 this.id = String.valueOf(System.identityHashCode(this)); 174 this.deployment = new Deployment(getArchive()); 175 this.factories = new HashMap <String , Factory>(); 176 } 177 181 public String getId() { 182 return id; 183 } 184 185 189 public void start() throws EZBContainerException { 190 191 long tStart = System.currentTimeMillis(); 193 try { 194 deployment.analyze(); 195 } catch (AnalyzerException e) { 196 throw new EZBContainerException("Cannot analyze archive '" + getArchive().getName() + "'.", e); 197 } catch (ResolverException e) { 198 throw new EZBContainerException("Cannot resolve some annotations in the archive '" + getName() 199 + "'.", e); 200 } catch (EJB3DeploymentDescException e) { 201 throw new EZBContainerException("Cannot parse deployment descriptor in the archive '" + getName() 202 + "'.", e); 203 } 204 if (logger.isInfoEnabled()) { 205 logger.info("Analyze elapsed during : " + (System.currentTimeMillis() - tStart) + " ms"); 206 } 207 208 URL url = null; 210 try { 211 url = getArchive().getURL(); 212 } catch (EZBArchiveException e) { 213 throw new EZBContainerException("Cannot get URL on the archive '" + getName() + "'.", e); 214 } 215 216 JNDIResolver jndiResolver = new JNDIResolver(); 218 jndiResolver.addDeployment(deployment); 219 220 Map <String , Object > enhancerMap = new HashMap <String , Object >(); 222 enhancerMap.put(JNDIResolver.NAME, jndiResolver); 223 224 ClassLoader old = Thread.currentThread().getContextClassLoader(); 225 if (classLoader == null) { 228 classLoader = new EasyBeansClassLoader(new URL [] {url}, old); 229 } 230 try { 231 Thread.currentThread().setContextClassLoader(classLoader); 232 Enhancer enhancer = new Enhancer(classLoader, deployment.getAnnotationDeploymentAnalyzer() 233 .getEjbJarAnnotationMetadata(), enhancerMap); 234 235 long tStartEnhancing = System.currentTimeMillis(); 236 try { 237 enhancer.enhance(); 238 } catch (EnhancerException e) { 239 throw new EZBContainerException("Cannot run enhancer on archive '" + getName() + "'.", e); 240 } 241 if (logger.isInfoEnabled()) { 242 logger.info("Enhancement elapsed during : " + (System.currentTimeMillis() - tStartEnhancing) + " ms"); 243 } 244 245 PersistenceUnitManager analyzedPersistenceUnitManager = null; 247 try { 248 analyzedPersistenceUnitManager = PersistenceXmlFileAnalyzer.analyzePersistenceXmlFile(getArchive(), 249 getClassLoader()); 250 } catch (PersistenceXmlFileAnalyzerException e) { 251 throw new EZBContainerException("Cannot analyze the persistence.xml file in the archive", e); 252 } 253 254 if (this.persistenceUnitManager == null) { 256 this.persistenceUnitManager = analyzedPersistenceUnitManager; 257 } else { 258 if (analyzedPersistenceUnitManager != null) { 260 analyzedPersistenceUnitManager.merge(persistenceUnitManager); 261 this.persistenceUnitManager = analyzedPersistenceUnitManager; 263 } 264 } 265 266 createBeanFactories(); 268 269 deployment = new Deployment(getArchive()); 271 enhancer = null; 272 } finally { 273 Thread.currentThread().setContextClassLoader(old); 274 } 275 if (logger.isInfoEnabled()) { 276 logger.info("Container started in : " + (System.currentTimeMillis() - tStart) + " ms"); 277 } 278 available = true; 279 280 if (getCallbacksLifeCycle().size() > 0) { 282 EZBContainerCallbackInfo info = getContainer3CallbackInfo(); 283 for (EZBContainerLifeCycleCallback callback : getCallbacksLifeCycle()) { 284 try { 285 callback.start(info); 286 } catch (Throwable t) { 287 logger.error("{0}.start() failed", callback.getClass().getName(), t); 289 } 290 } 291 } 292 293 } 294 295 299 private void createBeanFactories() throws EZBContainerException { 300 ejbJarInfo = new EJBJarInfo(); 301 EjbJarAnnotationMetadata ejbMetadata = deployment.getAnnotationDeploymentAnalyzer() 303 .getEjbJarAnnotationMetadata(); 304 if (ejbMetadata != null) { 305 for (ClassAnnotationMetadata bean : ejbMetadata.getClassAnnotationMetadataCollection()) { 306 Factory factory = null; 307 if (bean.isSession()) { 308 factory = createSessionBeanFactory(bean); 309 } else if (bean.isMdb()) { 310 factory = createMessageDrivenBeanFactory(bean); 311 } 312 313 if (factory != null) { 315 316 IBeanInfo beanInfo = factory.getBeanInfo(); 318 319 beanInfo.setName(bean.getJCommonBean().getName()); 321 322 beanInfo.setSecurityInfo(SecurityInfoHelper.getSecurityInfo(bean)); 324 ejbJarInfo.addBeanInfo(beanInfo); 325 326 Context javaContext; 328 try { 329 javaContext = JavaContextHelper.build(bean, factory); 330 } catch (JavaContextHelperException e) { 331 throw new EZBContainerException("Cannot build environment", e); 332 } 333 334 factory.setJavaContext(javaContext); 336 337 try { 339 MBeansHelper.getInstance().registerMBean(factory); 340 } catch (MBeansException me) { 341 throw new EZBContainerException("Cannot register the factory MBean", me); 342 } 343 344 345 try { 347 factory.init(); 348 } catch (FactoryException e) { 349 throw new EZBContainerException("Cannot initialize the factory.", e); 350 } 351 352 factories.put(factory.getClassName(), factory); 354 355 } 356 } 357 358 try { 360 permissionManager = new PermissionManager(getArchive().getURL(), ejbJarInfo); 361 permissionManager.translateMetadata(); 363 permissionManager.commit(); 365 } catch (PermissionManagerException e) { 366 throw new EZBContainerException("Cannot create permission manager", e); 367 } catch (EZBArchiveException e) { 368 throw new EZBContainerException("Cannot create permission manager", e); 369 } 370 371 } 372 } 373 374 381 private Factory createMessageDrivenBeanFactory(final ClassAnnotationMetadata messageDrivenBean) 382 throws EZBContainerException { 383 String className = messageDrivenBean.getClassName().replace("/", "."); 384 385 ActivationSpec activationSpec = null; 387 try { 388 activationSpec = (ActivationSpec ) new InitialContext ().lookup(DEFAULT_ACTIVATION_SPEC_NAME); 389 } catch (NamingException e1) { 390 throw new EZBContainerException("Cannot get the activation spec with the name '" 391 + DEFAULT_ACTIVATION_SPEC_NAME + "'."); 392 } 393 394 ResourceAdapter resourceAdapter = null; 396 try { 397 resourceAdapter = MDBResourceAdapterHelper.getResourceAdapter(DEFAULT_ACTIVATION_SPEC_NAME, 398 (Embedded) getConfiguration().getEZBServer()); 399 } catch (ResourceException e) { 400 throw new EZBContainerException("Cannot get the resource adapter for this MDB factory", e); 401 } 402 403 if (activationSpec.getResourceAdapter() == null) { 405 try { 406 activationSpec.setResourceAdapter(resourceAdapter); 407 } catch (ResourceException e) { 408 throw new EZBContainerException("Cannot associate resource adapter with activation spec object", e); 409 } 410 } 411 412 MDBMessageEndPointFactory mdbMessageEndPointFactory = null; 414 try { 415 mdbMessageEndPointFactory = new MDBMessageEndPointFactory(className, this, activationSpec, resourceAdapter); 416 } catch (FactoryException e) { 417 throw new EZBContainerException("Cannot build the MDB MessageEndPoint factory", e); 418 } 419 420 MessageDrivenInfo messageDrivenInfo = new MessageDrivenInfo(); 422 messageDrivenInfo.setApplicationExceptions(messageDrivenBean.getEjbJarAnnotationMetadata().getApplicationExceptions()); 423 messageDrivenInfo.setTransactionManagementType(messageDrivenBean.getTransactionManagementType()); 424 messageDrivenInfo.setMessageListenerInterface(messageDrivenBean.getJMessageDriven() 425 .getMessageListenerInterface()); 426 messageDrivenInfo.setActivationConfigProperties(messageDrivenBean.getJMessageDriven() 427 .getActivationConfigProperties()); 428 mdbMessageEndPointFactory.setMessageDrivenInfo(messageDrivenInfo); 429 430 431 432 return mdbMessageEndPointFactory; 433 434 } 435 436 442 private Factory createSessionBeanFactory(final ClassAnnotationMetadata sessionBean) throws EZBContainerException { 443 String className = sessionBean.getClassName().replace("/", "."); 444 445 SessionFactory sessionFactory = null; 446 447 if (sessionBean.isStateless()) { 448 try { 449 sessionFactory = new StatelessSessionFactory(className, this); 450 } catch (FactoryException fe) { 451 throw new EZBContainerException("Cannot build the stateless factory", fe); 452 } 453 } else { 454 try { 455 sessionFactory = new StatefulSessionFactory(className, this); 456 } catch (FactoryException fe) { 457 throw new EZBContainerException("Cannot build the stateless factory", fe); 458 } 459 } 460 461 SessionBeanInfo sessionBeanInfo = new SessionBeanInfo(); 463 sessionBeanInfo.setTransactionManagementType(sessionBean.getTransactionManagementType()); 464 sessionBeanInfo.setApplicationExceptions(sessionBean.getEjbJarAnnotationMetadata().getApplicationExceptions()); 465 sessionFactory.setSessionBeanInfo(sessionBeanInfo); 466 467 JLocal localItfs = sessionBean.getLocalInterfaces(); 469 JRemote remoteItfs = sessionBean.getRemoteInterfaces(); 470 471 if (localItfs != null) { 472 for (String itf : localItfs.getInterfaces()) { 473 bindLocalItf(itf, getEmbedded().getID(), getId(), className, sessionBean, "Local"); 474 } 475 } 476 if (remoteItfs != null) { 477 for (String itf : remoteItfs.getInterfaces()) { 478 bindRemoteItf(itf, getId(), className, sessionBean, "Remote"); 479 } 480 } 481 482 return sessionFactory; 483 } 484 485 488 public void stop() { 489 available = false; 490 491 for (Factory f : factories.values()) { 493 f.stop(); 494 495 try { 497 MBeansHelper.getInstance().unregisterMBean(f); 498 } catch (MBeansException me) { 499 logger.error("Cannot unregister the factory MBean", me); 500 } 501 502 } 503 504 classLoader = null; 506 507 510 if (getCallbacksLifeCycle().size() > 0) { 512 EZBContainerCallbackInfo info = getContainer3CallbackInfo(); 513 for (EZBContainerLifeCycleCallback callback : getCallbacksLifeCycle()) { 514 try { 515 callback.stop(info); 516 } catch (Throwable t) { 517 logger.error("{0}.stop() failed", callback.getClass().getName(), t); 519 } 520 } 521 } 522 } 523 524 529 private EZBContainerCallbackInfo getContainer3CallbackInfo() { 530 EZBContainerCallbackInfo info = new EZBContainerCallbackInfo(); 531 info.setArchive(getArchive()); 532 info.setFactories(factories); 533 return info; 534 } 535 536 548 private void bindLocalItf(final String itf, final Integer embeddedId, final String containerID, final String factoryName, 549 final ClassAnnotationMetadata bean, final String mode) throws EZBContainerException { 550 String itfClsName = itf.replace("/", "."); 551 Class clz = null; 552 try { 553 clz = classLoader.loadClass(itfClsName); 554 } catch (ClassNotFoundException e) { 555 throw new EZBContainerException( 556 "Cannot find the class '" + itf + "' in Classloader '" + classLoader + "'.", e); 557 } 558 559 LocalCallRef localCall = new LocalCallRef(itfClsName, embeddedId, containerID, factoryName, bean.isStateful()); 561 562 try { 563 String jndiName = null; 564 String mappedName = bean.getJCommonBean().getMappedName(); 565 if (mappedName != null && !"".equals(mappedName)) { 566 jndiName = mappedName; 567 } else { 568 jndiName = jndiNameEncode(bean.getClassName(), itfClsName, mode); 569 } 570 logger.debug("Binding bean {0} with interface {1} into registry with jndi name {2}", bean.getClassName() 571 .replace("/", "."), itf.replace("/", "."), jndiName); 572 new InitialContext ().rebind(jndiName, localCall); 573 } catch (NamingException e) { 574 throw new EZBContainerException("Cannot bind the object '" + localCall + "' into JNDI with the name '" 575 + clz.getName() + "'.", e); 576 } 577 578 } 579 580 591 private void bindRemoteItf(final String itf, final String containerID, final String factoryName, 592 final ClassAnnotationMetadata bean, final String mode) throws EZBContainerException { 593 String itfClsName = itf.replace("/", "."); 594 Class clz = null; 595 try { 596 clz = classLoader.loadClass(itfClsName); 597 } catch (ClassNotFoundException e) { 598 throw new EZBContainerException( 599 "Cannot find the class '" + itf + "' in Classloader '" + classLoader + "'.", e); 600 } 601 602 RemoteCallRef remoteCall = new RemoteCallRef(itfClsName, containerID, factoryName, bean.isStateful()); 604 605 try { 606 String jndiName = null; 607 String mappedName = bean.getJCommonBean().getMappedName(); 608 if (mappedName != null && !"".equals(mappedName)) { 609 jndiName = mappedName; 610 } else { 611 jndiName = jndiNameEncode(bean.getClassName(), itfClsName, mode); 612 } 613 logger.debug("Binding bean {0} with interface {1} into registry with jndi name {2}", bean.getClassName() 614 .replace("/", "."), itf.replace("/", "."), jndiName); 615 new InitialContext ().rebind(jndiName, remoteCall); 616 } catch (NamingException e) { 617 throw new EZBContainerException("Cannot bind the object '" + remoteCall + "' into JNDI with the name '" 618 + clz.getName() + "'.", e); 619 } 620 621 } 622 623 628 public Factory getFactory(final String factoryName) { 629 return factories.get(factoryName); 630 } 631 632 635 public Collection <Factory> getFactories() { 636 return factories.values(); 637 } 638 639 643 public String getName() { 644 return getArchive().getName(); 645 } 646 647 651 public ClassLoader getClassLoader() { 652 return classLoader; 653 } 654 655 660 public EZBArchive getArchive() { 661 return configuration.getArchive(); 662 } 663 664 668 public EZBServer getEmbedded() { 669 return configuration.getEZBServer(); 670 } 671 672 675 private List <EZBContainerLifeCycleCallback> getCallbacksLifeCycle() { 676 return configuration.getCallbacks(); 677 } 678 679 683 public boolean isAvailable() { 684 return available; 685 } 686 687 692 public EZBPersistenceUnitManager getPersistenceUnitManager() { 693 return persistenceUnitManager; 694 } 695 696 703 public static String jndiNameEncode(final String beanClassName, final String itfName, final String mode) { 704 return beanClassName.replace("/", ".") + "_" + itfName.replace("/", ".") + "@" + mode; 705 } 706 707 711 public void setClassLoader(final ClassLoader classLoader) { 712 if (this.classLoader != null) { 713 throw new IllegalArgumentException ("Cannot replace an existing classloader"); 714 } 715 this.classLoader = classLoader; 716 } 717 718 723 public void setPersistenceUnitManager(final EZBPersistenceUnitManager persistenceUnitManager) { 724 if (this.persistenceUnitManager != null) { 725 throw new IllegalArgumentException ("Cannot replace an existing persistenceUnitManager"); 726 } 727 this.persistenceUnitManager = persistenceUnitManager; 728 } 729 730 733 public EZBContainerConfig getConfiguration() { 734 return this.configuration; 735 } 736 737 738 739 743 public EZBPermissionManager getPermissionManager() { 744 return permissionManager; 745 } 746 747 751 public void setPermissionManager(final EZBPermissionManager ezbPermissionManager) { 752 this.permissionManager = ezbPermissionManager; 753 } 754 } 755 | Popular Tags |