[jboss-cvs] JBossAS SVN: r99550 - in projects/ejb3/trunk/nointerface/src: main/java/org/jboss/ejb3/nointerface/deployers and 15 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Jan 18 13:42:27 EST 2010
Author: jaikiran
Date: 2010-01-18 13:42:26 -0500 (Mon, 18 Jan 2010)
New Revision: 99550
Added:
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/deployers/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/deployers/EJB3NoInterfaceDeployer.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/invocationhandler/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/invocationhandler/NoInterfaceViewInvocationHandler.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/AbstractNoInterfaceViewJNDIBinder.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/NoInterfaceViewJNDIBinderFacade.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/StatefulNoInterfaceJNDIBinder.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/StatelessNoInterfaceJNDIBinder.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/metadata/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/metadata/processor/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/metadata/processor/ImplicitNoInterfaceViewMetadataProcessorFactory.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/NoInterfaceViewProxyFactoryRefAddrTypes.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/StatefulNoInterfaceViewObjectFactory.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/JavassistNoInterfaceViewFactory.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/StatefulNoInterfaceViewFacade.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/jndi/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/jndi/NoInterfaceViewJNDIBinder.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/view/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/view/factory/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/view/factory/NoInterfaceViewFactory.java
Removed:
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/deployers/EJB3NoInterfaceDeployer.java
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/factory/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/invocationhandler/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/mc/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/metadata/
projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/objectfactory/
Modified:
projects/ejb3/trunk/nointerface/src/main/resources/META-INF/ejb3-nointerface-jboss-beans.xml
projects/ejb3/trunk/nointerface/src/test/java/org/jboss/ejb3/nointerface/test/factory/unit/NoInterfaceViewFactoryTestCase.java
Log:
EJBTHREE-1989 Refactor the package names and classes to pave the way for creating a spi and an impl module for the nointerface component
Deleted: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/deployers/EJB3NoInterfaceDeployer.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/deployers/EJB3NoInterfaceDeployer.java 2010-01-18 18:29:32 UTC (rev 99549)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/deployers/EJB3NoInterfaceDeployer.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -1,411 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.nointerface.deployers;
-
-import java.io.Externalizable;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.ejb.LocalBean;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.naming.InitialContext;
-
-import org.jboss.beans.metadata.api.model.FromContext;
-import org.jboss.beans.metadata.plugins.AbstractInjectionValueMetaData;
-import org.jboss.beans.metadata.spi.BeanMetaData;
-import org.jboss.beans.metadata.spi.builder.BeanMetaDataBuilder;
-import org.jboss.dependency.spi.ControllerState;
-import org.jboss.deployers.spi.DeploymentException;
-import org.jboss.deployers.spi.deployer.DeploymentStages;
-import org.jboss.deployers.spi.deployer.helpers.AbstractDeployer;
-import org.jboss.deployers.structure.spi.DeploymentUnit;
-import org.jboss.ejb3.deployers.Ejb3MetadataProcessingDeployer;
-import org.jboss.ejb3.nointerface.mc.NoInterfaceViewJNDIBinder;
-import org.jboss.logging.Logger;
-import org.jboss.metadata.ear.jboss.JBossAppMetaData;
-import org.jboss.metadata.ejb.jboss.JBossEnterpriseBeanMetaData;
-import org.jboss.metadata.ejb.jboss.JBossEnterpriseBeansMetaData;
-import org.jboss.metadata.ejb.jboss.JBossMetaData;
-import org.jboss.metadata.ejb.jboss.JBossSessionBean31MetaData;
-import org.jboss.metadata.ejb.jboss.JBossSessionBeanMetaData;
-
-/**
- * EJB3NoInterfaceDeployer
- *
- * Deployer responsible for processing EJB3 deployments with a no-interface view.
- * @see #deploy(DeploymentUnit) for the deployment unit processing details.
- *
- * @author Jaikiran Pai
- * @version $Revision: $
- */
-public class EJB3NoInterfaceDeployer extends AbstractDeployer
-{
-
- /**
- * Logger
- */
- private static Logger logger = Logger.getLogger(EJB3NoInterfaceDeployer.class);
-
- /**
- * We need processed metadata
- */
- private static final String INPUT = Ejb3MetadataProcessingDeployer.OUTPUT;
-
- /**
- * Constructor
- */
- public EJB3NoInterfaceDeployer()
- {
- setStage(DeploymentStages.REAL);
- setInput(JBossMetaData.class);
- addInput(INPUT);
- // we deploy MC beans
- addOutput(BeanMetaData.class);
-
- }
-
- /**
- * Process the deployment unit and deploy appropriate MC beans (see details below)
- * if it corresponds to a no-interface view deployment.
- *
- * If any beans in the unit are eligible for no-interface view, then internally this method
- * creates a {@link NoInterfaceViewJNDIBinder} MC bean for the no-interface view.
- *
- * The {@link NoInterfaceViewJNDIBinder}, thus created, will be dependent on the {@link ControllerState#DESCRIBED}
- * state of the container (endpoint) MC bean. This way, we ensure that this {@link NoInterfaceViewJNDIBinder}
- * will be deployed only after the corresponding container MC bean moves to {@link ControllerState#DESCRIBED}
- * state.
- */
- public void deploy(DeploymentUnit unit) throws DeploymentException
- {
-
- if (logger.isTraceEnabled())
- {
- logger.trace("Deploying unit " + unit.getName());
- }
- // get processed metadata
- JBossMetaData metaData = unit.getAttachment(INPUT, JBossMetaData.class);
- if (metaData == null)
- {
- if (logger.isTraceEnabled())
- logger.trace("No JBossMetadata for unit : " + unit.getName());
- return;
- }
- // work on the ejbs
- JBossEnterpriseBeansMetaData beans = metaData.getEnterpriseBeans();
- for (JBossEnterpriseBeanMetaData bean : beans)
- {
- if (bean.isSession())
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Found bean of type session: " + bean.getEjbClass() + " in unit " + unit.getName());
- }
- // too bad
- if (bean instanceof JBossSessionBean31MetaData)
- {
- // Process for no-interface view
- deploy(unit, (JBossSessionBean31MetaData) bean);
- }
- }
- }
-
- }
-
- /**
- * Creates a {@link NoInterfaceViewJNDIBinder} MC bean for the no-interface view represented by the
- * <code>sessionBeanMetaData</code>. The {@link NoInterfaceViewJNDIBinder} is created only
- * if the bean is eligible for a no-interface view as defined by the EJB3.1 spec
- *
- * The {@link NoInterfaceViewJNDIBinder}, thus created, will be dependent on the {@link ControllerState#DESCRIBED}
- * state of the container (endpoint) MC bean. This way, we ensure that this {@link NoInterfaceViewJNDIBinder}
- * will be deployed only after the corresponding container MC bean moves to {@link ControllerState#DESCRIBED}
- * state.
- *
- * @param unit Deployment unit
- * @param sessionBeanMetaData Session bean metadata
- * @throws DeploymentException If any exceptions are encountered during processing of the deployment unit
- */
- private void deploy(DeploymentUnit unit, JBossSessionBean31MetaData sessionBeanMetaData) throws DeploymentException
- {
- try
- {
- if (!sessionBeanMetaData.isNoInterfaceBean())
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Bean class " + sessionBeanMetaData.getEjbClass() + " is not eligible for no-interface view");
- }
- return;
- }
- Class<?> beanClass = Class.forName(sessionBeanMetaData.getEjbClass(), false, unit.getClassLoader());
-
- String containerMCBeanName = sessionBeanMetaData.getContainerName();
- if (logger.isTraceEnabled())
- {
- logger.trace("Container name for bean " + sessionBeanMetaData.getEjbName() + " in unit " + unit + " is "
- + containerMCBeanName);
- }
- if (containerMCBeanName == null)
- {
- // The container name is set in the metadata only after the creation of the container
- // However, this deployer does not have an dependency on the creation of a container,
- // so getting the container name from the bean metadata won't work. Need to do a different/better way
- //String containerMCBeanName = sessionBeanMetaData.getContainerName();
- containerMCBeanName = getContainerName(unit, sessionBeanMetaData);
-
- }
-
- // Create the NoInterfaceViewJNDIBinder (MC bean) and add a dependency on the DESCRIBED
- // state of the container (endpoint) MC bean
- NoInterfaceViewJNDIBinder<JBossSessionBean31MetaData> noInterfaceViewJNDIBinder = NoInterfaceViewJNDIBinder.getNoInterfaceViewJndiBinder(new InitialContext(), beanClass,
- sessionBeanMetaData);
- String noInterfaceViewMCBeanName = unit.getName() + "$" + sessionBeanMetaData.getEjbName();
- BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(noInterfaceViewMCBeanName, noInterfaceViewJNDIBinder.getClass()
- .getName());
- builder.setConstructorValue(noInterfaceViewJNDIBinder);
-
- // add dependency
- AbstractInjectionValueMetaData injectMetaData = new AbstractInjectionValueMetaData(containerMCBeanName);
- injectMetaData.setDependentState(ControllerState.DESCRIBED);
- injectMetaData.setFromContext(FromContext.CONTEXT);
-
- // Too bad we have to know the field name. Need to do more research on MC to see if we can
- // add property metadata based on type instead of field name.
- builder.addPropertyMetaData("endpointContext", injectMetaData);
-
- // Add this as an attachment
- unit.addAttachment(BeanMetaData.class + ":" + noInterfaceViewMCBeanName, builder.getBeanMetaData());
-
- logger.debug("No-interface JNDI binder for container " + containerMCBeanName + " has been created and added to the deployment unit " + unit);
-
- }
- catch (Throwable t)
- {
- DeploymentException.rethrowAsDeploymentException("Could not create no-interface view for "
- + sessionBeanMetaData.getEjbClass() + " in unit " + unit.getName(), t);
- }
- }
-
- /**
- * Undeploy
- *
- * @param unit
- * @param deployment
- */
- public void undeploy(DeploymentUnit unit, JBossMetaData deployment)
- {
- // TODO Needs implementation
-
- }
-
- /**
- * See section 4.9.8 (bullet 1) of the EJB3.1 spec for eligibility of
- * a bean for no-interface view
- *
- * @param sessionBeanMetadata
- * @return
- */
- private boolean isEligibleForNoInterfaceView(DeploymentUnit unit, JBossSessionBeanMetaData sessionBeanMetadata)
- throws Exception
- {
-
- // if the bean has a @LocalBean defined, then it qualifies for a no-interface view
- // irrespective of the other rules.
- //TODO: The JBMETA does not yet support @LocalBean so let's HACK it for now
- String ejbClassName = sessionBeanMetadata.getEjbClass();
- Class<?> beanClass = Class.forName(ejbClassName, false, unit.getClassLoader());
- if (beanClass.getAnnotation(LocalBean.class) != null) //sessionBeanMetadata.getLocalBean())
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Bean class " + ejbClassName + " in unit " + unit + " is marked as @LocalBean");
- }
- return true;
- }
-
- // If there are any local business interfaces then its not eligible
- if (sessionBeanMetadata.getBusinessLocals() != null && !sessionBeanMetadata.getBusinessLocals().isEmpty())
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Bean " + sessionBeanMetadata.getEjbClass()
- + " has business local, hence not eligible for no-interface view");
- }
- return false;
- }
-
- // If there are any remote business interfaces then its not eligible
- if (sessionBeanMetadata.getBusinessRemotes() != null && !sessionBeanMetadata.getBusinessRemotes().isEmpty())
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Bean " + sessionBeanMetadata.getEjbClass()
- + " has business remote, hence not eligible for no-interface view");
- }
-
- return false;
- }
-
- // If it has a 2.x home or local home view, then its not eligible
- if (sessionBeanMetadata.getHome() != null || sessionBeanMetadata.getLocalHome() != null)
- {
- if (logger.isTraceEnabled())
- {
- logger.trace("Bean " + sessionBeanMetadata.getEjbClass()
- + " has 2.x home/local-home, hence not eligible for no-interface view");
- }
-
- return false;
- }
-
- // Check if the bean implements any interfaces
- if (doesBeanImplementAnyInterfaces(beanClass))
- {
- if (logger.isTraceEnabled())
- {
- logger
- .trace("Bean "
- + sessionBeanMetadata.getEjbClass()
- + " implements interfaces (other than the one's excluded as per section 4.9.8 of EJB3.1 spec), hence not eligible for no-interface view");
- }
- return false;
- }
- // The bean satisfies the pre-requisites of a no-interface view.
- return true;
-
- }
-
- /**
- * Checks whether the bean class implements any interfaces other than
- * {@link Serializable} or {@link Externalizable} or anything from javax.ejb.* packages.
- *
- * @param beanClass
- * @return Returns true if the bean implements any interface(s) other than {@link Serializable}
- * or {@link Externalizable} or anything from javax.ejb.* packages.
- *
- */
- private boolean doesBeanImplementAnyInterfaces(Class<?> beanClass)
- {
- Class<?>[] interfaces = beanClass.getInterfaces();
- if (interfaces.length == 0)
- {
- return false;
- }
-
- // As per section 4.9.8 (bullet 1.3) of EJB3.1 spec
- // java.io.Serializable; java.io.Externalizable; any of the interfaces defined by the javax.ejb
- // are excluded from interface check
-
- // Impl detail : We need an ArrayList because it supports removing of elements through iterator, while
- // iterating. The List returned through Arrays.asList(...) does not allow this and throws UnsupportedException
- List<Class<?>> implementedInterfaces = new ArrayList<Class<?>>(Arrays.asList(interfaces));
- Iterator<Class<?>> implementedInterfacesIterator = implementedInterfaces.iterator();
- while (implementedInterfacesIterator.hasNext())
- {
- Class<?> implementedInterface = implementedInterfacesIterator.next();
- if (implementedInterface.equals(java.io.Serializable.class)
- || implementedInterface.equals(java.io.Externalizable.class)
- || implementedInterface.getName().startsWith("javax.ejb."))
- {
- implementedInterfacesIterator.remove();
- }
- }
- // Now that we have removed the interfaces that should be excluded from the check,
- // if the implementedInterfaces collection is empty then this bean can be considered for no-interface view
- return !implementedInterfaces.isEmpty();
- }
-
- /**
- * Ultimately, the container name should come from the <code>sessionBeanMetadata</code>.
- * However because of the current behaviour where the container on its start sets the containername
- * in the metadata, its not possible to get this information even before the container is started.
- *
- * Hence let's for the time being create the container name from all the information that we have
- * in the <code>unit</code>
- *
- * @param unit The deployment unit
- * @param sessionBeanMetadata Session bean metadata
- * @return Returns the container name for the bean corresponding to the <code>sessionBeanMetadata</code> in the <code>unit</code>
- *
- * @throws MalformedObjectNameException
- */
- private String getContainerName(DeploymentUnit unit, JBossSessionBeanMetaData sessionBeanMetadata)
- throws MalformedObjectNameException
- {
- // TODO the base ejb3 jmx object name comes from Ejb3Module.BASE_EJB3_JMX_NAME, but
- // we don't need any reference to ejb3-core. Right now just hard code here, we need
- // a better way/place for this later
- StringBuilder containerName = new StringBuilder("jboss.j2ee:service=EJB3" + ",");
-
- // Get the top level unit for this unit (ex: the top level might be an ear and this unit might be the jar
- // in that ear
- DeploymentUnit toplevelUnit = unit.getTopLevel();
- if (toplevelUnit != null)
- {
- // if top level is an ear, then create the name with the ear reference
- if (isEar(toplevelUnit))
- {
- containerName.append("ear=");
- containerName.append(toplevelUnit.getSimpleName());
- containerName.append(",");
-
- }
- }
- // now work on the passed unit, to get the jar name
- if (unit.getSimpleName() == null)
- {
- containerName.append("*");
- }
- else
- {
- containerName.append("jar=");
- containerName.append(unit.getSimpleName());
- }
- // now the ejbname
- containerName.append(",name=");
- containerName.append(sessionBeanMetadata.getEjbName());
-
- if (logger.isTraceEnabled())
- {
- logger.trace("Container name generated for ejb = " + sessionBeanMetadata.getEjbName() + " in unit " + unit
- + " is " + containerName);
- }
- ObjectName containerJMXName = new ObjectName(containerName.toString());
- return containerJMXName.getCanonicalName();
- }
-
- /**
- * Returns true if this <code>unit</code> represents an .ear deployment
- *
- * @param unit
- * @return
- */
- private boolean isEar(DeploymentUnit unit)
- {
- return unit.getSimpleName().endsWith(".ear") || unit.getAttachment(JBossAppMetaData.class) != null;
- }
-}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/deployers/EJB3NoInterfaceDeployer.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/deployers/EJB3NoInterfaceDeployer.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/deployers/EJB3NoInterfaceDeployer.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,288 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.nointerface.impl.deployers;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.naming.InitialContext;
+
+import org.jboss.beans.metadata.api.model.FromContext;
+import org.jboss.beans.metadata.plugins.AbstractInjectionValueMetaData;
+import org.jboss.beans.metadata.spi.BeanMetaData;
+import org.jboss.beans.metadata.spi.builder.BeanMetaDataBuilder;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.spi.deployer.DeploymentStages;
+import org.jboss.deployers.spi.deployer.helpers.AbstractDeployer;
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+import org.jboss.ejb3.deployers.Ejb3MetadataProcessingDeployer;
+import org.jboss.ejb3.nointerface.impl.jndi.NoInterfaceViewJNDIBinderFacade;
+import org.jboss.logging.Logger;
+import org.jboss.metadata.ear.jboss.JBossAppMetaData;
+import org.jboss.metadata.ejb.jboss.JBossEnterpriseBeanMetaData;
+import org.jboss.metadata.ejb.jboss.JBossEnterpriseBeansMetaData;
+import org.jboss.metadata.ejb.jboss.JBossMetaData;
+import org.jboss.metadata.ejb.jboss.JBossSessionBean31MetaData;
+import org.jboss.metadata.ejb.jboss.JBossSessionBeanMetaData;
+
+/**
+ * EJB3NoInterfaceDeployer
+ *
+ * Deployer responsible for processing EJB3 deployments with a no-interface view.
+ * @see #deploy(DeploymentUnit) for the deployment unit processing details.
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class EJB3NoInterfaceDeployer extends AbstractDeployer
+{
+
+ /**
+ * Logger
+ */
+ private static Logger logger = Logger.getLogger(EJB3NoInterfaceDeployer.class);
+
+ /**
+ * We need processed metadata
+ */
+ private static final String INPUT = Ejb3MetadataProcessingDeployer.OUTPUT;
+
+ /**
+ * Constructor
+ */
+ public EJB3NoInterfaceDeployer()
+ {
+ setStage(DeploymentStages.REAL);
+ setInput(JBossMetaData.class);
+ addInput(INPUT);
+ // we deploy MC beans
+ addOutput(BeanMetaData.class);
+
+ }
+
+ /**
+ * Process the deployment unit and deploy appropriate MC beans (see details below)
+ * if it corresponds to a no-interface view deployment.
+ *
+ * If any beans in the unit are eligible for no-interface view, then internally this method
+ * creates a {@link NoInterfaceViewJNDIBinderFacade} MC bean for the no-interface view.
+ *
+ * The {@link NoInterfaceViewJNDIBinderFacade}, thus created, will be dependent on the {@link ControllerState#DESCRIBED}
+ * state of the container (endpoint) MC bean. This way, we ensure that this {@link NoInterfaceViewJNDIBinderFacade}
+ * will be deployed only after the corresponding container MC bean moves to {@link ControllerState#DESCRIBED}
+ * state.
+ */
+ public void deploy(DeploymentUnit unit) throws DeploymentException
+ {
+
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Deploying unit " + unit.getName());
+ }
+ // get processed metadata
+ JBossMetaData metaData = unit.getAttachment(INPUT, JBossMetaData.class);
+ if (metaData == null)
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("No JBossMetadata for unit : " + unit.getName());
+ return;
+ }
+ // work on the ejbs
+ JBossEnterpriseBeansMetaData beans = metaData.getEnterpriseBeans();
+ for (JBossEnterpriseBeanMetaData bean : beans)
+ {
+ if (bean.isSession())
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Found bean of type session: " + bean.getEjbClass() + " in unit " + unit.getName());
+ }
+ // too bad
+ if (bean instanceof JBossSessionBean31MetaData)
+ {
+ // Process for no-interface view
+ deploy(unit, (JBossSessionBean31MetaData) bean);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Creates a {@link NoInterfaceViewJNDIBinderFacade} MC bean for the no-interface view represented by the
+ * <code>sessionBeanMetaData</code>. The {@link NoInterfaceViewJNDIBinderFacade} is created only
+ * if the bean is eligible for a no-interface view as defined by the EJB3.1 spec
+ *
+ * The {@link NoInterfaceViewJNDIBinderFacade}, thus created, will be dependent on the {@link ControllerState#DESCRIBED}
+ * state of the container (endpoint) MC bean. This way, we ensure that this {@link NoInterfaceViewJNDIBinderFacade}
+ * will be deployed only after the corresponding container MC bean moves to {@link ControllerState#DESCRIBED}
+ * state.
+ *
+ * @param unit Deployment unit
+ * @param sessionBeanMetaData Session bean metadata
+ * @throws DeploymentException If any exceptions are encountered during processing of the deployment unit
+ */
+ private void deploy(DeploymentUnit unit, JBossSessionBean31MetaData sessionBeanMetaData) throws DeploymentException
+ {
+ try
+ {
+ if (!sessionBeanMetaData.isNoInterfaceBean())
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Bean class " + sessionBeanMetaData.getEjbClass()
+ + " is not eligible for no-interface view");
+ }
+ return;
+ }
+ Class<?> beanClass = Class.forName(sessionBeanMetaData.getEjbClass(), false, unit.getClassLoader());
+
+ String containerMCBeanName = sessionBeanMetaData.getContainerName();
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Container name for bean " + sessionBeanMetaData.getEjbName() + " in unit " + unit + " is "
+ + containerMCBeanName);
+ }
+ if (containerMCBeanName == null)
+ {
+ // The container name is set in the metadata only after the creation of the container
+ // However, this deployer does not have an dependency on the creation of a container,
+ // so getting the container name from the bean metadata won't work. Need to do a different/better way
+ //String containerMCBeanName = sessionBeanMetaData.getContainerName();
+ containerMCBeanName = getContainerName(unit, sessionBeanMetaData);
+
+ }
+
+ // Create the NoInterfaceViewJNDIBinder (MC bean) and add a dependency on the DESCRIBED
+ // state of the container (endpoint) MC bean
+ NoInterfaceViewJNDIBinderFacade noInterfaceViewJNDIBinderFacade = new NoInterfaceViewJNDIBinderFacade(
+ new InitialContext(), beanClass, sessionBeanMetaData);
+ String noInterfaceViewMCBeanName = unit.getName() + "$" + sessionBeanMetaData.getEjbName();
+ BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(noInterfaceViewMCBeanName,
+ noInterfaceViewJNDIBinderFacade.getClass().getName());
+ builder.setConstructorValue(noInterfaceViewJNDIBinderFacade);
+
+ // add dependency
+ AbstractInjectionValueMetaData injectMetaData = new AbstractInjectionValueMetaData(containerMCBeanName);
+ injectMetaData.setDependentState(ControllerState.DESCRIBED);
+ injectMetaData.setFromContext(FromContext.CONTEXT);
+
+ // Too bad we have to know the field name. Need to do more research on MC to see if we can
+ // add property metadata based on type instead of field name.
+ builder.addPropertyMetaData("endpointContext", injectMetaData);
+
+ // Add this as an attachment
+ unit.addAttachment(BeanMetaData.class + ":" + noInterfaceViewMCBeanName, builder.getBeanMetaData());
+
+ logger.debug("No-interface JNDI binder for container " + containerMCBeanName
+ + " has been created and added to the deployment unit " + unit);
+
+ }
+ catch (Throwable t)
+ {
+ DeploymentException.rethrowAsDeploymentException("Could not create no-interface view for "
+ + sessionBeanMetaData.getEjbClass() + " in unit " + unit.getName(), t);
+ }
+ }
+
+ /**
+ * Undeploy
+ *
+ * @param unit
+ * @param deployment
+ */
+ public void undeploy(DeploymentUnit unit, JBossMetaData deployment)
+ {
+ // TODO Needs implementation
+
+ }
+
+ /**
+ * Ultimately, the container name should come from the <code>sessionBeanMetadata</code>.
+ * However because of the current behaviour where the container on its start sets the containername
+ * in the metadata, its not possible to get this information even before the container is started.
+ *
+ * Hence let's for the time being create the container name from all the information that we have
+ * in the <code>unit</code>
+ *
+ * @param unit The deployment unit
+ * @param sessionBeanMetadata Session bean metadata
+ * @return Returns the container name for the bean corresponding to the <code>sessionBeanMetadata</code> in the <code>unit</code>
+ *
+ * @throws MalformedObjectNameException
+ */
+ private String getContainerName(DeploymentUnit unit, JBossSessionBeanMetaData sessionBeanMetadata)
+ throws MalformedObjectNameException
+ {
+ // TODO the base ejb3 jmx object name comes from Ejb3Module.BASE_EJB3_JMX_NAME, but
+ // we don't need any reference to ejb3-core. Right now just hard code here, we need
+ // a better way/place for this later
+ StringBuilder containerName = new StringBuilder("jboss.j2ee:service=EJB3" + ",");
+
+ // Get the top level unit for this unit (ex: the top level might be an ear and this unit might be the jar
+ // in that ear
+ DeploymentUnit toplevelUnit = unit.getTopLevel();
+ if (toplevelUnit != null)
+ {
+ // if top level is an ear, then create the name with the ear reference
+ if (isEar(toplevelUnit))
+ {
+ containerName.append("ear=");
+ containerName.append(toplevelUnit.getSimpleName());
+ containerName.append(",");
+
+ }
+ }
+ // now work on the passed unit, to get the jar name
+ if (unit.getSimpleName() == null)
+ {
+ containerName.append("*");
+ }
+ else
+ {
+ containerName.append("jar=");
+ containerName.append(unit.getSimpleName());
+ }
+ // now the ejbname
+ containerName.append(",name=");
+ containerName.append(sessionBeanMetadata.getEjbName());
+
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Container name generated for ejb = " + sessionBeanMetadata.getEjbName() + " in unit " + unit
+ + " is " + containerName);
+ }
+ ObjectName containerJMXName = new ObjectName(containerName.toString());
+ return containerJMXName.getCanonicalName();
+ }
+
+ /**
+ * Returns true if this <code>unit</code> represents an .ear deployment
+ *
+ * @param unit
+ * @return
+ */
+ private boolean isEar(DeploymentUnit unit)
+ {
+ return unit.getSimpleName().endsWith(".ear") || unit.getAttachment(JBossAppMetaData.class) != null;
+ }
+}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/invocationhandler/NoInterfaceViewInvocationHandler.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/invocationhandler/NoInterfaceViewInvocationHandler.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/invocationhandler/NoInterfaceViewInvocationHandler.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,346 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.nointerface.impl.invocationhandler;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.ejb3.endpoint.Endpoint;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.logging.Logger;
+
+/**
+ * NoInterfaceViewInvocationHandler
+ *
+ * An {@link InvocationHandler} which corresponds to the
+ * no-interface view of a EJB container. All calls on the no-interface
+ * view are routed through this {@link InvocationHandler} to the container.
+ *
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class NoInterfaceViewInvocationHandler implements InvocationHandler
+{
+
+ /**
+ * Equals and hashCode methods are handled within this invocation handler
+ */
+ private static final Method METHOD_EQUALS;
+
+ private static final Method METHOD_HASH_CODE;
+
+ private static final Method METHOD_TO_STRING;
+
+ static
+ {
+ try
+ {
+ METHOD_EQUALS = Object.class.getDeclaredMethod("equals", Object.class);
+ METHOD_HASH_CODE = Object.class.getDeclaredMethod("hashCode");
+ METHOD_TO_STRING = Object.class.getDeclaredMethod("toString");
+ }
+ catch (SecurityException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ /**
+ * Logger
+ */
+ private static Logger logger = Logger.getLogger(NoInterfaceViewInvocationHandler.class);
+
+ /**
+ * The KernelControllerContext corresponding to the endpoint for which
+ * the no-interface view is to be created by this factory. This context
+ * may <i>not</i> be in INSTALLED state. This factory is responsible
+ * for pushing it to INSTALLED state whenever necessary.
+ *
+ * All calls to this invocation handler will be forwarded to the container represented
+ * by this context
+ *
+ *
+ */
+ private KernelControllerContext endpointContext;
+
+ /**
+ * The session used to interact with the {@link Endpoint}
+ */
+ private Serializable session;
+
+ /**
+ * Constructor
+ * @param container
+ */
+ public NoInterfaceViewInvocationHandler(KernelControllerContext endpointContext, Serializable session)
+ {
+ assert endpointContext != null : "Endpoint context is null for no-interface view invocation handler";
+ this.endpointContext = endpointContext;
+ this.session = session;
+ }
+
+ /**
+ * The entry point when a client calls any methods on the no-interface view of a bean,
+ * returned through JNDI.
+ *
+ *
+ * @param proxy
+ * @param method The invoked method
+ * @param args The arguments to the method
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ // handle equals() and hashCode() in this InvocationHandler
+ try
+ {
+ return handleDirectly(proxy, method, args);
+ }
+ catch (CannotHandleDirectlyException chde)
+ {
+ //ignore
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Cannot handle method: " + method.getName() + " in " + this.getClass().getName());
+ }
+ }
+ // get the endpoint (which will involve pushing it to INSTALLED state)
+ Endpoint endpoint = getInstalledEndpoint();
+ assert endpoint != null : "No endpoint associated with context " + this.endpointContext
+ + " - cannot invoke the method on bean";
+
+ // finally pass-on the control to the endpoint
+ return endpoint.invoke(this.session, null, method, args);
+ }
+
+ /**
+ * Returns the context corresponding to the container, associated with this invocation handler
+ *
+ * @return
+ */
+ public KernelControllerContext getContainerContext()
+ {
+ return this.endpointContext;
+ }
+
+ /**
+ * Returns the {@link Endpoint} container corresponding to this
+ * {@link NoInterfaceViewInvocationHandler}. Internally, the {@link Endpoint}
+ * will be first pushed to the INSTALLED state
+ *
+ * @return
+ */
+ public Endpoint getInstalledEndpoint()
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Pushing the endpoint context to INSTALLED state from its current state = "
+ + this.endpointContext.getState().getStateString());
+ }
+ try
+ {
+ // first push the context corresponding to the endpoint to INSTALLED
+ this.endpointContext.getController().change(this.endpointContext, ControllerState.INSTALLED);
+ // get hold of the endpoint from its context
+ Endpoint endpoint = (Endpoint) this.endpointContext.getTarget();
+ return endpoint;
+ }
+ catch (Throwable t)
+ {
+ throw new RuntimeException("Error getting endpoint out of container KernelControllerContext "
+ + this.endpointContext, t);
+ }
+
+ }
+
+ /**
+ * Returns the {@link Endpoint} container corresponding to this
+ * {@link NoInterfaceViewInvocationHandler}. Note that this method does NOT
+ * change the state of the KernelControllerContext of this Endpoint. As such,
+ * the Endpoint returned by this method is NOT guaranteed to be in INSTALLED state.
+ * If the Endpoint with INSTALLED state is required, then use the {@link #getInstalledEndpoint()}
+ * method.
+ *
+ * @return
+ * @see #getInstalledEndpoint()
+ */
+ private Endpoint getEndpoint()
+ {
+ Object endpoint = this.endpointContext.getTarget();
+ assert endpoint instanceof Endpoint : "Unexpected type " + endpoint.getClass().getName() + " found in context "
+ + this.endpointContext + " Expected " + Endpoint.class.getName();
+ return (Endpoint) endpoint;
+ }
+
+ /**
+ * @see Object#equals(Object)
+ */
+ @Override
+ public boolean equals(Object other)
+ {
+ // simple object comparison
+ if (this == other)
+ {
+ return true;
+ }
+
+ // equals() method contract specifies that if the other object is null
+ // then equals() should return false
+ if (other == null)
+ {
+ return false;
+ }
+
+ // If the other object is not an instance of MCAwareNoInterfaceViewInvocationHandler
+ // then they are not equal
+ if (!(other instanceof NoInterfaceViewInvocationHandler))
+ {
+ return false;
+ }
+
+ NoInterfaceViewInvocationHandler otherNoInterfaceViewInvocationHandler = (NoInterfaceViewInvocationHandler) other;
+
+ // First check whether the Endpoints of both these InvocationHandlers are equal. If
+ // not, then no need for any further comparison, just return false
+ if (!(this.getInstalledEndpoint().equals(otherNoInterfaceViewInvocationHandler.getInstalledEndpoint())))
+ {
+ return false;
+ }
+
+ // If the endpoints are equal, then let's next check whether the sessions for
+ // these invocation handlers are equal. If not, return false.
+ if (!(this.session.equals(otherNoInterfaceViewInvocationHandler.session)))
+ {
+ return false;
+ }
+ // All possible, inequality conditions have been tested, so return true.
+ return true;
+ }
+
+ /**
+ * @see Object#hashCode()
+ */
+ @Override
+ public int hashCode()
+ {
+ int hashCode = this.getInstalledEndpoint().hashCode();
+ if (this.session != null)
+ {
+ hashCode += this.session.hashCode();
+ }
+ return hashCode;
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder("No-Interface view for endpoint [ " + this.getEndpoint() + " ]");
+ if (this.session != null)
+ {
+ sb.append(" and session " + this.session);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Handles {@link Object#equals(Object)} and {@link Object#hashCode()} method invocations on the
+ * proxy.
+ *
+ * @param proxy
+ * @param method The method that was invoked on the no-interface view
+ * @param args The arguments to the method
+ * @return
+ * @throws CannotHandleDirectlyException If the <code>method</code> is neither {@link Object#equals(Object) nor Object#hashCode()
+ */
+ private Object handleDirectly(Object proxy, Method method, Object[] args) throws CannotHandleDirectlyException
+ {
+
+ // if equals()
+ if (method.equals(METHOD_EQUALS))
+ {
+ Object other = args[0];
+ // if the other object is null, then it's a false straight-away as per the
+ // contract of equals method
+ if (other == null)
+ {
+ return false;
+ }
+ // simple instance comparison
+ if (this == other)
+ {
+ return true;
+ }
+
+ // This is the important one (and a good one) - thanks to Carlo
+ // When the equals is called on the no-interface view - view1.equals(view2)
+ // we somehow have to get the invocation handler (which hold the session information) for view2.
+ // So the trick here is to first check whether the other is an instance of
+ // MCAwareNoInterfaceViewInvocationHandler. If not, then invoke the equals on that object.
+ // - If the "other" happens to be an no-interface view, the call will be redirected
+ // to the invocation handler of view2 and thus we have the session information that we needed
+ // from view2.
+ // - If the "other" happens to be an instance of some other class, then that class' equals
+ // would return false since its not an instance of MCAwareNoInterfaceViewInvocationHandler.
+ if (!(other instanceof NoInterfaceViewInvocationHandler))
+ {
+ return other.equals(this);
+ }
+
+ return this.equals(other);
+ }
+ // handle hashCode
+ else if (method.equals(METHOD_HASH_CODE))
+ {
+ return this.hashCode();
+ }
+ else if (method.equals(METHOD_TO_STRING))
+ {
+ return this.toString();
+ }
+ throw new CannotHandleDirectlyException();
+ }
+
+ /**
+ *
+ * CannotHandleDirectlyException
+ *
+ * Will be used to indicate that this {@link NoInterfaceViewInvocationHandler} cannot
+ * handle the method invocation in the invocation handler.
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+ private class CannotHandleDirectlyException extends Exception
+ {
+ }
+
+}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/AbstractNoInterfaceViewJNDIBinder.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/AbstractNoInterfaceViewJNDIBinder.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/AbstractNoInterfaceViewJNDIBinder.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,85 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.impl.jndi;
+
+import org.jboss.ejb3.nointerface.impl.invocationhandler.NoInterfaceViewInvocationHandler;
+import org.jboss.ejb3.nointerface.spi.jndi.NoInterfaceViewJNDIBinder;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.metadata.ejb.jboss.JBossSessionBean31MetaData;
+import org.jboss.metadata.ejb.jboss.jndi.resolver.impl.JNDIPolicyBasedJNDINameResolverFactory;
+import org.jboss.metadata.ejb.jboss.jndi.resolver.spi.SessionBean31JNDINameResolver;
+import org.jboss.metadata.ejb.jboss.jndipolicy.plugins.DefaultJNDIBindingPolicyFactory;
+import org.jboss.metadata.ejb.jboss.jndipolicy.spi.DefaultJndiBindingPolicy;
+
+/**
+ * AbstractNoInterfaceViewJNDIBinder
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public abstract class AbstractNoInterfaceViewJNDIBinder implements NoInterfaceViewJNDIBinder
+{
+
+ /**
+ * The endpoint context which will be used while creating the {@link NoInterfaceViewInvocationHandler}
+ */
+ protected KernelControllerContext endpointContext;
+
+ /**
+ * Creates a jndi binder
+ * @param endPointCtx The endpoint context which will be used by the {@link NoInterfaceViewInvocationHandler}
+ */
+ public AbstractNoInterfaceViewJNDIBinder(KernelControllerContext endPointCtx)
+ {
+ if (endPointCtx == null)
+ {
+ throw new IllegalArgumentException("Endpoint kernel controller context cannot be null while creating a "
+ + this.getClass().getSimpleName());
+ }
+ this.endpointContext = endPointCtx;
+ }
+
+ /**
+ * Ensures that the bean represented by the <code>beanMetadata</code> has a no-interface view.
+ * If a no-interface view is not present, then it throws a {@link IllegalStateException}
+ *
+ * @param beanMetadata The bean metadata
+ */
+ protected void ensureNoInterfaceViewExists(JBossSessionBean31MetaData beanMetadata) throws IllegalStateException
+ {
+ if (!beanMetadata.isNoInterfaceBean())
+ {
+ throw new IllegalStateException(beanMetadata.getEjbName() + " bean does not have a no-interface view");
+ }
+ }
+
+ /**
+ * @param sessionBean The session bean metadata
+ * @return Returns a jndi-name resolver for the session bean
+ */
+ protected SessionBean31JNDINameResolver getJNDINameResolver(JBossSessionBean31MetaData sessionBean)
+ {
+ DefaultJndiBindingPolicy jndiBindingPolicy = DefaultJNDIBindingPolicyFactory.getDefaultJNDIBindingPolicy();
+ return JNDIPolicyBasedJNDINameResolverFactory.getJNDINameResolver(sessionBean, jndiBindingPolicy);
+ }
+
+}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/NoInterfaceViewJNDIBinderFacade.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/NoInterfaceViewJNDIBinderFacade.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/NoInterfaceViewJNDIBinderFacade.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,196 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.nointerface.impl.jndi;
+
+import javax.naming.Context;
+
+import org.jboss.beans.metadata.api.annotations.Inject;
+import org.jboss.beans.metadata.api.annotations.Start;
+import org.jboss.beans.metadata.api.annotations.Stop;
+import org.jboss.beans.metadata.api.model.FromContext;
+import org.jboss.ejb3.nointerface.spi.jndi.NoInterfaceViewJNDIBinder;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.logging.Logger;
+import org.jboss.metadata.ejb.jboss.JBossSessionBean31MetaData;
+import org.jboss.metadata.ejb.jboss.jndi.resolver.impl.JNDIPolicyBasedJNDINameResolverFactory;
+import org.jboss.metadata.ejb.jboss.jndi.resolver.spi.SessionBean31JNDINameResolver;
+import org.jboss.metadata.ejb.jboss.jndipolicy.plugins.DefaultJNDIBindingPolicyFactory;
+import org.jboss.metadata.ejb.jboss.jndipolicy.spi.DefaultJndiBindingPolicy;
+
+/**
+ * NoInterfaceViewJNDIBinderFacade
+ *
+ * A {@link NoInterfaceViewJNDIBinderFacade} corresponds to a EJB which is eligible
+ * for a no-interface view
+ *
+ * This MC bean has dependencies (like the container) injected as necessary.
+ * During its START phase this NoInterfaceViewJNDIBinder creates a no-interface view
+ * and binds it to the jndi.
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class NoInterfaceViewJNDIBinderFacade
+{
+
+ /**
+ * Logger
+ */
+ private static Logger logger = Logger.getLogger(NoInterfaceViewJNDIBinderFacade.class);
+
+ /**
+ * The endpoint for which this {@link NoInterfaceViewJNDIBinderFacade} holds
+ * an no-interface view
+ */
+ // Bean name will be added to this Inject by the deployer.
+ // We need NOT use the annotation here at all, since the deployer adds this
+ // dynamically. But having this here provides a better understanding about how
+ // this field is used
+ @Inject(dependentState = "Described", fromContext = FromContext.CONTEXT)
+ protected KernelControllerContext endpointContext;
+
+ /**
+ * The bean class for which the no-interface view corresponds
+ */
+ private Class<?> beanClass;
+
+ /**
+ * The bean metadata
+ */
+ private JBossSessionBean31MetaData sessionBeanMetadata;
+
+ /**
+ * JNDI naming context
+ */
+ private Context jndiCtx;
+
+ /**
+ * JNDI name resolver for the bean
+ */
+ private SessionBean31JNDINameResolver jndiNameResolver;
+
+ /**
+ * Constructor
+ *
+ * @param beanClass
+ * @param sessionBeanMetadata
+ */
+ public NoInterfaceViewJNDIBinderFacade(Context ctx, Class<?> beanClass,
+ JBossSessionBean31MetaData sessionBeanMetadata)
+ {
+ this.jndiCtx = ctx;
+ this.beanClass = beanClass;
+ this.sessionBeanMetadata = sessionBeanMetadata;
+
+ }
+
+ /**
+ * Will be called when the dependencies of this {@link NoInterfaceViewJNDIBinderFacade} are
+ * resolved and this MC bean reaches the START state.
+ *
+ * At this point, the {@link #endpointContext} associated with this {@link NoInterfaceViewJNDIBinderFacade}
+ * is injected and is at a minimal of DESCRIBED state. We now create a no-interface view
+ * for the corresponding bean.
+ * Note: No validations (like whether the bean is eligible for no-interface view) is done at this
+ * stage. It's assumed that the presence of a {@link NoInterfaceViewJNDIBinderFacade} indicates that the
+ * corresponding bean is eligible for no-interface view.
+ *
+ * @throws Exception
+ */
+ @Start
+ public void onStart() throws Exception
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Creating no-interface view for endpoint " + this.endpointContext);
+ }
+
+ this.getNoInterfaceViewJndiBinder().bindNoInterfaceView(this.jndiCtx, this.beanClass, this.sessionBeanMetadata);
+ }
+
+ /**
+ * Does any relevant cleanup
+ *
+ * @throws Exception
+ */
+ @Stop
+ public void onStop() throws Exception
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Unbinding no-interface view from JNDI, for endpoint " + this.endpointContext);
+ }
+ this.getNoInterfaceViewJndiBinder().unbindNoInterfaceView(this.jndiCtx, this.beanClass, this.sessionBeanMetadata);
+ }
+
+ /**
+ *
+ * @param endpointContext The KernelControllerContext corresponding to the endpoint
+ * @throws Exception
+ */
+ public void setEndpointContext(KernelControllerContext endpointContext) throws Exception
+ {
+ this.endpointContext = endpointContext;
+
+ }
+
+ /**
+ * Returns the jndi name resolver, which will be responsible for returning the
+ * appropriate jndi names for various views of the session bean
+ * @return
+ */
+ protected SessionBean31JNDINameResolver getJNDINameResolver()
+ {
+ if (this.jndiNameResolver != null)
+ {
+ return this.jndiNameResolver;
+ }
+ DefaultJndiBindingPolicy jndiBindingPolicy = DefaultJNDIBindingPolicyFactory.getDefaultJNDIBindingPolicy();
+ return JNDIPolicyBasedJNDINameResolverFactory.getJNDINameResolver(this.sessionBeanMetadata, jndiBindingPolicy);
+ }
+
+ /**
+ * Returns an appropriate instance of {@link NoInterfaceViewJNDIBinderFacade} based on the
+ * <code>sessionBeanMetadata</code>
+ *
+ * @param ctx JNDI naming context into which this {@link NoInterfaceViewJNDIBinderFacade} will be
+ * responsible for binding/unbinding objects
+ * @param beanClass Bean class
+ * @param sessionBeanMetadata Session bean metadata of the bean class
+ * @return
+ */
+ private NoInterfaceViewJNDIBinder getNoInterfaceViewJndiBinder()
+ {
+ if (this.sessionBeanMetadata.isStateful())
+ {
+ return new StatefulNoInterfaceJNDIBinder(this.endpointContext);
+ }
+ else if (this.sessionBeanMetadata.isStateless())
+ {
+ return new StatelessNoInterfaceJNDIBinder(this.endpointContext);
+ }
+ throw new RuntimeException("Cannot get a jndi binder for bean " + this.sessionBeanMetadata.getEjbName()
+ + " since it's neither a stateful nor a stateless bean");
+ }
+
+
+}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/StatefulNoInterfaceJNDIBinder.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/StatefulNoInterfaceJNDIBinder.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/StatefulNoInterfaceJNDIBinder.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,140 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.nointerface.impl.jndi;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+
+import org.jboss.ejb3.nointerface.impl.objectfactory.NoInterfaceViewProxyFactoryRefAddrTypes;
+import org.jboss.ejb3.nointerface.impl.objectfactory.StatefulNoInterfaceViewObjectFactory;
+import org.jboss.ejb3.nointerface.impl.view.factory.StatefulNoInterfaceViewFacade;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.logging.Logger;
+import org.jboss.metadata.ejb.jboss.JBossSessionBean31MetaData;
+import org.jboss.util.naming.NonSerializableFactory;
+
+/**
+ * StatefulNoInterfaceJNDIBinder
+ *
+ * Responsible for creating and binding the appropriate objects
+ * corresponding to the no-interface view of a stateful session bean
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class StatefulNoInterfaceJNDIBinder extends AbstractNoInterfaceViewJNDIBinder
+{
+
+ /**
+ * Logger
+ */
+ private static Logger logger = Logger.getLogger(StatefulNoInterfaceJNDIBinder.class);
+
+ /**
+ * Suffix to be added to the ejb-name to form the jndi name of no-interface stateful proxyfactory
+ */
+ private static final String NO_INTERFACE_STATEFUL_PROXY_FACTORY_JNDI_NAME_SUFFIX = "/no-interface-stateful-proxyfactory";
+
+
+ /**
+ * Constructor
+ * @param beanClass The bean class
+ * @param sessionBeanMetadata Metadata of the bean
+ */
+ public StatefulNoInterfaceJNDIBinder(KernelControllerContext endPointCtx)
+ {
+ super(endPointCtx);
+ }
+
+ /**
+ * 1) Creates a {@link StatefulNoInterfaceViewFacade} and binds it to JNDI (let's call
+ * this jndi-name "A")
+ *
+ * 2) Creates a {@link StatefulNoInterfaceViewObjectFactory} objectfactory and binds a {@link Reference}
+ * to this objectfactory into the JNDI (let's call it jndi-name "B").
+ *
+ * The objectfactory will have a reference to the jndi-name of the stateful factory (created in step#1).
+ * This will then be used by the object factory to lookup the stateful factory for creating the no-interface
+ * view when the client does a lookup.
+ *
+ *
+ */
+ @Override
+ public String bindNoInterfaceView(Context jndiCtx, Class<?> beanClass, JBossSessionBean31MetaData beanMetaData)
+ throws NamingException, IllegalStateException
+ {
+ // ensure it has a no-interface view
+ this.ensureNoInterfaceViewExists(beanMetaData);
+
+ // This factory will be bound to JNDI and will be invoked (through an objectfactory) to create
+ // the no-interface view for a SFSB
+ StatefulNoInterfaceViewFacade statefulNoInterfaceViewFactory = new StatefulNoInterfaceViewFacade(
+ beanClass, this.endpointContext);
+
+ // TODO - Needs to be a proper jndi name for the factory
+ String statefulProxyFactoryJndiName = beanMetaData.getEjbName()
+ + NO_INTERFACE_STATEFUL_PROXY_FACTORY_JNDI_NAME_SUFFIX;
+ // Bind the proxy factory to jndi
+ NonSerializableFactory.rebind(jndiCtx, statefulProxyFactoryJndiName, statefulNoInterfaceViewFactory, true);
+
+ // Create an Reference which will hold the jndi-name of the statefulproxyfactory which will
+ // be responsible for creating the no-interface view for the stateful bean upon lookup
+ Reference reference = new Reference(
+ NoInterfaceViewProxyFactoryRefAddrTypes.STATEFUL_NO_INTERFACE_VIEW_OBJECT_FACTORY_KEY,
+ StatefulNoInterfaceViewObjectFactory.class.getName(), null);
+ RefAddr refAddr = new StringRefAddr(
+ NoInterfaceViewProxyFactoryRefAddrTypes.STATEFUL_NO_INTERFACE_VIEW_PROXY_FACTORY_JNDI_LOCATION,
+ statefulProxyFactoryJndiName);
+ // add this refaddr to the reference which will be bound to jndi
+ reference.add(refAddr);
+
+ String noInterfaceJndiName = this.getJNDINameResolver(beanMetaData).resolveNoInterfaceJNDIName(beanMetaData);
+ jndiCtx.bind(noInterfaceJndiName, reference);
+ logger.info("Bound the no-interface view for bean " + beanClass + " to jndi at " + noInterfaceJndiName);
+
+ return noInterfaceJndiName;
+
+ }
+
+ /**
+ * Unbind the {@link StatefulNoInterfaceViewFacade} and the {@link StatefulNoInterfaceViewObjectFactory}
+ * from the jndi
+ *
+ * @see org.jboss.ejb3.nointerface.impl.jndi.NoInterfaceViewJNDIBinderFacade#unbindNoInterfaceView()
+ */
+ @Override
+ public void unbindNoInterfaceView(Context jndiCtx, Class<?> beanClass, JBossSessionBean31MetaData beanMetaData)
+ throws NamingException, IllegalStateException
+ {
+ // ensure it has a no-interface view
+ this.ensureNoInterfaceViewExists(beanMetaData);
+
+ String noInterfaceJndiName = this.getJNDINameResolver(beanMetaData).resolveNoInterfaceJNDIName(beanMetaData);
+ jndiCtx.unbind(noInterfaceJndiName);
+ jndiCtx.unbind(beanMetaData.getEjbName() + NO_INTERFACE_STATEFUL_PROXY_FACTORY_JNDI_NAME_SUFFIX);
+
+ }
+
+}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/StatelessNoInterfaceJNDIBinder.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/StatelessNoInterfaceJNDIBinder.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/jndi/StatelessNoInterfaceJNDIBinder.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,114 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.nointerface.impl.jndi;
+
+import java.lang.reflect.InvocationHandler;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.jboss.ejb3.nointerface.impl.invocationhandler.NoInterfaceViewInvocationHandler;
+import org.jboss.ejb3.nointerface.impl.view.factory.JavassistNoInterfaceViewFactory;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.logging.Logger;
+import org.jboss.metadata.ejb.jboss.JBossSessionBean31MetaData;
+import org.jboss.util.naming.NonSerializableFactory;
+
+/**
+ * StatelessNoInterfaceJNDIBinder
+ *
+ * Responsible for binding the appropriate objects corresponding to the
+ * no-interface view of a stateless session bean
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class StatelessNoInterfaceJNDIBinder extends AbstractNoInterfaceViewJNDIBinder
+{
+
+ /**
+ * Logger
+ */
+ private static Logger logger = Logger.getLogger(StatelessNoInterfaceJNDIBinder.class);
+
+ /**
+ * Constructor
+ *
+ * @param ctx
+ * @param beanClass
+ * @param sessionBeanMetadata
+ */
+ public StatelessNoInterfaceJNDIBinder(KernelControllerContext endPointCtx)
+ {
+ super(endPointCtx);
+ }
+
+ /**
+ * Creates the no-interface view for the bean and binds it to the JNDI
+ * under the no-interface view jndi name obtained from <code>sessionBeanMetadata</code>.
+ *
+ * @see JavassistNoInterfaceViewFactory#createView(java.lang.reflect.InvocationHandler, Class)
+ */
+ @Override
+ public String bindNoInterfaceView(Context jndiCtx, Class<?> beanClass, JBossSessionBean31MetaData beanMetaData)
+ throws NamingException, IllegalStateException
+ {
+ // ensure no-interface view exists
+ this.ensureNoInterfaceViewExists(beanMetaData);
+
+
+ InvocationHandler invocationHandler = new NoInterfaceViewInvocationHandler(this.endpointContext, null);
+
+ Object noInterfaceView;
+ try
+ {
+ noInterfaceView = new JavassistNoInterfaceViewFactory().createView(invocationHandler, beanClass);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Could not create no-interface view for bean class: " + beanClass, e);
+ }
+ // bind
+ String noInterfaceJndiName = this.getJNDINameResolver(beanMetaData).resolveNoInterfaceJNDIName(beanMetaData);
+ NonSerializableFactory.rebind(jndiCtx, noInterfaceJndiName, noInterfaceView, true);
+
+ logger.info("Bound the no-interface view for bean " + beanClass + " to jndi at " + noInterfaceJndiName);
+ return noInterfaceJndiName;
+ }
+
+ /**
+ * Unbinds the no-interface view proxy from the JNDI
+ *
+ * @see org.jboss.ejb3.nointerface.impl.jndi.NoInterfaceViewJNDIBinderFacade#unbindNoInterfaceView()
+ */
+ @Override
+ public void unbindNoInterfaceView(Context jndiCtx, Class<?> beanClass, JBossSessionBean31MetaData beanMetaData)
+ throws NamingException, IllegalStateException
+ {
+ // ensure no-interface view exists
+ this.ensureNoInterfaceViewExists(beanMetaData);
+
+ String noInterfaceJndiName = this.getJNDINameResolver(beanMetaData).resolveNoInterfaceJNDIName(beanMetaData);
+ jndiCtx.unbind(noInterfaceJndiName);
+
+ }
+}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/metadata/processor/ImplicitNoInterfaceViewMetadataProcessorFactory.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/metadata/processor/ImplicitNoInterfaceViewMetadataProcessorFactory.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/metadata/processor/ImplicitNoInterfaceViewMetadataProcessorFactory.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,54 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.impl.metadata.temp;
+
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+import org.jboss.ejb3.deployers.metadata.processor.JBossMetaDataProcessorFactory;
+import org.jboss.metadata.ejb.jboss.JBossMetaData;
+import org.jboss.metadata.process.processor.JBossMetaDataProcessor;
+import org.jboss.metadata.process.processor.ejb.jboss.ImplicitNoInterfaceViewProcessor;
+
+
+
+/**
+ * ImplicitNoInterfaceViewMetadataProcessorFactory
+ *
+ * Responsible for creating a {@link ImplicitNoInterfaceViewProcessor} for
+ * processing the metadata with implicit nointerface bean rules (as defined in spec)
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class ImplicitNoInterfaceViewMetadataProcessorFactory implements JBossMetaDataProcessorFactory<JBossMetaData>
+{
+
+ /**
+ * @see org.jboss.ejb3.deployers.metadata.processor.JBossMetaDataProcessorFactory#create(org.jboss.deployers.structure.spi.DeploymentUnit)
+ * @throws NullPointerException If <code>deploymentUnit</code> is null
+ */
+ @Override
+ public JBossMetaDataProcessor<JBossMetaData> create(DeploymentUnit deploymentUnit)
+ {
+ return new ImplicitNoInterfaceViewProcessor(deploymentUnit.getClassLoader());
+ }
+
+}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/NoInterfaceViewProxyFactoryRefAddrTypes.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/NoInterfaceViewProxyFactoryRefAddrTypes.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/NoInterfaceViewProxyFactoryRefAddrTypes.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.nointerface.impl.objectfactory;
+
+/**
+ * NoInterfaceViewProxyFactoryRefAddrTypes
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public interface NoInterfaceViewProxyFactoryRefAddrTypes
+{
+
+ public static final String STATEFUL_NO_INTERFACE_VIEW_PROXY_FACTORY_JNDI_LOCATION = "Stateful Proxy factory for no-interface view";
+
+ public static final String STATEFUL_NO_INTERFACE_VIEW_OBJECT_FACTORY_KEY = "Object factory for no-interface view for stateful bean";
+}
Property changes on: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/NoInterfaceViewProxyFactoryRefAddrTypes.java
___________________________________________________________________
Name: svn:executable
+ *
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/StatefulNoInterfaceViewObjectFactory.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/StatefulNoInterfaceViewObjectFactory.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/StatefulNoInterfaceViewObjectFactory.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.nointerface.impl.objectfactory;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+import javax.naming.spi.ObjectFactory;
+
+import org.jboss.ejb3.nointerface.impl.view.factory.StatefulNoInterfaceViewFacade;
+import org.jboss.logging.Logger;
+
+/**
+ * StatefulNoInterfaceViewObjectFactory
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class StatefulNoInterfaceViewObjectFactory implements ObjectFactory
+{
+
+ private static Logger logger = Logger.getLogger(StatefulNoInterfaceViewObjectFactory.class);
+
+ /**
+ * @see ObjectFactory#getObjectInstance(Object, Name, Context, Hashtable)
+ */
+ public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment)
+ throws Exception
+ {
+
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Creating object instance through object instance factory for name " + name);
+ }
+ logger.debug("Creating object instance through object instance factory for name " + name);
+ assert obj instanceof Reference : StatefulNoInterfaceViewObjectFactory.class
+ + " cannot create view from obj of type " + obj.getClass().getName();
+
+ Reference reference = (Reference) obj;
+ String jndiNameOfStatefulProxyFactory = this.getProxyFactoryJNDINameFromReference(reference);
+ assert jndiNameOfStatefulProxyFactory != null : "Stateful proxy factory for creating no-interface view, not found in reference";
+
+ // now lookup the factory
+ Object proxyFactory = nameCtx.lookup(jndiNameOfStatefulProxyFactory);
+
+ assert proxyFactory instanceof StatefulNoInterfaceViewFacade : "Unexpected type found at jndi name "
+ + jndiNameOfStatefulProxyFactory + " Expected type " + StatefulNoInterfaceViewFacade.class.getName();
+
+ StatefulNoInterfaceViewFacade noInterfaceViewFacade = (StatefulNoInterfaceViewFacade) proxyFactory;
+
+ return noInterfaceViewFacade.createNoInterfaceView();
+ // TODO: Should not throw an exception, return null instead. see objectfactory reference
+ }
+
+ /**
+ * Returns the jndi-name at which the {@link StatefulNoInterfaceViewFacade} can be found
+ * @param ref
+ * @return
+ */
+ protected String getProxyFactoryJNDINameFromReference(Reference ref)
+ {
+ RefAddr refAddr = ref
+ .get(NoInterfaceViewProxyFactoryRefAddrTypes.STATEFUL_NO_INTERFACE_VIEW_PROXY_FACTORY_JNDI_LOCATION);
+ Object jndiNameOfStatefulProxyFactory = refAddr.getContent();
+ assert jndiNameOfStatefulProxyFactory instanceof String : "Unexpected type for "
+ + NoInterfaceViewProxyFactoryRefAddrTypes.STATEFUL_NO_INTERFACE_VIEW_PROXY_FACTORY_JNDI_LOCATION;
+
+ return (String) jndiNameOfStatefulProxyFactory;
+ }
+
+}
Property changes on: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/objectfactory/StatefulNoInterfaceViewObjectFactory.java
___________________________________________________________________
Name: svn:executable
+ *
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/JavassistNoInterfaceViewFactory.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/JavassistNoInterfaceViewFactory.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/JavassistNoInterfaceViewFactory.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,285 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.nointerface.impl.view.factory;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.CtMethod;
+import javassist.CtNewMethod;
+import javassist.LoaderClassPath;
+import javassist.Modifier;
+
+import org.jboss.ejb3.nointerface.spi.view.factory.NoInterfaceViewFactory;
+import org.jboss.logging.Logger;
+
+/**
+ * NoInterfaceEJBViewFactoryBase
+ *
+ * Creates a no-interface view for a EJB as per the EJB3.1 spec (section 3.4.4)
+ *
+ * @see NoInterfaceViewFactory
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class JavassistNoInterfaceViewFactory implements NoInterfaceViewFactory
+{
+
+ /**
+ * The proxies (sub-classes) created for the bean class need to be
+ * unique. This unique number is appended to the generated class name
+ */
+ private static long nextUniqueNumberForNoViewInterfaceClassName = 0;
+
+ /**
+ * Used while generating unique number for the proxy class
+ */
+ private static Object nextUniqueNumberLock = new Object();
+
+ /**
+ * Logger
+ */
+ private static Logger logger = Logger.getLogger(JavassistNoInterfaceViewFactory.class);
+
+ /**
+ * Inspects the bean class for all public methods and creates a proxy (sub-class)
+ * out of it with overriden implementation of the public methods. The overriden
+ * implementation will just give a call to <code>container</code>'s invoke(...) method
+ * which handles the actual call.
+ *
+ * @param <T>
+ * @param invocationHandler The container correpsonding to the bean class
+ * @param beanClass The bean class (currently assumed)
+ * @return Returns the no-interface view for the <code>beanClass</code>
+ * @throws Exception
+ */
+ public <T> T createView(InvocationHandler invocationHandler, Class<T> beanClass) throws Exception
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Creating nointerface view for beanClass: " + beanClass + " with container " + invocationHandler);
+ }
+
+ // Create a ClassPool and add the classpath using the classloader of the beanClass, so
+ // that it uses the correct jar while looking up the class
+ ClassPool pool = new ClassPool();
+ pool.appendClassPath(new LoaderClassPath(beanClass.getClassLoader()));
+
+ CtClass beanCtClass = pool.get(beanClass.getName());
+
+ // Create a sub-class (proxy) for the bean class. A unique name will be used for the subclass
+ CtClass proxyCtClass = pool.makeClass(beanClass.getName() + "_NoInterfaceProxy$" + getNextUniqueNumber(),
+ beanCtClass);
+
+ // We need to maintain a reference of the invocationHandler in the proxy, so that we can
+ // forward the method calls to invocationHandler.invoke. Create a new field in the sub-class (proxy)
+ CtField invocationHandlerField = CtField.make("private java.lang.reflect.InvocationHandler invocationHandler;",
+ proxyCtClass);
+ proxyCtClass.addField(invocationHandlerField);
+
+ // get all public methods from the bean class
+ Set<CtMethod> beanPublicMethods = getAllPublicNonStaticNonFinalMethods(beanCtClass);
+
+ // Override each of the public methods
+ for (CtMethod beanPublicMethod : beanPublicMethods)
+ {
+ // Methods from java.lang.Object can be skipped, if they are
+ // not implemented (overriden) in the bean class. TODO: Do we really need to do this?
+ if (shouldMethodBeSkipped(pool, beanPublicMethod))
+ {
+ logger.debug("Skipping " + beanPublicMethod.getName() + " on bean " + beanCtClass.getName()
+ + " from no-interface view");
+ continue;
+ }
+ // We should not be changing the bean class methods. So we need to create a copy of the methods
+ // for the sub-class (proxy)
+ CtMethod proxyPublicMethod = CtNewMethod.copy(beanPublicMethod, proxyCtClass, null);
+ // All the public methods of the bean should now be overriden (through the proxy)
+ // to give a call to the container.invoke
+ // Ex: If the bean's public method was:
+ // public String sayHi(String name) { return "Hi " + name; }
+ // then it will be changed in the proxy to
+ // public String sayHi(String name) { java.lang.reflect.Method currentMethod = beanClass.getName() + ".class.getMethod(theMethodName,params);
+ // return container.invoke(this,currentMethod,args); }
+ proxyPublicMethod = overridePublicMethod(invocationHandler, beanClass, beanPublicMethod, proxyPublicMethod);
+ // We have now created the overriden method. We need to add it to the proxy
+ proxyCtClass.addMethod(proxyPublicMethod);
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Added overriden implementation for method " + proxyPublicMethod.getName()
+ + " in no-interface view " + proxyCtClass.getName() + " for bean " + beanClass.getName());
+ }
+ }
+ // Add java.io.Serializable as the interface for the proxy (since it goes into JNDI)
+ //proxyCtClass.addInterface(pool.get(Serializable.class.getName()));
+ proxyCtClass.addMethod(createEqualsMethod(pool, proxyCtClass));
+
+ // We are almost done (except for setting the container field in the proxy)
+ // Let's first create a java.lang.Class (i.e. load) out of the javassist class
+ // using the classloader of the bean
+ Class<?> proxyClass = proxyCtClass.toClass(beanClass.getClassLoader(), beanClass.getProtectionDomain());
+ // time to set the container field through normal java reflection
+ Object proxyInstance = proxyClass.newInstance();
+ Field containerInProxy = proxyClass.getDeclaredField("invocationHandler");
+ containerInProxy.setAccessible(true);
+ containerInProxy.set(proxyInstance, invocationHandler);
+
+ // return the proxy instance
+ return beanClass.cast(proxyInstance);
+
+ }
+
+ private <T> CtMethod overridePublicMethod(InvocationHandler container, Class<T> beanClass,
+ CtMethod publicMethodOnBean, CtMethod publicMethodOnProxy) throws Exception
+ {
+ publicMethodOnProxy.setBody("{"
+ +
+ // The proxy needs to call the container.invoke
+ // the InvocationHandler.invoke accepts (Object proxy,Method method,Object[] args)
+ // This view needs to create a java.lang.reflect.Method object based on the "current method"
+ // that is invoked on the view. Note that we need to get the Method from the beanclass.
+ // Note: All the '$' parameters used are javassist specific syntax
+ "java.lang.reflect.Method currentMethod = " + beanClass.getName() + ".class.getMethod(\""
+ + publicMethodOnBean.getName() + "\",$sig);" +
+ // At this point we have the container, the Method to be invoked and the parameters to be passed
+ // All we have to do is invoke the container
+ "return ($r) invocationHandler.invoke(this,currentMethod,$args);" + "}");
+
+ return publicMethodOnProxy;
+ }
+
+ /**
+ * Returns all public, non-static and non-final methods for the class
+ *
+ * @param ctClass The class whose non-final, non-static public methods are to be returned
+ * @return
+ * @throws Exception
+ */
+ private Set<CtMethod> getAllPublicNonStaticNonFinalMethods(CtClass ctClass) throws Exception
+ {
+ CtMethod[] allMethods = ctClass.getMethods();
+ Set<CtMethod> publicMethods = new HashSet<CtMethod>();
+
+ for (CtMethod ctMethod : allMethods)
+ {
+ int modifier = ctMethod.getModifiers();
+ // Public non-static non-final methods
+ if (((Modifier.PUBLIC & modifier) == Modifier.PUBLIC) && ((Modifier.STATIC & modifier) != Modifier.STATIC)
+ && ((Modifier.FINAL & modifier) != Modifier.FINAL) && ((Modifier.NATIVE & modifier) != Modifier.NATIVE))
+ {
+ publicMethods.add(ctMethod);
+ }
+ }
+ return publicMethods;
+ }
+
+ /**
+ * Checks whether a method has to be skipped from being overriden in the proxy
+ * that is returned for the no-interface view.
+ *
+ * TODO: Do we really need this. Need to think more. Let's keep it for the time-being
+ *
+ * @param beanCtClass
+ * @param ctMethod
+ * @return
+ * @throws Exception
+ */
+ private boolean shouldMethodBeSkipped(CtClass beanCtClass, CtMethod ctMethod) throws Exception
+ {
+
+ // List<CtMethod> declaredMethods = Arrays.asList(beanCtClass.getDeclaredMethods());
+ // if (declaredMethods.contains(ctMethod))
+ // {
+ // return false;
+ // }
+ // CtClass objectCtClass = ClassPool.getDefault().get(Object.class.getName());
+ // CtMethod[] methodsInObjectClass = objectCtClass.getMethods();
+ // List<CtMethod> methodsToBeSkipped = Arrays.asList(methodsInObjectClass);
+ // return methodsToBeSkipped.contains(ctMethod);
+ return false;
+
+ }
+
+ private static boolean shouldMethodBeSkipped(ClassPool pool, CtMethod ctMethod) throws Exception
+ {
+ CtClass paramsToEqualsMethodInObjectClass[] = new CtClass[]
+ {pool.get(Object.class.getName())};
+ if (!ctMethod.getName().equals("equals"))
+ {
+ return false;
+ }
+ if (ctMethod.getParameterTypes().length != paramsToEqualsMethodInObjectClass.length)
+ {
+ return false;
+ }
+ CtClass paramsToEqualsMethodInOtherClass[] = ctMethod.getParameterTypes();
+ return paramsToEqualsMethodInObjectClass[0].equals(paramsToEqualsMethodInOtherClass[0]);
+
+ }
+
+ private static CtMethod createEqualsMethod(ClassPool pool, CtClass proxyCtClass) throws Exception
+ {
+ String body = "{" + "java.lang.reflect.Method currentMethod = " + Object.class.getName()
+ + ".class.getMethod(\"equals\",$sig);" + "return ($r) invocationHandler.invoke(this,currentMethod,$args);"
+ + "}";
+
+ Method equals = Object.class.getMethod("equals", new Class<?>[]
+ {Object.class});
+ CtClass returnType = pool.get(equals.getReturnType().getName());
+ CtClass paramTypes[] = new CtClass[equals.getParameterTypes().length];
+ int i = 0;
+ for (Class<?> paramType : equals.getParameterTypes())
+ {
+ paramTypes[i++] = pool.get(paramType.getName());
+ }
+
+ CtClass exceptionTypes[] = new CtClass[equals.getExceptionTypes().length];
+ int j = 0;
+ for (Class<?> exceptionType : equals.getExceptionTypes())
+ {
+ exceptionTypes[j++] = pool.get(exceptionType.getName());
+ }
+
+ return CtNewMethod.make(returnType, equals.getName(), paramTypes, exceptionTypes, body, proxyCtClass);
+ }
+
+ /**
+ * Get the next unique number which will be used for the proxy class name
+ *
+ * @return
+ */
+ private long getNextUniqueNumber()
+ {
+ synchronized (nextUniqueNumberLock)
+ {
+ this.nextUniqueNumberForNoViewInterfaceClassName++;
+ return this.nextUniqueNumberForNoViewInterfaceClassName;
+ }
+ }
+
+}
Property changes on: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/JavassistNoInterfaceViewFactory.java
___________________________________________________________________
Name: svn:executable
+ *
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/StatefulNoInterfaceViewFacade.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/StatefulNoInterfaceViewFacade.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/impl/view/factory/StatefulNoInterfaceViewFacade.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,125 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.nointerface.impl.view.factory;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.ejb3.endpoint.Endpoint;
+import org.jboss.ejb3.nointerface.impl.invocationhandler.NoInterfaceViewInvocationHandler;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.logging.Logger;
+
+/**
+ * StatefulNoInterfaceViewFacade
+ *
+ * Responsible for (not necessarily in the following order)
+ * - Creating a session from the stateful container
+ * - Creating the no-interface view for a stateful session bean
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public class StatefulNoInterfaceViewFacade
+{
+
+ /**
+ * Logger
+ */
+ private static Logger logger = Logger.getLogger(StatefulNoInterfaceViewFacade.class);
+
+ /**
+ * The bean class
+ */
+ protected Class<?> beanClass;
+
+ /**
+ * The KernelControllerContext corresponding to the container of a bean for which
+ * the no-interface view is to be created by this factory. This context
+ * may <i>not</i> be in INSTALLED state. This factory is responsible
+ * for pushing it to INSTALLED state whenever necessary.
+ *
+ */
+ protected KernelControllerContext endpointContext;
+
+ /**
+ * Constructor
+ * @param beanClass
+ * @param container
+ * @param statefulSessionFactory
+ */
+ public StatefulNoInterfaceViewFacade(Class<?> beanClass, KernelControllerContext containerContext)
+ {
+ this.beanClass = beanClass;
+ this.endpointContext = containerContext;
+ }
+
+ /**
+ * First creates a session and then creates a no-interface view for the bean.
+ *
+ * @return
+ * @throws Exception
+ */
+ public Object createNoInterfaceView() throws Exception
+ {
+ try
+ {
+ // first push the endpointContext to INSTALLED
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("Changing the context " + this.endpointContext.getName() + " to state "
+ + ControllerState.INSTALLED.getStateString() + " from current state "
+ + this.endpointContext.getState().getStateString());
+ }
+ this.endpointContext.getController().change(this.endpointContext, ControllerState.INSTALLED);
+ }
+ catch (Throwable t)
+ {
+ throw new RuntimeException("Could not push the context " + this.endpointContext.getName()
+ + " from its current state " + this.endpointContext.getState().getStateString() + " to INSTALLED", t);
+ }
+
+ // now get hold of the StatefulSessionFactory from the context
+ Object target = this.endpointContext.getTarget();
+ assert target instanceof Endpoint : "Unexpected object type found " + target + " - expected a " + Endpoint.class;
+
+ Endpoint endpoint = (Endpoint) target;
+ if (!endpoint.isSessionAware())
+ {
+ throw new IllegalStateException("Endpoint " + endpoint
+ + " is not session aware. Cannot be used for Stateful no-interface view(s)");
+ }
+
+ // create the session
+ Serializable session = endpoint.getSessionFactory().createSession(null, null);
+ logger.debug("Created session " + session + " for " + this.beanClass);
+
+ // create an invocation handler
+ InvocationHandler invocationHandler = new NoInterfaceViewInvocationHandler(this.endpointContext, session);
+
+ // Now create the view for this bean class and the newly created invocation handler
+ Object noInterfaceView = new JavassistNoInterfaceViewFactory().createView(invocationHandler, beanClass);
+ return noInterfaceView;
+ }
+
+}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/jndi/NoInterfaceViewJNDIBinder.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/jndi/NoInterfaceViewJNDIBinder.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/jndi/NoInterfaceViewJNDIBinder.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,68 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.spi.jndi;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.jboss.metadata.ejb.jboss.JBossSessionBean31MetaData;
+
+/**
+ * NoInterfaceViewJNDIBinder
+ *
+ * Responsible for binding and unbinding no-interface view(s) to/from the JNDI.
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public interface NoInterfaceViewJNDIBinder
+{
+
+ /**
+ * Binds the no-interface view of the bean <code>beanClass</code> to the JNDI,
+ * at the provided <code>jndiCtx</code> context.
+ *
+ * @param jndiCtx The jndi context to which the no-interface view has to be bound
+ * @param beanClass The EJB class
+ * @param beanMetaData The metadata of the bean
+ *
+ * @return Returns the jndi-name where the no-interface view has been bound
+ * @throws NamingException If any exception while binding to JNDI
+ * @throws IllegalStateException If a no-interface view is not applicable for this bean
+ */
+ String bindNoInterfaceView(Context jndiCtx, Class<?> beanClass, JBossSessionBean31MetaData beanMetaData)
+ throws NamingException, IllegalStateException;
+
+ /**
+ * Unbind the no-interface view of the bean <code>beanClass</code> from the JNDI
+ * at the provided <code>jndiCtx</code> context.
+ *
+ * @param jndiCtx The jndi context from where the no-interface view has to be unbound
+ * @param beanClass The EJB class
+ * @param beanMetaData The metadata of the bean
+ *
+ * @throws NamingException If any exception while unbinding from JNDI
+ * @throws IllegalStateException If a no-interface view is not applicable for this bean
+ */
+ void unbindNoInterfaceView(Context jndiCtx, Class<?> beanClass, JBossSessionBean31MetaData beanMetaData)
+ throws NamingException, IllegalStateException;
+}
Added: projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/view/factory/NoInterfaceViewFactory.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/view/factory/NoInterfaceViewFactory.java (rev 0)
+++ projects/ejb3/trunk/nointerface/src/main/java/org/jboss/ejb3/nointerface/spi/view/factory/NoInterfaceViewFactory.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -0,0 +1,51 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ejb3.nointerface.spi.view.factory;
+
+import java.lang.reflect.InvocationHandler;
+
+/**
+ * NoInterfaceViewFactory
+ *
+ * Factory for creating no-interface view for a bean
+ *
+ * @author Jaikiran Pai
+ * @version $Revision: $
+ */
+public interface NoInterfaceViewFactory
+{
+
+ /**
+ * Creates a no-interface view for the EJB represented by the
+ * <code>beanClass</code>
+ *
+ * @param <T>
+ * @param invocationHandler The invocation handler responsible for handling
+ * requests on the no-interface view returned by this
+ * method
+ * @param beanClass The bean class (no validation on the Class is done to check for EJB semantics)
+ * @return Returns the no-interface view for the <code>beanClass</code>
+ *
+ * @throws Exception If any exceptions are encountered during the no-interface view creation
+ */
+ public <T> T createView(InvocationHandler invocationHandler, Class<T> beanClass) throws Exception;
+}
Modified: projects/ejb3/trunk/nointerface/src/main/resources/META-INF/ejb3-nointerface-jboss-beans.xml
===================================================================
--- projects/ejb3/trunk/nointerface/src/main/resources/META-INF/ejb3-nointerface-jboss-beans.xml 2010-01-18 18:29:32 UTC (rev 99549)
+++ projects/ejb3/trunk/nointerface/src/main/resources/META-INF/ejb3-nointerface-jboss-beans.xml 2010-01-18 18:42:26 UTC (rev 99550)
@@ -3,12 +3,12 @@
<deployment xmlns="urn:jboss:bean-deployer:2.0">
<!-- No-interface view deployer - works on JBossMetadata and creates a NoInterfaceMCBean -->
- <bean name="Ejb3NoInterfaceViewDeployer" class="org.jboss.ejb3.nointerface.deployers.EJB3NoInterfaceDeployer"/>
+ <bean name="Ejb3NoInterfaceViewDeployer" class="org.jboss.ejb3.nointerface.impl.deployers.EJB3NoInterfaceDeployer"/>
<!-- A metadata processor factory responsible for creating a processor to apply implicit
nointerface bean rules (as defined by spec) on merged metadata. This processor factory
will be picked up by the Ejb3MetadataProcessingDeployer and added to a chain of processor factories -->
<bean name="ImplicitNoInterfaceViewMetadataProcessorFactory"
- class="org.jboss.ejb3.nointerface.metadata.processor.ImplicitNoInterfaceViewMetadataProcessorFactory"/>
+ class="org.jboss.ejb3.nointerface.impl.metadata.processor.ImplicitNoInterfaceViewMetadataProcessorFactory"/>
</deployment>
\ No newline at end of file
Modified: projects/ejb3/trunk/nointerface/src/test/java/org/jboss/ejb3/nointerface/test/factory/unit/NoInterfaceViewFactoryTestCase.java
===================================================================
--- projects/ejb3/trunk/nointerface/src/test/java/org/jboss/ejb3/nointerface/test/factory/unit/NoInterfaceViewFactoryTestCase.java 2010-01-18 18:29:32 UTC (rev 99549)
+++ projects/ejb3/trunk/nointerface/src/test/java/org/jboss/ejb3/nointerface/test/factory/unit/NoInterfaceViewFactoryTestCase.java 2010-01-18 18:42:26 UTC (rev 99550)
@@ -28,8 +28,8 @@
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
-import org.jboss.ejb3.nointerface.factory.NoInterfaceEJBViewFactoryBase;
-import org.jboss.ejb3.nointerface.factory.NoInterfaceViewFactory;
+import org.jboss.ejb3.nointerface.impl.view.factory.JavassistNoInterfaceViewFactory;
+import org.jboss.ejb3.nointerface.spi.view.factory.NoInterfaceViewFactory;
import org.jboss.ejb3.nointerface.test.viewcreator.SimpleSFSBeanWithoutInterfaces;
import org.jboss.ejb3.nointerface.test.viewcreator.SimpleSLSBWithoutInterface;
import org.jboss.logging.Logger;
@@ -86,7 +86,7 @@
@Test
public void testFinalMethodsAreNotConsideredInView() throws Exception
{
- NoInterfaceViewFactory noInterfaceBeanFactory = new NoInterfaceEJBViewFactoryBase();
+ NoInterfaceViewFactory noInterfaceBeanFactory = new JavassistNoInterfaceViewFactory();
SimpleSLSBWithoutInterface beanInstance = new SimpleSLSBWithoutInterface();
Object proxy = noInterfaceBeanFactory.createView(new DummyInvocationHandler(beanInstance), beanInstance.getClass());
// ensure that the returned object is not null and is of expected type
@@ -117,7 +117,7 @@
@Test
public void testStaticMethodsAreNotConsideredInView() throws Exception
{
- NoInterfaceViewFactory noInterfaceBeanFactory = new NoInterfaceEJBViewFactoryBase();
+ NoInterfaceViewFactory noInterfaceBeanFactory = new JavassistNoInterfaceViewFactory();
SimpleSFSBeanWithoutInterfaces beanInstance = new SimpleSFSBeanWithoutInterfaces();
Object proxy = noInterfaceBeanFactory.createView(new DummyInvocationHandler(beanInstance), beanInstance.getClass());
// ensure that the returned object is not null and is of expected type
More information about the jboss-cvs-commits
mailing list