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.plugins;
023:
024: import java.lang.reflect.Method;
025: import java.rmi.RemoteException;
026:
027: import javax.ejb.EJBException;
028: import javax.ejb.TimedObject;
029: import javax.ejb.Timer;
030: import javax.xml.rpc.handler.MessageContext;
031:
032: import org.jboss.ejb.AllowedOperationsAssociation;
033: import org.jboss.ejb.Container;
034: import org.jboss.ejb.EnterpriseContext;
035: import org.jboss.ejb.InstancePool;
036: import org.jboss.ejb.StatelessSessionContainer;
037: import org.jboss.ejb.StatelessSessionEnterpriseContext;
038: import org.jboss.invocation.Invocation;
039: import org.jboss.invocation.InvocationKey;
040: import org.jboss.invocation.InvocationType;
041:
042: /**
043: * This container acquires the given instance. This must be used after
044: * the EnvironmentInterceptor, since acquiring instances requires a proper
045: * JNDI environment to be set
046: *
047: * @author Rickard Oberg
048: * @author Scott.Stark@jboss.org
049: * @version $Revision: 59509 $
050: */
051: public class StatelessSessionInstanceInterceptor extends
052: AbstractInterceptor {
053: // Constants -----------------------------------------------------
054:
055: // Attributes ----------------------------------------------------
056:
057: protected StatelessSessionContainer container;
058:
059: // Static --------------------------------------------------------
060:
061: /** A reference to {@link javax.ejb.TimedObject#ejbTimeout}. */
062: protected static final Method ejbTimeout;
063: static {
064: try {
065: ejbTimeout = TimedObject.class.getMethod("ejbTimeout",
066: new Class[] { Timer.class });
067: } catch (Exception e) {
068: throw new ExceptionInInitializerError(e);
069: }
070: }
071:
072: // Constructors --------------------------------------------------
073:
074: // Public --------------------------------------------------------
075:
076: public void setContainer(final Container container) {
077: super .setContainer(container);
078: this .container = (StatelessSessionContainer) container;
079: }
080:
081: // Interceptor implementation --------------------------------------
082:
083: public Object invokeHome(final Invocation mi) throws Exception {
084: InstancePool pool = container.getInstancePool();
085: StatelessSessionEnterpriseContext ctx = null;
086: try {
087: // Acquire an instance in case the ejbCreate throws a CreateException
088: ctx = (StatelessSessionEnterpriseContext) pool.get();
089: mi.setEnterpriseContext(ctx);
090: // Dispatch the method to the container
091: return getNext().invokeHome(mi);
092: } finally {
093: mi.setEnterpriseContext(null);
094: // If an instance was created, return it to the pool
095: if (ctx != null)
096: pool.free(ctx);
097: }
098:
099: }
100:
101: public Object invoke(final Invocation mi) throws Exception {
102: // Get context
103: InstancePool pool = container.getInstancePool();
104:
105: StatelessSessionEnterpriseContext ctx = null;
106: try {
107: ctx = (StatelessSessionEnterpriseContext) pool.get();
108: } catch (EJBException e) {
109: throw e;
110: } catch (RemoteException e) {
111: throw e;
112: } catch (Exception e) {
113: InvocationType type = mi.getType();
114: boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
115: if (isLocal)
116: throw new EJBException(
117: "Unable to get an instance from the pool", e);
118: else
119: throw new RemoteException(
120: "Unable to get an intance from the pool", e);
121: }
122:
123: // Set the current security information
124: ctx.setPrincipal(mi.getPrincipal());
125: // Set the JACC EnterpriseBean PolicyContextHandler data
126: EnterpriseBeanPolicyContextHandler.setEnterpriseBean(ctx
127: .getInstance());
128:
129: // Use this context
130: mi.setEnterpriseContext(ctx);
131:
132: // Timer invocation
133: if (ejbTimeout.equals(mi.getMethod())) {
134: AllowedOperationsAssociation
135: .pushInMethodFlag(IN_EJB_TIMEOUT);
136: }
137:
138: // Service Endpoint invocation
139: else if (mi.getValue(InvocationKey.SOAP_MESSAGE_CONTEXT) instanceof MessageContext) {
140: ctx.setMessageContext((MessageContext) mi
141: .getValue(InvocationKey.SOAP_MESSAGE_CONTEXT));
142: AllowedOperationsAssociation
143: .pushInMethodFlag(IN_SERVICE_ENDPOINT_METHOD);
144: }
145:
146: // Business Method Invocation
147: else {
148: AllowedOperationsAssociation
149: .pushInMethodFlag(IN_BUSINESS_METHOD);
150: }
151:
152: // There is no need for synchronization since the instance is always fresh also there should
153: // never be a tx associated with the instance.
154: try {
155: Object obj = getNext().invoke(mi);
156: return obj;
157:
158: } catch (RuntimeException e) // Instance will be GC'ed at MI return
159: {
160: mi.setEnterpriseContext(null);
161: throw e;
162: } catch (RemoteException e) // Instance will be GC'ed at MI return
163: {
164: mi.setEnterpriseContext(null);
165: throw e;
166: } catch (Error e) // Instance will be GC'ed at MI return
167: {
168: mi.setEnterpriseContext(null);
169: throw e;
170: } finally {
171: AllowedOperationsAssociation.popInMethodFlag();
172: EnterpriseBeanPolicyContextHandler.setEnterpriseBean(null);
173:
174: // Return context
175: if (mi.getEnterpriseContext() != null) {
176: pool.free(((EnterpriseContext) mi
177: .getEnterpriseContext()));
178: } else {
179: pool.discard(ctx);
180: }
181: }
182: }
183: }
|