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:
031: import org.jboss.ejb.AllowedOperationsAssociation;
032: import org.jboss.ejb.EnterpriseContext;
033: import org.jboss.ejb.InstancePool;
034: import org.jboss.ejb.MessageDrivenContainer;
035: import org.jboss.invocation.Invocation;
036:
037: /**
038: * This container acquires the given instance. This must be used after
039: * the EnvironmentInterceptor, since acquiring instances requires a proper
040: * JNDI environment to be set.
041: *
042: * @author <a href="mailto:peter.antman@tim.se">Peter Antman</a>.
043: * @author <a href="mailto:rickard.oberg@telkel.com">Rickard Öberg</a>
044: * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
045: * @version $Revision: 59509 $
046: */
047: public class MessageDrivenInstanceInterceptor extends
048: AbstractInterceptor {
049:
050: /** A reference to {@link javax.ejb.TimedObject#ejbTimeout}. */
051: protected static final Method ejbTimeout;
052: static {
053: try {
054: ejbTimeout = TimedObject.class.getMethod("ejbTimeout",
055: new Class[] { Timer.class });
056: } catch (Exception e) {
057: throw new ExceptionInInitializerError(e);
058: }
059: }
060:
061: /**
062: * Message driven beans do not have homes.
063: *
064: * @throws Error Not valid for MessageDriven beans.
065: */
066: public Object invokeHome(final Invocation mi) throws Exception {
067: throw new Error("Not valid for MessageDriven beans");
068: }
069:
070: // Interceptor implementation --------------------------------------
071:
072: public Object invoke(final Invocation mi) throws Exception {
073: // Get context
074: MessageDrivenContainer mdc = (MessageDrivenContainer) container;
075: InstancePool pool = mdc.getInstancePool();
076: EnterpriseContext ctx = null;
077: try {
078: ctx = pool.get();
079: } catch (EJBException e) {
080: throw e;
081: } catch (Exception e) {
082: throw new EJBException(
083: "Unable to get an instance from the pool", e);
084: }
085:
086: // Set the current security information
087: ctx.setPrincipal(mi.getPrincipal());
088:
089: // Use this context
090: mi.setEnterpriseContext(ctx);
091: // Set the JACC EnterpriseBean PolicyContextHandler data
092: EnterpriseBeanPolicyContextHandler.setEnterpriseBean(ctx
093: .getInstance());
094:
095: if (ejbTimeout.equals(mi.getMethod()))
096: AllowedOperationsAssociation
097: .pushInMethodFlag(IN_EJB_TIMEOUT);
098: else
099: AllowedOperationsAssociation
100: .pushInMethodFlag(IN_BUSINESS_METHOD);
101:
102: // There is no need for synchronization since the instance is always
103: // fresh also there should never be a tx associated with the instance.
104: try {
105: // Invoke through interceptors
106: Object obj = getNext().invoke(mi);
107: return obj;
108: } catch (RuntimeException e) // Instance will be GC'ed at MI return
109: {
110: mi.setEnterpriseContext(null);
111: throw e;
112: } catch (RemoteException e) // Instance will be GC'ed at MI return
113: {
114: mi.setEnterpriseContext(null);
115: throw e;
116: } catch (Error e) // Instance will be GC'ed at MI return
117: {
118: mi.setEnterpriseContext(null);
119: throw e;
120: } finally {
121: AllowedOperationsAssociation.popInMethodFlag();
122: EnterpriseBeanPolicyContextHandler.setEnterpriseBean(null);
123:
124: // Return context
125: if (mi.getEnterpriseContext() != null) {
126: pool
127: .free((EnterpriseContext) mi
128: .getEnterpriseContext());
129: } else {
130: pool.discard(ctx);
131: }
132: }
133: }
134:
135: }
|