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.resource.connectionmanager;
023:
024: import java.lang.reflect.Method;
025: import java.rmi.RemoteException;
026: import java.util.Collection;
027: import java.util.HashSet;
028: import java.util.Iterator;
029: import java.util.Set;
030:
031: import javax.ejb.EJBException;
032: import javax.ejb.RemoveException;
033: import javax.management.MBeanServer;
034: import javax.resource.ResourceException;
035:
036: import org.jboss.ejb.Container;
037: import org.jboss.ejb.EnterpriseContext;
038: import org.jboss.ejb.EntityContainer;
039: import org.jboss.ejb.EntityEnterpriseContext;
040: import org.jboss.ejb.EntityPersistenceManager;
041: import org.jboss.ejb.GenericEntityObjectFactory;
042: import org.jboss.ejb.plugins.AbstractInterceptor;
043: import org.jboss.invocation.Invocation;
044: import org.jboss.invocation.InvocationType;
045: import org.jboss.logging.Logger;
046: import org.jboss.metadata.ApplicationMetaData;
047: import org.jboss.metadata.BeanMetaData;
048: import org.jboss.metadata.ResourceRefMetaData;
049: import org.jboss.mx.util.JMXExceptionDecoder;
050: import org.jboss.mx.util.MBeanServerLocator;
051:
052: /**
053: * CachedConnectionInterceptor
054: *
055: * @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
056: * @author <a href="mailto:E.Guib@ceyoniq.com">Erwin Guib</a>
057: * @author <a href="mailto:adrian@jboss.com">Adrian Brock</a>
058: * @version $Revision: 57189 $
059: */
060: public class CachedConnectionInterceptor extends AbstractInterceptor
061: implements EntityPersistenceManager {
062: private final CachedConnectionManager ccm;
063:
064: private final Logger log = Logger.getLogger(getClass());
065:
066: private Container container;
067:
068: private EntityPersistenceManager pm;
069:
070: // contains the JNDI names of unshareable resources
071: private Set unsharableResources = new HashSet();
072:
073: public CachedConnectionInterceptor() throws Exception {
074: try {
075: MBeanServer server = MBeanServerLocator.locateJBoss();
076: ccm = (CachedConnectionManager) server.getAttribute(
077: CachedConnectionManagerMBean.OBJECT_NAME,
078: "Instance");
079: } catch (Exception e) {
080: JMXExceptionDecoder.rethrow(e);
081: throw e;
082: }
083: }
084:
085: public void start() throws Exception {
086: log.debug("start called in CachedConnectionInterceptor");
087: if (container == null) {
088: log
089: .warn("container is null, can't steal persistence manager");
090: return;
091: }
092: if (container instanceof EntityContainer) {
093: EntityContainer ec = (EntityContainer) container;
094:
095: if (ec.getPersistenceManager() == null) {
096: log.info("no persistence manager in container!");
097: return;
098: }
099: if (ec.getPersistenceManager() == this ) {
100: log
101: .info(" persistence manager in container already set!");
102: return;
103: }
104: pm = ec.getPersistenceManager();
105: ec.setPersistenceManager(this );
106: }
107:
108: // get the JNDI names for all resources that are referenced "Unshareable"
109: BeanMetaData bmd = container.getBeanMetaData();
110: ApplicationMetaData appMetaData = bmd.getApplicationMetaData();
111: ResourceRefMetaData resRefMetaData;
112: String jndiName;
113:
114: for (Iterator iter = bmd.getResourceReferences(); iter
115: .hasNext();) {
116: resRefMetaData = (ResourceRefMetaData) iter.next();
117: jndiName = resRefMetaData.getJndiName();
118: if (jndiName == null) {
119: jndiName = appMetaData.getResourceByName(resRefMetaData
120: .getResourceName());
121: }
122: if (jndiName != null
123: && resRefMetaData.isShareable() == false) {
124: int i = jndiName.indexOf(':');
125: if (jndiName.charAt(i + 1) == '/') {
126: i++;
127: }
128: unsharableResources.add(jndiName.substring(i + 1));
129: }
130: }
131:
132: }
133:
134: public void stop() {
135: if (container != null
136: && pm != null
137: && ((EntityContainer) container)
138: .getPersistenceManager() == this ) {
139: ((EntityContainer) container).setPersistenceManager(pm);
140: pm = null;
141: }
142: unsharableResources.clear();
143: }
144:
145: public Object invoke(Invocation mi) throws Exception {
146: Object key = ((EnterpriseContext) mi.getEnterpriseContext())
147: .getInstance();
148: try {
149: ccm.pushMetaAwareObject(key, unsharableResources);
150: try {
151: return getNext().invoke(mi);
152: } finally {
153: ccm.popMetaAwareObject(unsharableResources);
154: }
155: } catch (ResourceException e) {
156: InvocationType type = mi.getType();
157: boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
158: if (isLocal)
159: throw new EJBException(
160: "Resource problem during invoke", e);
161: else
162: throw new RemoteException(
163: "Resource problem during invoke", e);
164: }
165: }
166:
167: public Object invokeHome(Invocation mi) throws Exception {
168: EnterpriseContext ctx = (EnterpriseContext) mi
169: .getEnterpriseContext();
170: if (ctx == null)
171: return getNext().invokeHome(mi);
172: else {
173: Object key = ctx.getInstance();
174: try {
175: ccm.pushMetaAwareObject(key, unsharableResources);
176: try {
177: return getNext().invokeHome(mi);
178: } finally {
179: ccm.popMetaAwareObject(unsharableResources);
180: }
181: } catch (ResourceException e) {
182: InvocationType type = mi.getType();
183: boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
184: if (isLocal)
185: throw new EJBException(
186: "Resource problem during invokeHome", e);
187: else
188: throw new RemoteException(
189: "Resource problem during invokeHome", e);
190: }
191: }
192: }
193:
194: public void setContainer(Container container) {
195: this .container = container;
196: }
197:
198: public Container getContainer() {
199: return container;
200: }
201:
202: public Object createBeanClassInstance() throws Exception {
203: return pm.createBeanClassInstance();
204: }
205:
206: public void createEntity(Method m, Object[] args,
207: EntityEnterpriseContext instance) throws Exception {
208: pm.createEntity(m, args, instance);
209: }
210:
211: public void postCreateEntity(Method m, Object[] args,
212: EntityEnterpriseContext instance) throws Exception {
213: pm.postCreateEntity(m, args, instance);
214: }
215:
216: public Object findEntity(Method finderMethod, Object[] args,
217: EntityEnterpriseContext instance,
218: GenericEntityObjectFactory factory) throws Exception {
219: return pm.findEntity(finderMethod, args, instance, factory);
220: }
221:
222: public Collection findEntities(Method finderMethod, Object[] args,
223: EntityEnterpriseContext instance,
224: GenericEntityObjectFactory factory) throws Exception {
225: return pm.findEntities(finderMethod, args, instance, factory);
226: }
227:
228: public void activateEntity(EntityEnterpriseContext instance)
229: throws RemoteException {
230: pm.activateEntity(instance);
231: }
232:
233: public void loadEntity(EntityEnterpriseContext instance)
234: throws RemoteException {
235: pm.loadEntity(instance);
236: }
237:
238: public boolean isStoreRequired(EntityEnterpriseContext instance)
239: throws Exception {
240: return pm.isStoreRequired(instance);
241: }
242:
243: public boolean isModified(EntityEnterpriseContext ctx)
244: throws Exception {
245: return pm.isModified(ctx);
246: }
247:
248: public void storeEntity(EntityEnterpriseContext ctx)
249: throws RemoteException {
250: Object key = ctx.getInstance();
251: try {
252: ccm.pushMetaAwareObject(key, unsharableResources);
253: try {
254: pm.storeEntity(ctx);
255: } finally {
256: ccm.popMetaAwareObject(unsharableResources);
257: }
258: } catch (ResourceException e) {
259: throw new RemoteException("Could not store!: ", e);
260: }
261: }
262:
263: public void invokeEjbStore(EntityEnterpriseContext ctx)
264: throws RemoteException {
265: Object key = ctx.getInstance();
266: try {
267: ccm.pushMetaAwareObject(key, unsharableResources);
268: try {
269: pm.invokeEjbStore(ctx);
270: } finally {
271: ccm.popMetaAwareObject(unsharableResources);
272: }
273: } catch (ResourceException e) {
274: throw new RemoteException("Could not store!: ", e);
275: }
276: }
277:
278: public void passivateEntity(EntityEnterpriseContext instance)
279: throws RemoteException {
280: pm.passivateEntity(instance);
281: }
282:
283: public void removeEntity(EntityEnterpriseContext instance)
284: throws RemoteException, RemoveException {
285: pm.removeEntity(instance);
286: }
287:
288: /**
289: Return the real EntityPersistenceManager to which this interceptor delegates.
290: @return the real EntityPersistenceManager
291: */
292: public EntityPersistenceManager getDelegatePersistenceManager() {
293: return pm;
294: }
295: }
|