001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb;
023:
024: import org.jboss.ejb.txtimer.TimedObjectInvoker;
025: import org.jboss.invocation.Invocation;
026: import org.jboss.proxy.ejb.EJBMetaDataImpl;
027: import org.jboss.util.UnreachableStatementException;
028:
029: import javax.ejb.CreateException;
030: import javax.ejb.EJBException;
031: import javax.ejb.EJBHome;
032: import javax.ejb.EJBLocalObject;
033: import javax.ejb.EJBMetaData;
034: import javax.ejb.EJBObject;
035: import javax.ejb.Handle;
036: import javax.ejb.HomeHandle;
037: import javax.ejb.RemoveException;
038: import java.lang.reflect.Method;
039: import java.rmi.RemoteException;
040: import java.util.HashMap;
041: import java.util.Map;
042:
043: /**
044: * The container for <em>stateless</em> session beans.
045: *
046: * @author <a href="mailto:rickard.oberg@telkel.com">Rickard �berg</a>
047: * @author <a href="mailto:marc.fleury@telkel.com">Marc Fleury</a>
048: * @author <a href="mailto:docodan@mvcsoft.com">Daniel OConnor</a>
049: * @author <a href="mailto:Christoph.Jung@infor.de">Christoph G. Jung</a>
050: * @version $Revision: 57209 $
051: */
052: public class StatelessSessionContainer extends SessionContainer
053: implements EJBProxyFactoryContainer, InstancePoolContainer {
054: // EJBObject implementation --------------------------------------
055:
056: /**
057: * No-op.
058: */
059: public void remove(Invocation mi) throws RemoteException,
060: RemoveException {
061: log
062: .debug("Useless invocation of remove() for stateless session bean");
063: }
064:
065: // EJBLocalHome implementation
066:
067: public EJBLocalObject createLocalHome() throws CreateException {
068: if (localProxyFactory == null) {
069: String msg = "No ProxyFactory, check for ProxyFactoryFinderInterceptor";
070: throw new IllegalStateException(msg);
071: }
072: createCount++;
073: return localProxyFactory.getStatelessSessionEJBLocalObject();
074: }
075:
076: /**
077: * No-op.
078: */
079: public void removeLocalHome(Object primaryKey) {
080: log
081: .debug("Useless invocation of remove(Object) for stateless session bean");
082: }
083:
084: // EJBHome implementation ----------------------------------------
085:
086: public EJBObject createHome() throws RemoteException,
087: CreateException {
088: EJBProxyFactory ci = getProxyFactory();
089: if (ci == null) {
090: String msg = "No ProxyFactory, check for ProxyFactoryFinderInterceptor";
091: throw new IllegalStateException(msg);
092: }
093: createCount++;
094: Object obj = ci.getStatelessSessionEJBObject();
095: return (EJBObject) obj;
096: }
097:
098: /**
099: * No-op.
100: */
101: public void removeHome(Handle handle) throws RemoteException,
102: RemoveException {
103: throw new UnreachableStatementException();
104: }
105:
106: /**
107: * No-op.
108: */
109: public void removeHome(Object primaryKey) throws RemoteException,
110: RemoveException {
111: throw new UnreachableStatementException();
112: }
113:
114: // Protected ----------------------------------------------------
115:
116: protected void setupHomeMapping() throws NoSuchMethodException {
117: boolean debug = log.isDebugEnabled();
118:
119: Map map = new HashMap();
120:
121: if (homeInterface != null) {
122: Method[] m = homeInterface.getMethods();
123: for (int i = 0; i < m.length; i++) {
124: // Implemented by container
125: if (debug)
126: log.debug("Mapping " + m[i].getName());
127: map.put(m[i], getClass().getMethod(
128: m[i].getName() + "Home",
129: m[i].getParameterTypes()));
130: }
131: }
132: if (localHomeInterface != null) {
133: Method[] m = localHomeInterface.getMethods();
134: for (int i = 0; i < m.length; i++) {
135: // Implemented by container
136: if (debug)
137: log.debug("Mapping " + m[i].getName());
138: map.put(m[i], getClass().getMethod(
139: m[i].getName() + "LocalHome",
140: m[i].getParameterTypes()));
141: }
142: }
143:
144: homeMapping = map;
145: }
146:
147: Interceptor createContainerInterceptor() {
148: return new ContainerInterceptor();
149: }
150:
151: /**
152: * This is the last step before invocation - all interceptors are done
153: */
154: class ContainerInterceptor extends AbstractContainerInterceptor {
155: public Object invokeHome(Invocation mi) throws Exception {
156: Method miMethod = mi.getMethod();
157: Method m = (Method) getHomeMapping().get(miMethod);
158: if (m == null) {
159: String msg = "Invalid invocation, check your deployment packaging, method="
160: + miMethod;
161: throw new EJBException(msg);
162: }
163:
164: try {
165: return mi.performCall(StatelessSessionContainer.this ,
166: m, mi.getArguments());
167: } catch (Exception e) {
168: rethrow(e);
169: }
170:
171: // We will never get this far, but the compiler does not know that
172: throw new org.jboss.util.UnreachableStatementException();
173: }
174:
175: public Object invoke(Invocation mi) throws Exception {
176: // wire the transaction on the context, this is how the instance remember the tx
177: EnterpriseContext ctx = (EnterpriseContext) mi
178: .getEnterpriseContext();
179: if (ctx.getTransaction() == null)
180: ctx.setTransaction(mi.getTransaction());
181:
182: // Get method and instance to invoke upon
183: Method miMethod = mi.getMethod();
184:
185: Map map = getBeanMapping();
186: Method m = (Method) map.get(miMethod);
187:
188: // In case of an JSR-181 service endpoint without a remote
189: // and service-endpoint interface, the miMethod is the actual
190: // target bean method
191: if (m == null && map.values().contains(miMethod)) {
192: m = miMethod;
193: }
194:
195: if (m == null) {
196: String msg = "Invalid invocation, check your deployment packaging, method="
197: + miMethod;
198: throw new EJBException(msg);
199: }
200:
201: //If we have a method that needs to be done by the container (EJBObject methods)
202: if (m.getDeclaringClass().equals(
203: StatelessSessionContainer.class)
204: || m.getDeclaringClass().equals(
205: SessionContainer.class)) {
206: try {
207: return mi.performCall(
208: StatelessSessionContainer.this , m,
209: new Object[] { mi });
210: } catch (Exception e) {
211: rethrow(e);
212: }
213: } else // we have a method that needs to be done by a bean instance
214: {
215: // Invoke and handle exceptions
216: try {
217: Object bean = ctx.getInstance();
218: return mi.performCall(bean, m, mi.getArguments());
219: } catch (Exception e) {
220: rethrow(e);
221: }
222: }
223:
224: // We will never get this far, but the compiler does not know that
225: throw new org.jboss.util.UnreachableStatementException();
226: }
227: }
228: }
|