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 org.jboss.ejb.EntityContainer;
025: import org.jboss.ejb.EntityPersistenceManager;
026: import org.jboss.ejb.EntityEnterpriseContext;
027: import org.jboss.ejb.InstancePool;
028: import org.jboss.ejb.AllowedOperationsAssociation;
029: import org.jboss.invocation.Invocation;
030: import org.jboss.invocation.InvocationType;
031:
032: import javax.ejb.EJBException;
033: import javax.ejb.TimedObject;
034: import javax.ejb.Timer;
035: import java.lang.reflect.Method;
036: import java.rmi.RemoteException;
037:
038: /**
039: * @deprecated this interceptor was used with Instance Per Transaction containers which do not use a global cache
040: * but cache instances per transaction and always passivate instances at commit time (commit option C).
041: * This interceptor used org.jboss.ejb.TxEntityMap to compensate the absence of a real per transaction cache implementation.
042: * Now, the differences between IPT and standard container are:
043: * <ul>
044: * <li>org.jboss.ejb.plugins.PerTxEntityInstanceCache as the cache implementation;</li>
045: * <li>NoLock as the locking policy;</li>
046: * <li>empty container-cache-conf element.</li>
047: * </ul>
048: * (alex@jboss.org)
049: *
050: * The instance interceptors role is to acquire a context representing
051: * the target object from the cache.
052: *
053: * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
054: * @version $Revision: 59508 $
055: */
056: public class EntityMultiInstanceInterceptor extends AbstractInterceptor {
057: // Constants -----------------------------------------------------
058:
059: // Attributes ----------------------------------------------------
060:
061: // Static --------------------------------------------------------
062:
063: /** A reference to {@link javax.ejb.TimedObject#ejbTimeout}. */
064: protected static final Method ejbTimeout;
065: static {
066: try {
067: ejbTimeout = TimedObject.class.getMethod("ejbTimeout",
068: new Class[] { Timer.class });
069: } catch (Exception e) {
070: throw new ExceptionInInitializerError(e);
071: }
072: }
073:
074: // Constructors --------------------------------------------------
075:
076: // Public --------------------------------------------------------
077:
078: // Interceptor implementation --------------------------------------
079:
080: public Object invokeHome(Invocation mi) throws Exception {
081: // Get context
082: EntityContainer ec = (EntityContainer) getContainer();
083: EntityEnterpriseContext ctx = (EntityEnterpriseContext) ec
084: .getInstancePool().get();
085:
086: // Pass it to the method invocation
087: mi.setEnterpriseContext(ctx);
088:
089: // Give it the transaction
090: ctx.setTransaction(mi.getTransaction());
091:
092: // Set the current security information
093: ctx.setPrincipal(mi.getPrincipal());
094:
095: AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_HOME);
096:
097: Object result;
098: try {
099: // Invoke through interceptors
100: result = getNext().invokeHome(mi);
101: } finally {
102: AllowedOperationsAssociation.popInMethodFlag();
103: }
104:
105: // No id, means we can put the context back in the pool
106: if (ctx.getId() == null) {
107: ctx.setTransaction(null);
108: ec.getInstancePool().free(ctx);
109: }
110:
111: // We are done
112: return result;
113: }
114:
115: public Object invoke(Invocation mi) throws Exception {
116:
117: // The key
118: Object key = mi.getId();
119:
120: EntityEnterpriseContext ctx = null;
121: EntityContainer ec = (EntityContainer) container;
122: if (mi.getTransaction() != null) {
123: //ctx = ec.getTxEntityMap().getCtx(mi.getTransaction(), key);
124: }
125: if (ctx == null) {
126: InstancePool pool = ec.getInstancePool();
127: try {
128: ctx = (EntityEnterpriseContext) pool.get();
129: } catch (EJBException e) {
130: throw e;
131: } catch (RemoteException e) {
132: throw e;
133: } catch (Exception e) {
134: InvocationType type = mi.getType();
135: boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
136: if (isLocal)
137: throw new EJBException(
138: "Unable to get an instance from the pool",
139: e);
140: else
141: throw new RemoteException(
142: "Unable to get an intance from the pool", e);
143: }
144: ctx.setCacheKey(key);
145: ctx.setId(key);
146: EntityPersistenceManager pm = ec.getPersistenceManager();
147: pm.activateEntity(ctx);
148: }
149:
150: boolean trace = log.isTraceEnabled();
151: if (trace)
152: log.trace("Begin invoke, key=" + key);
153:
154: // Associate transaction, in the new design the lock already has the transaction from the
155: // previous interceptor
156: ctx.setTransaction(mi.getTransaction());
157:
158: // Set the current security information
159: ctx.setPrincipal(mi.getPrincipal());
160: // Set the JACC EnterpriseBean PolicyContextHandler data
161: EnterpriseBeanPolicyContextHandler.setEnterpriseBean(ctx
162: .getInstance());
163:
164: // Set context on the method invocation
165: mi.setEnterpriseContext(ctx);
166:
167: if (ejbTimeout.equals(mi.getMethod()))
168: AllowedOperationsAssociation
169: .pushInMethodFlag(IN_EJB_TIMEOUT);
170: else
171: AllowedOperationsAssociation
172: .pushInMethodFlag(IN_BUSINESS_METHOD);
173:
174: try {
175: Object ret = getNext().invoke(mi);
176: return ret;
177: } finally {
178: AllowedOperationsAssociation.popInMethodFlag();
179: EnterpriseBeanPolicyContextHandler.setEnterpriseBean(null);
180: }
181: }
182: }
|