0001: /**
0002: * EasyBeans
0003: * Copyright (C) 2006 Bull S.A.S.
0004: * Contact: easybeans@ow2.org
0005: *
0006: * This library is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU Lesser General Public
0008: * License as published by the Free Software Foundation; either
0009: * version 2.1 of the License, or any later version.
0010: *
0011: * This library is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * Lesser General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU Lesser General Public
0017: * License along with this library; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
0019: * USA
0020: *
0021: * --------------------------------------------------------------------------
0022: * $Id: JContainer3.java 2156 2007-12-11 12:33:00Z loris $
0023: * --------------------------------------------------------------------------
0024: */package org.ow2.easybeans.container;
0025:
0026: import static org.ow2.easybeans.container.mdb.MDBMessageEndPointFactory.DEFAULT_ACTIVATION_SPEC_NAME;
0027: import static org.ow2.easybeans.util.marshalling.Serialization.loadObject;
0028: import static org.ow2.easybeans.util.marshalling.Serialization.storeObject;
0029:
0030: import java.io.IOException;
0031: import java.io.Serializable;
0032: import java.net.URL;
0033: import java.util.ArrayList;
0034: import java.util.Collection;
0035: import java.util.HashMap;
0036: import java.util.List;
0037: import java.util.Map;
0038:
0039: import javax.naming.Context;
0040: import javax.naming.InitialContext;
0041: import javax.naming.NamingException;
0042: import javax.resource.ResourceException;
0043: import javax.resource.spi.ActivationSpec;
0044: import javax.resource.spi.ResourceAdapter;
0045:
0046: import org.ow2.easybeans.api.EZBContainer;
0047: import org.ow2.easybeans.api.EZBContainerCallbackInfo;
0048: import org.ow2.easybeans.api.EZBContainerConfig;
0049: import org.ow2.easybeans.api.EZBContainerException;
0050: import org.ow2.easybeans.api.EZBContainerLifeCycleCallback;
0051: import org.ow2.easybeans.api.EZBPermissionManager;
0052: import org.ow2.easybeans.api.EZBServer;
0053: import org.ow2.easybeans.api.Factory;
0054: import org.ow2.easybeans.api.FactoryException;
0055: import org.ow2.easybeans.api.LifeCycleCallbackException;
0056: import org.ow2.easybeans.api.PermissionManagerException;
0057: import org.ow2.easybeans.api.bean.info.IBeanInfo;
0058: import org.ow2.easybeans.api.bean.info.IEJBJarInfo;
0059: import org.ow2.easybeans.api.binding.BindingException;
0060: import org.ow2.easybeans.api.binding.EZBBindingFactory;
0061: import org.ow2.easybeans.api.binding.EZBRef;
0062: import org.ow2.easybeans.container.info.EJBJarInfo;
0063: import org.ow2.easybeans.container.info.MessageDrivenInfo;
0064: import org.ow2.easybeans.container.info.SessionBeanInfo;
0065: import org.ow2.easybeans.container.info.security.SecurityInfoHelper;
0066: import org.ow2.easybeans.container.mdb.MDBMessageEndPointFactory;
0067: import org.ow2.easybeans.container.mdb.helper.MDBResourceAdapterHelper;
0068: import org.ow2.easybeans.container.session.SessionFactory;
0069: import org.ow2.easybeans.container.session.stateful.StatefulSessionFactory;
0070: import org.ow2.easybeans.container.session.stateless.StatelessSessionFactory;
0071: import org.ow2.easybeans.deployment.Deployment;
0072: import org.ow2.easybeans.deployment.annotations.exceptions.AnalyzerException;
0073: import org.ow2.easybeans.deployment.annotations.exceptions.ResolverException;
0074: import org.ow2.easybeans.deployment.annotations.impl.JLocal;
0075: import org.ow2.easybeans.deployment.annotations.impl.JRemote;
0076: import org.ow2.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata;
0077: import org.ow2.easybeans.deployment.annotations.metadata.EjbJarAnnotationMetadata;
0078: import org.ow2.easybeans.deployment.helper.JavaContextHelper;
0079: import org.ow2.easybeans.deployment.helper.JavaContextHelperException;
0080: import org.ow2.easybeans.deployment.resolver.JNDIResolver;
0081: import org.ow2.easybeans.deployment.xml.EJB3DeploymentDescException;
0082: import org.ow2.easybeans.enhancer.Enhancer;
0083: import org.ow2.easybeans.enhancer.EnhancerException;
0084: import org.ow2.easybeans.jmx.MBeansException;
0085: import org.ow2.easybeans.jmx.MBeansHelper;
0086: import org.ow2.easybeans.loader.EasyBeansClassLoader;
0087: import org.ow2.easybeans.persistence.PersistenceUnitManager;
0088: import org.ow2.easybeans.persistence.api.EZBPersistenceUnitManager;
0089: import org.ow2.easybeans.persistence.xml.PersistenceXmlFileAnalyzer;
0090: import org.ow2.easybeans.persistence.xml.PersistenceXmlFileAnalyzerException;
0091: import org.ow2.easybeans.proxy.binding.BindingManager;
0092: import org.ow2.easybeans.proxy.reference.EJBHomeCallRef;
0093: import org.ow2.easybeans.proxy.reference.EJBLocalHomeCallRef;
0094: import org.ow2.easybeans.proxy.reference.LocalCallRef;
0095: import org.ow2.easybeans.proxy.reference.RemoteCallRef;
0096: import org.ow2.easybeans.security.permissions.PermissionManager;
0097: import org.ow2.easybeans.server.Embedded;
0098: import org.ow2.util.ee.deploy.api.archive.ArchiveException;
0099: import org.ow2.util.ee.deploy.api.archive.IArchive;
0100: import org.ow2.util.log.Log;
0101: import org.ow2.util.log.LogFactory;
0102:
0103: /**
0104: * Defines an EJB3 container.
0105: * @author Florent Benoit
0106: */
0107: public class JContainer3 implements EZBContainer {
0108:
0109: /**
0110: * Logger.
0111: */
0112: private static Log logger = LogFactory.getLog(JContainer3.class);
0113:
0114: /**
0115: * Id of this container.
0116: */
0117: private String id = null;
0118:
0119: /**
0120: * Classloader use to manage this archive.
0121: */
0122: private ClassLoader classLoader = null;
0123:
0124: /**
0125: * Deployment for the managed archive.
0126: */
0127: private Deployment deployment = null;
0128:
0129: /**
0130: * Container available.
0131: */
0132: private boolean available = false;
0133:
0134: /**
0135: * Map of managed ejb3 factories.
0136: */
0137: private Map<String, Factory<?, ?>> factories = null;
0138:
0139: /**
0140: * Persistence manager object which manages all persistence-unit associated
0141: * to this container.
0142: */
0143: private EZBPersistenceUnitManager persistenceUnitManager = null;
0144:
0145: /**
0146: * JContainer Configuration.
0147: */
0148: private EZBContainerConfig configuration = null;
0149:
0150: /**
0151: * PermissionManager for the security permissions.
0152: */
0153: private EZBPermissionManager permissionManager = null;
0154:
0155: /**
0156: * Info on an ejb-jar file.
0157: */
0158: private IEJBJarInfo ejbJarInfo = null;
0159:
0160: /**
0161: * List of all the Reference that have been bound.
0162: */
0163: private List<EZBRef> bindingReferences = null;
0164:
0165: /**
0166: * Name of the application (EAR case).
0167: */
0168: private String applicationName = null;
0169:
0170: /**
0171: * Build a new container on the given archive.
0172: * @param config The JContainer configuration storing the archive (jar file
0173: * or exploded).
0174: */
0175: public JContainer3(final EZBContainerConfig config) {
0176: setContainerConfig(config);
0177: this .bindingReferences = new ArrayList<EZBRef>();
0178: }
0179:
0180: /**
0181: * Default constructor. Must be used in conjonction with setContainerConfig().
0182: */
0183: protected JContainer3() {
0184: }
0185:
0186: /**
0187: * Configure ths JConatiner. Must be called before start().
0188: * @param config ContainerConfiguration instance.
0189: */
0190: protected void setContainerConfig(final EZBContainerConfig config) {
0191: if (this .available) {
0192: throw new IllegalStateException(
0193: "Cannot change the EZBContainer configuration after start().");
0194: }
0195: this .configuration = config;
0196: this .id = String.valueOf(System.identityHashCode(this ));
0197: this .deployment = new Deployment(getArchive());
0198: this .factories = new HashMap<String, Factory<?, ?>>();
0199: }
0200:
0201: /**
0202: * Gets the id of this container.
0203: * @return string id.
0204: */
0205: public String getId() {
0206: return id;
0207: }
0208:
0209: /**
0210: * Start this container.
0211: * @throws EZBContainerException if starting fails.
0212: */
0213: public void start() throws EZBContainerException {
0214:
0215: // Analyze files
0216: long tStart = System.currentTimeMillis();
0217: try {
0218: deployment.analyze();
0219: } catch (AnalyzerException e) {
0220: throw new EZBContainerException("Cannot analyze archive '"
0221: + getArchive().getName() + "'.", e);
0222: } catch (ResolverException e) {
0223: throw new EZBContainerException(
0224: "Cannot resolve some annotations in the archive '"
0225: + getName() + "'.", e);
0226: } catch (EJB3DeploymentDescException e) {
0227: throw new EZBContainerException(
0228: "Cannot parse deployment descriptor in the archive '"
0229: + getName() + "'.", e);
0230: }
0231: if (logger.isDebugEnabled()) {
0232: logger.debug("Analyze elapsed during : "
0233: + (System.currentTimeMillis() - tStart) + " ms");
0234: }
0235:
0236: // Run enhancer on classes found
0237: URL url = null;
0238: try {
0239: url = getArchive().getURL();
0240: } catch (ArchiveException e) {
0241: throw new EZBContainerException(
0242: "Cannot get URL on the archive '" + getName()
0243: + "'.", e);
0244: }
0245:
0246: // Build JNDI resolver
0247: JNDIResolver jndiResolver = new JNDIResolver();
0248: jndiResolver.addDeployment(deployment);
0249:
0250: // add resolver in the map
0251: Map<String, Object> enhancerMap = new HashMap<String, Object>();
0252: enhancerMap.put(JNDIResolver.NAME, jndiResolver);
0253:
0254: ClassLoader old = Thread.currentThread()
0255: .getContextClassLoader();
0256: // Define classloader if it was not yet defined (ear case -->
0257: // classloader already set)
0258: if (classLoader == null) {
0259: classLoader = new EasyBeansClassLoader(new URL[] { url },
0260: old);
0261: }
0262: try {
0263: Thread.currentThread().setContextClassLoader(classLoader);
0264: Enhancer enhancer = new Enhancer(classLoader, deployment
0265: .getAnnotationDeploymentAnalyzer()
0266: .getEjbJarAnnotationMetadata(), enhancerMap);
0267:
0268: long tStartEnhancing = System.currentTimeMillis();
0269: try {
0270: enhancer.enhance();
0271: } catch (EnhancerException ee) {
0272: throw new EZBContainerException(
0273: "Cannot run enhancer on archive '" + getName()
0274: + "'.", ee);
0275: } catch (RuntimeException e) {
0276: // Catch Exception as some exceptions can be runtime exception
0277: throw new EZBContainerException(
0278: "Cannot run enhancer on archive '" + getName()
0279: + "'.", e);
0280: }
0281: if (logger.isDebugEnabled()) {
0282: logger
0283: .debug("Enhancement elapsed during : "
0284: + (System.currentTimeMillis() - tStartEnhancing)
0285: + " ms");
0286: }
0287:
0288: // Check if there is META-INF/persistence.xml file
0289: PersistenceUnitManager analyzedPersistenceUnitManager = null;
0290: try {
0291: analyzedPersistenceUnitManager = PersistenceXmlFileAnalyzer
0292: .analyzePersistenceXmlFile(getArchive(),
0293: getClassLoader());
0294: } catch (PersistenceXmlFileAnalyzerException e) {
0295: throw new EZBContainerException(
0296: "Cannot analyze the persistence.xml file in the archive",
0297: e);
0298: }
0299:
0300: // No previous manager
0301: if (this .persistenceUnitManager == null) {
0302: this .persistenceUnitManager = analyzedPersistenceUnitManager;
0303: } else {
0304: // merge old and new.
0305: if (analyzedPersistenceUnitManager != null) {
0306: analyzedPersistenceUnitManager
0307: .merge(persistenceUnitManager);
0308: // update persistence manager with the merged one.
0309: this .persistenceUnitManager = analyzedPersistenceUnitManager;
0310: }
0311: }
0312:
0313: // Create Beans Factories
0314: createBeanFactories();
0315:
0316: // cleanup
0317: deployment.reset();
0318: enhancer = null;
0319: } finally {
0320: Thread.currentThread().setContextClassLoader(old);
0321: }
0322: if (logger.isInfoEnabled()) {
0323: logger.info("Container started in : "
0324: + (System.currentTimeMillis() - tStart) + " ms");
0325: }
0326: available = true;
0327:
0328: // Send notification to callbacks
0329: if (getCallbacksLifeCycle().size() > 0) {
0330: EZBContainerCallbackInfo info = getContainer3CallbackInfo();
0331: for (EZBContainerLifeCycleCallback callback : getCallbacksLifeCycle()) {
0332: try {
0333: callback.start(info);
0334: } catch (Throwable t) {
0335: // Protection from malicious code
0336: logger.error("{0}.start() failed", callback
0337: .getClass().getName(), t);
0338: }
0339: }
0340: }
0341:
0342: try {
0343: MBeansHelper.getInstance().registerMBean(this );
0344: } catch (MBeansException e) {
0345: // TODO what to do here ? log or exception ?
0346: logger.error("Cannot register Container MBeans for "
0347: + getArchive().getName(), e);
0348: }
0349:
0350: }
0351:
0352: /**
0353: * Create the factories of the beans (session and MDB).
0354: * @throws EZBContainerException if binding fails.
0355: */
0356: private void createBeanFactories() throws EZBContainerException {
0357: ejbJarInfo = new EJBJarInfo();
0358: // bind session beans
0359: EjbJarAnnotationMetadata ejbMetadata = deployment
0360: .getAnnotationDeploymentAnalyzer()
0361: .getEjbJarAnnotationMetadata();
0362: if (ejbMetadata != null) {
0363: for (ClassAnnotationMetadata bean : ejbMetadata
0364: .getClassAnnotationMetadataCollection()) {
0365: Factory<?, ?> factory = null;
0366: if (bean.isSession()) {
0367: factory = createSessionBeanFactory(bean);
0368: } else if (bean.isMdb()) {
0369: factory = createMessageDrivenBeanFactory(bean);
0370: }
0371:
0372: // Post-Configure the created factories.
0373: if (factory != null) {
0374:
0375: // Adds more runtime info
0376: IBeanInfo beanInfo = factory.getBeanInfo();
0377:
0378: // EJB Name
0379: beanInfo.setName(bean.getJCommonBean().getName());
0380:
0381: // Adds security info.
0382: beanInfo.setSecurityInfo(SecurityInfoHelper
0383: .getSecurityInfo(bean));
0384: ejbJarInfo.addBeanInfo(beanInfo);
0385:
0386: // Build java: Context
0387: Context javaContext;
0388: try {
0389: javaContext = JavaContextHelper.build(bean,
0390: factory);
0391: } catch (JavaContextHelperException e) {
0392: throw new EZBContainerException(
0393: "Cannot build environment", e);
0394: }
0395:
0396: // Set java: context
0397: factory.setJavaContext(javaContext);
0398:
0399: // Add Management
0400: try {
0401: MBeansHelper.getInstance().registerMBean(
0402: factory);
0403: } catch (MBeansException me) {
0404: throw new EZBContainerException(
0405: "Cannot register the factory MBean", me);
0406: }
0407:
0408: // Init factory
0409: try {
0410: factory.init();
0411: } catch (FactoryException e) {
0412: throw new EZBContainerException(
0413: "Cannot initialize the factory.", e);
0414: }
0415:
0416: // Add the factory to the managed factories
0417: factories.put(factory.getClassName(), factory);
0418:
0419: }
0420: }
0421:
0422: // Permission Manager.
0423: try {
0424: permissionManager = new PermissionManager(getArchive()
0425: .getURL(), ejbJarInfo);
0426: // translate metadata into permission
0427: permissionManager.translateMetadata();
0428: // commit
0429: permissionManager.commit();
0430: } catch (PermissionManagerException e) {
0431: throw new EZBContainerException(
0432: "Cannot create permission manager", e);
0433: } catch (ArchiveException e) {
0434: throw new EZBContainerException(
0435: "Cannot create permission manager", e);
0436: }
0437:
0438: }
0439: }
0440:
0441: /**
0442: * Creates the given message driven bean factory.
0443: * @param messageDrivenBean the message driven bean class metadata.
0444: * @throws EZBContainerException if the message driven bean cannot be
0445: * created.
0446: * @return the build factory.
0447: */
0448: private Factory<?, ?> createMessageDrivenBeanFactory(
0449: final ClassAnnotationMetadata messageDrivenBean)
0450: throws EZBContainerException {
0451: String className = messageDrivenBean.getClassName().replace(
0452: "/", ".");
0453:
0454: // get Activation spec object
0455: ActivationSpec activationSpec = null;
0456: try {
0457: activationSpec = (ActivationSpec) new InitialContext()
0458: .lookup(DEFAULT_ACTIVATION_SPEC_NAME);
0459: } catch (NamingException e1) {
0460: throw new EZBContainerException(
0461: "Cannot get the activation spec with the name '"
0462: + DEFAULT_ACTIVATION_SPEC_NAME + "'.");
0463: }
0464:
0465: // Marshall the given object in order to be sure to get a new Object each time
0466: if (activationSpec instanceof Serializable) {
0467: byte[] byteArgs;
0468: try {
0469: byteArgs = storeObject((Serializable) activationSpec);
0470: } catch (IOException e) {
0471: throw new EZBContainerException(
0472: "Cannot serialize the activation spec object '"
0473: + activationSpec + "'.", e);
0474: }
0475:
0476: // Then load object from this array of bytes
0477: try {
0478: activationSpec = (ActivationSpec) loadObject(byteArgs);
0479: } catch (IOException e) {
0480: throw new EZBContainerException(
0481: "Cannot load activation spec from the serialized object.",
0482: e);
0483: } catch (ClassNotFoundException e) {
0484: throw new EZBContainerException(
0485: "Cannot load activation spec from the serialized object.",
0486: e);
0487: }
0488:
0489: }
0490:
0491: // get ResourceAdapter object
0492: ResourceAdapter resourceAdapter = null;
0493: try {
0494: resourceAdapter = MDBResourceAdapterHelper
0495: .getResourceAdapter(DEFAULT_ACTIVATION_SPEC_NAME,
0496: (Embedded) getConfiguration()
0497: .getEZBServer());
0498: } catch (ResourceException e) {
0499: throw new EZBContainerException(
0500: "Cannot get the resource adapter for this MDB factory",
0501: e);
0502: }
0503:
0504: // Associate Resource Adapter with ActivationSpec object (if not set)
0505: if (activationSpec.getResourceAdapter() == null) {
0506: try {
0507: activationSpec.setResourceAdapter(resourceAdapter);
0508: } catch (ResourceException e) {
0509: throw new EZBContainerException(
0510: "Cannot associate resource adapter with activation spec object",
0511: e);
0512: }
0513: }
0514:
0515: // Create factory
0516: MDBMessageEndPointFactory mdbMessageEndPointFactory = null;
0517: try {
0518: mdbMessageEndPointFactory = new MDBMessageEndPointFactory(
0519: className, this , activationSpec, resourceAdapter);
0520: } catch (FactoryException e) {
0521: throw new EZBContainerException(
0522: "Cannot build the MDB MessageEndPoint factory", e);
0523: }
0524:
0525: // build runtime information
0526: MessageDrivenInfo messageDrivenInfo = new MessageDrivenInfo();
0527: messageDrivenInfo.setApplicationExceptions(messageDrivenBean
0528: .getEjbJarAnnotationMetadata()
0529: .getApplicationExceptions());
0530: messageDrivenInfo
0531: .setTransactionManagementType(messageDrivenBean
0532: .getTransactionManagementType());
0533: messageDrivenInfo.setMessageListenerInterface(messageDrivenBean
0534: .getJMessageDriven().getMessageListenerInterface());
0535: messageDrivenInfo
0536: .setActivationConfigProperties(messageDrivenBean
0537: .getJMessageDriven()
0538: .getActivationConfigProperties());
0539: mdbMessageEndPointFactory
0540: .setMessageDrivenInfo(messageDrivenInfo);
0541:
0542: return mdbMessageEndPointFactory;
0543:
0544: }
0545:
0546: /**
0547: * Creates the given session bean and bind it.
0548: * @param sessionBean the session bean class metadata.
0549: * @throws EZBContainerException if the session bean cannot be created
0550: * @return the build factory.
0551: */
0552: private Factory<?, ?> createSessionBeanFactory(
0553: final ClassAnnotationMetadata sessionBean)
0554: throws EZBContainerException {
0555: String className = sessionBean.getClassName().replace("/", ".");
0556:
0557: SessionFactory<?> sessionFactory = null;
0558:
0559: if (sessionBean.isStateless()) {
0560: try {
0561: sessionFactory = new StatelessSessionFactory(className,
0562: this );
0563: } catch (FactoryException fe) {
0564: throw new EZBContainerException(
0565: "Cannot build the stateless factory", fe);
0566: }
0567: } else {
0568: try {
0569: sessionFactory = new StatefulSessionFactory(className,
0570: this );
0571: } catch (FactoryException fe) {
0572: throw new EZBContainerException(
0573: "Cannot build the stateless factory", fe);
0574: }
0575: }
0576:
0577: // build runtime information
0578: SessionBeanInfo sessionBeanInfo = new SessionBeanInfo();
0579: sessionBeanInfo.setTransactionManagementType(sessionBean
0580: .getTransactionManagementType());
0581: sessionBeanInfo.setApplicationExceptions(sessionBean
0582: .getEjbJarAnnotationMetadata()
0583: .getApplicationExceptions());
0584: sessionFactory.setSessionBeanInfo(sessionBeanInfo);
0585:
0586: // get interfaces of bean
0587: JLocal localItfs = sessionBean.getLocalInterfaces();
0588: JRemote remoteItfs = sessionBean.getRemoteInterfaces();
0589:
0590: if (localItfs != null) {
0591: for (String itf : localItfs.getInterfaces()) {
0592: bindingReferences.add(createLocalItfRef(itf,
0593: getEmbedded().getID(), getId(), className,
0594: sessionBean));
0595: }
0596: }
0597: if (remoteItfs != null) {
0598: for (String itf : remoteItfs.getInterfaces()) {
0599: bindingReferences.add(createRemoteItfRef(itf, getId(),
0600: className, sessionBean));
0601: }
0602: }
0603:
0604: // Bind EJB 2.x Home/LocalHome interfaces
0605: String remoteHome = sessionBean.getRemoteHome();
0606: String localHome = sessionBean.getLocalHome();
0607: if (remoteHome != null) {
0608: bindingReferences.add(createRemoteHomeRef(remoteHome,
0609: getId(), className, sessionBean));
0610: }
0611: if (localHome != null) {
0612: bindingReferences.add(createLocalHomeRef(localHome,
0613: getEmbedded().getID(), getId(), className,
0614: sessionBean));
0615: }
0616:
0617: // Sets the factory on the binding references and register them
0618: for (EZBRef reference : bindingReferences) {
0619: // Set factory
0620: reference.setFactory(sessionFactory);
0621:
0622: // Invoke callbacks
0623: List<EZBContainerLifeCycleCallback> lifeCycleCallbacks = getCallbacksLifeCycle();
0624: if (!lifeCycleCallbacks.isEmpty()) {
0625: EZBContainerCallbackInfo info = getContainer3CallbackInfo();
0626: for (EZBContainerLifeCycleCallback lifeCycleCallback : lifeCycleCallbacks) {
0627: try {
0628: lifeCycleCallback.beforeBind(info, reference);
0629: } catch (LifeCycleCallbackException e) {
0630: throw new EZBContainerException(
0631: "Cannot invoke the callback before binding.",
0632: e);
0633: }
0634: }
0635: }
0636:
0637: // Bind it
0638: for (EZBBindingFactory bindingFactory : BindingManager
0639: .getInstance().getFactories()) {
0640: try {
0641: bindingFactory.bind(reference);
0642: } catch (BindingException e) {
0643: logger
0644: .warn(
0645: "Cannot bind the reference ''{0}'' on the binding factory ''{1}'' for the container ''{2}''.",
0646: reference, bindingFactory, this
0647: .getArchive().getName(), e);
0648:
0649: }
0650: }
0651:
0652: }
0653:
0654: return sessionFactory;
0655: }
0656:
0657: /**
0658: * Stop this container.
0659: */
0660: public void stop() {
0661: available = false;
0662:
0663: // Unregister MBean
0664: try {
0665: MBeansHelper.getInstance().unregisterMBean(this );
0666: } catch (MBeansException e) {
0667: // TODO what to do here ? log or exception ?
0668: logger.error("Cannot unregister Container MBeans for "
0669: + getArchive().getName(), e);
0670: }
0671:
0672: // stop each factories
0673: for (Factory<?, ?> f : factories.values()) {
0674: f.stop();
0675:
0676: // Remove MBeans
0677: try {
0678: MBeansHelper.getInstance().unregisterMBean(f);
0679: } catch (MBeansException me) {
0680: logger.error("Cannot unregister the factory MBean", me);
0681: }
0682:
0683: }
0684:
0685: // reset CL
0686: classLoader = null;
0687:
0688: // Send notification to callbacks
0689: if (getCallbacksLifeCycle().size() > 0) {
0690: EZBContainerCallbackInfo info = getContainer3CallbackInfo();
0691: for (EZBContainerLifeCycleCallback callback : getCallbacksLifeCycle()) {
0692: try {
0693: callback.stop(info);
0694: } catch (Throwable t) {
0695: // Protection from malicious code
0696: logger.error("{0}.stop() failed", callback
0697: .getClass().getName(), t);
0698: }
0699: }
0700: }
0701:
0702: // Unbind references
0703: for (EZBRef reference : bindingReferences) {
0704: for (EZBBindingFactory bindingFactory : BindingManager
0705: .getInstance().getFactories()) {
0706: try {
0707: bindingFactory.unbind(reference);
0708: } catch (BindingException e) {
0709: logger
0710: .warn(
0711: "Cannot unbind the reference ''{0}'' on the binding factory ''{1}'' for the container ''{2}''.",
0712: reference, bindingFactory, this
0713: .getArchive().getName(), e);
0714:
0715: }
0716: }
0717: }
0718: }
0719:
0720: /**
0721: * Gets information on the container that can be given to container
0722: * callbacks.
0723: * @return information on the managed container.
0724: */
0725: private EZBContainerCallbackInfo getContainer3CallbackInfo() {
0726: EZBContainerCallbackInfo info = new EZBContainerCallbackInfo();
0727: info.setArchive(getArchive());
0728: info.setFactories(factories);
0729: return info;
0730: }
0731:
0732: /**
0733: * Creates an EJBHome reference and return it.
0734: * @param remoteHome the name of the remote home interface that object will have.
0735: * @param containerID the ID of the container.
0736: * @param factoryName the name of the factory.
0737: * @param bean the bean class associated to given interface.
0738: * @return the reference.
0739: * @throws EZBContainerException if interface cannot be loaded or if the
0740: * bind fails
0741: */
0742: private EZBRef createRemoteHomeRef(final String remoteHome,
0743: final String containerID, final String factoryName,
0744: final ClassAnnotationMetadata bean)
0745: throws EZBContainerException {
0746: String itfClsName = remoteHome.replace("/", ".");
0747: try {
0748: classLoader.loadClass(itfClsName);
0749: } catch (ClassNotFoundException e) {
0750: throw new EZBContainerException("Cannot find the class '"
0751: + remoteHome + "' in Classloader '" + classLoader
0752: + "'.", e);
0753: }
0754:
0755: // get the name of the Remote Interface
0756: String remoteInterface = bean.getRemoteInterface();
0757:
0758: // Build a reference
0759: EJBHomeCallRef ejbHomeCallRef = new EJBHomeCallRef(itfClsName,
0760: containerID, factoryName, bean.isStateful(),
0761: remoteInterface);
0762: String jndiName = jndiNameEncode(bean.getClassName(),
0763: itfClsName, null);
0764:
0765: // Sets the JNDI Name
0766: ejbHomeCallRef.setJNDIName(jndiName);
0767: return ejbHomeCallRef;
0768:
0769: }
0770:
0771: /**
0772: * Creates an EJB Local Home reference and return it.
0773: * @param itf the name of the interface that object will have.
0774: * @param embeddedId the ID of the embedded server.
0775: * @param containerID the ID of the container.
0776: * @param factoryName the name of the factory.
0777: * @param bean the bean class associated to given interface.
0778: * @return the reference.
0779: * @throws EZBContainerException if interface cannot be loaded or if the
0780: * bind fails
0781: */
0782: private EZBRef createLocalHomeRef(final String itf,
0783: final Integer embeddedId, final String containerID,
0784: final String factoryName, final ClassAnnotationMetadata bean)
0785: throws EZBContainerException {
0786: String itfClsName = itf.replace("/", ".");
0787: try {
0788: classLoader.loadClass(itfClsName);
0789: } catch (ClassNotFoundException e) {
0790: throw new EZBContainerException("Cannot find the class '"
0791: + itf + "' in Classloader '" + classLoader + "'.",
0792: e);
0793: }
0794:
0795: // Build a reference
0796: EJBLocalHomeCallRef ejbLocalHomeCallRef = new EJBLocalHomeCallRef(
0797: itfClsName, embeddedId, containerID, factoryName, bean
0798: .isStateful());
0799:
0800: // Sets the JNDI Name
0801: ejbLocalHomeCallRef.setJNDIName(jndiNameEncode(bean
0802: .getClassName(), itfClsName, null));
0803:
0804: return ejbLocalHomeCallRef;
0805: }
0806:
0807: /**
0808: * Creates an EJB Local interface reference and return it.
0809: * @param itf the name of the interface that object will have.
0810: * @param embeddedId the ID of the embedded server.
0811: * @param containerID the ID of the container.
0812: * @param factoryName the name of the factory.
0813: * @param bean the bean class associated to given interface.
0814: * @return the reference.
0815: * @throws EZBContainerException if interface cannot be loaded or if the
0816: * bind fails
0817: */
0818: private EZBRef createLocalItfRef(final String itf,
0819: final Integer embeddedId, final String containerID,
0820: final String factoryName, final ClassAnnotationMetadata bean)
0821: throws EZBContainerException {
0822: String itfClsName = itf.replace("/", ".");
0823: try {
0824: classLoader.loadClass(itfClsName);
0825: } catch (ClassNotFoundException e) {
0826: throw new EZBContainerException("Cannot find the class '"
0827: + itf + "' in Classloader '" + classLoader + "'.",
0828: e);
0829: }
0830:
0831: // Build a reference
0832: LocalCallRef localCallRef = new LocalCallRef(itfClsName,
0833: embeddedId, containerID, factoryName, bean.isStateful());
0834: String jndiName = null;
0835: String mappedName = bean.getJCommonBean().getMappedName();
0836: if (mappedName != null && !"".equals(mappedName)) {
0837: jndiName = mappedName;
0838: } else {
0839: jndiName = jndiNameEncode(bean.getClassName(), itfClsName,
0840: "Local");
0841: }
0842:
0843: // Sets the JNDI Name
0844: localCallRef.setJNDIName(jndiName);
0845:
0846: return localCallRef;
0847: }
0848:
0849: /**
0850: * Creates an EJB Remote interface reference and return it.
0851: * @param itf the name of the interface that object will have.
0852: * @param containerID the ID of the container.
0853: * @param factoryName the name of the factory.
0854: * @param bean the bean class associated to given interface.
0855: * @return the reference.
0856: * @throws EZBContainerException if interface cannot be loaded or if the
0857: * bind fails
0858: */
0859: private EZBRef createRemoteItfRef(final String itf,
0860: final String containerID, final String factoryName,
0861: final ClassAnnotationMetadata bean)
0862: throws EZBContainerException {
0863: String itfClsName = itf.replace("/", ".");
0864: try {
0865: classLoader.loadClass(itfClsName);
0866: } catch (ClassNotFoundException e) {
0867: throw new EZBContainerException("Cannot find the class '"
0868: + itf + "' in Classloader '" + classLoader + "'.",
0869: e);
0870: }
0871:
0872: // Build a reference
0873: RemoteCallRef remoteCallRef = new RemoteCallRef(itfClsName,
0874: containerID, factoryName, bean.isStateful());
0875:
0876: String jndiName = null;
0877: String mappedName = bean.getJCommonBean().getMappedName();
0878: if (mappedName != null && !"".equals(mappedName)) {
0879: jndiName = mappedName;
0880: } else {
0881: jndiName = jndiNameEncode(bean.getClassName(), itfClsName,
0882: "Remote");
0883: }
0884: // Sets the JNDI Name
0885: remoteCallRef.setJNDIName(jndiName);
0886:
0887: return remoteCallRef;
0888: }
0889:
0890: /**
0891: * Gets a factory with its given name.
0892: * @param factoryName the factory name.
0893: * @return the factory found or null.
0894: */
0895: public Factory<?, ?> getFactory(final String factoryName) {
0896: return factories.get(factoryName);
0897: }
0898:
0899: /**
0900: * @return Returns a Collection of managed Factories.
0901: */
0902: public Collection<Factory<?, ?>> getFactories() {
0903: return factories.values();
0904: }
0905:
0906: /**
0907: * Gets the name of this container.
0908: * @return the name.
0909: */
0910: public String getName() {
0911: return getArchive().getName();
0912: }
0913:
0914: /**
0915: * Gets the classloader.
0916: * @return classloader of the container
0917: */
0918: public ClassLoader getClassLoader() {
0919: return classLoader;
0920: }
0921:
0922: /**
0923: * Gets the archive used by this container. It can be a .jar file or a
0924: * directory.
0925: * @return the archive.
0926: */
0927: public IArchive getArchive() {
0928: return configuration.getArchive();
0929: }
0930:
0931: /**
0932: * Gets the parent EZBServer instance.
0933: * @return Returns the Embedded instance.
0934: */
0935: public EZBServer getEmbedded() {
0936: return configuration.getEZBServer();
0937: }
0938:
0939: /**
0940: * @return Returns the LifeCycleCallback(s) instances as a List.
0941: */
0942: private List<EZBContainerLifeCycleCallback> getCallbacksLifeCycle() {
0943: return configuration.getCallbacks();
0944: }
0945:
0946: /**
0947: * Check if the container is available or not.
0948: * @return true if the container is available.
0949: */
0950: public boolean isAvailable() {
0951: return available;
0952: }
0953:
0954: /**
0955: * Gets the persistence manager object which manages all persistence-unit
0956: * associated to this container.
0957: * @return persistence unit manager object
0958: */
0959: public EZBPersistenceUnitManager getPersistenceUnitManager() {
0960: return persistenceUnitManager;
0961: }
0962:
0963: /**
0964: * Encode a given name by prefixing it with given mode.
0965: * @param beanClassName name of the bean class.
0966: * @param itfName name of the interface.
0967: * @param mode local/remote, etc
0968: * @return encoded jndi Name
0969: */
0970: public static String jndiNameEncode(final String beanClassName,
0971: final String itfName, final String mode) {
0972: String suffix = "";
0973: if (mode != null) {
0974: suffix = "@" + mode;
0975: }
0976: return beanClassName.replace("/", ".") + "_"
0977: + itfName.replace("/", ".") + suffix;
0978: }
0979:
0980: /**
0981: * Sets the classloader.
0982: * @param classLoader to be used by the container
0983: */
0984: public void setClassLoader(final ClassLoader classLoader) {
0985: if (this .classLoader != null) {
0986: throw new IllegalArgumentException(
0987: "Cannot replace an existing classloader");
0988: }
0989: this .classLoader = classLoader;
0990: }
0991:
0992: /**
0993: * Sets the persistence manager object which manages all persistence-unit
0994: * associated to this container.
0995: * @param persistenceUnitManager persistence unit manager object to set.
0996: */
0997: public void setPersistenceUnitManager(
0998: final EZBPersistenceUnitManager persistenceUnitManager) {
0999: if (this .persistenceUnitManager != null) {
1000: throw new IllegalArgumentException(
1001: "Cannot replace an existing persistenceUnitManager");
1002: }
1003: this .persistenceUnitManager = persistenceUnitManager;
1004: }
1005:
1006: /**
1007: * @return Returns the Container Configuration.
1008: */
1009: public EZBContainerConfig getConfiguration() {
1010: return this .configuration;
1011: }
1012:
1013: /**
1014: * Gets the permission manager (that manages EJB permissions).
1015: * @return permission manager.
1016: */
1017: public EZBPermissionManager getPermissionManager() {
1018: return permissionManager;
1019: }
1020:
1021: /**
1022: * Sets the permission manager (that manages EJB permissions).
1023: * @param ezbPermissionManager the EasyBeans permission manager.
1024: */
1025: public void setPermissionManager(
1026: final EZBPermissionManager ezbPermissionManager) {
1027: this .permissionManager = ezbPermissionManager;
1028: }
1029:
1030: /**
1031: * Sets the Application Name of this container (EAR case).
1032: * @param applicationName the name of the application of this container.
1033: */
1034: public void setApplicationName(final String applicationName) {
1035: this .applicationName = applicationName;
1036: }
1037:
1038: /**
1039: * Gets the Application Name of this container (EAR case).
1040: * @return the name of the application of this container.
1041: */
1042: public String getApplicationName() {
1043: return applicationName;
1044: }
1045:
1046: /**
1047: * Add extra archives for finding classes.
1048: * @param extraArchives the given archives.
1049: */
1050: public void setExtraArchives(final List<IArchive> extraArchives) {
1051: this.deployment.setExtraArchives(extraArchives);
1052: }
1053:
1054: }
|