1 /*
2 * JBoss, Home of Professional Open Source.
3 * Copyright 2006, Red Hat Middleware LLC, and individual contributors
4 * as indicated by the @author tags. See the copyright.txt file in the
5 * distribution for a full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22 package org.jboss.resource.connectionmanager;
23
24 import java.lang.reflect.Method;
25 import java.rmi.RemoteException;
26 import java.util.Collection;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.Set;
30
31 import javax.ejb.EJBException;
32 import javax.ejb.RemoveException;
33 import javax.management.MBeanServer;
34 import javax.resource.ResourceException;
35
36 import org.jboss.ejb.Container;
37 import org.jboss.ejb.EnterpriseContext;
38 import org.jboss.ejb.EntityContainer;
39 import org.jboss.ejb.EntityEnterpriseContext;
40 import org.jboss.ejb.EntityPersistenceManager;
41 import org.jboss.ejb.GenericEntityObjectFactory;
42 import org.jboss.ejb.plugins.AbstractInterceptor;
43 import org.jboss.invocation.Invocation;
44 import org.jboss.invocation.InvocationType;
45 import org.jboss.logging.Logger;
46 import org.jboss.metadata.ApplicationMetaData;
47 import org.jboss.metadata.BeanMetaData;
48 import org.jboss.metadata.ResourceRefMetaData;
49 import org.jboss.mx.util.JMXExceptionDecoder;
50 import org.jboss.mx.util.MBeanServerLocator;
51
52 /**
53 * CachedConnectionInterceptor
54 *
55 * @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
56 * @author <a href="mailto:E.Guib@ceyoniq.com">Erwin Guib</a>
57 * @author <a href="mailto:adrian@jboss.com">Adrian Brock</a>
58 * @version $Revision: 71554 $
59 */
60 public class CachedConnectionInterceptor extends AbstractInterceptor implements EntityPersistenceManager
61 {
62 private final CachedConnectionManager ccm;
63
64 private final Logger log = Logger.getLogger(getClass());
65
66 private Container container;
67
68 private EntityPersistenceManager pm;
69
70 // contains the JNDI names of unshareable resources
71 private Set unsharableResources = new HashSet();
72
73 public CachedConnectionInterceptor() throws Exception
74 {
75 try
76 {
77 MBeanServer server = MBeanServerLocator.locateJBoss();
78 ccm = (CachedConnectionManager) server.getAttribute(CachedConnectionManagerMBean.OBJECT_NAME, "Instance");
79 }
80 catch (Exception e)
81 {
82 JMXExceptionDecoder.rethrow(e);
83 throw e;
84 }
85 }
86
87 public void start() throws Exception
88 {
89 log.debug("start called in CachedConnectionInterceptor");
90 if (container == null)
91 {
92 log.warn("container is null, can't steal persistence manager");
93 return;
94 }
95 if (container instanceof EntityContainer)
96 {
97 EntityContainer ec = (EntityContainer) container;
98
99 if (ec.getPersistenceManager() == null)
100 {
101 log.info("no persistence manager in container!");
102 return;
103 }
104 if (ec.getPersistenceManager() == this)
105 {
106 log.info(" persistence manager in container already set!");
107 return;
108 }
109 pm = ec.getPersistenceManager();
110 ec.setPersistenceManager(this);
111 }
112
113 // get the JNDI names for all resources that are referenced "Unshareable"
114 BeanMetaData bmd = container.getBeanMetaData();
115 ApplicationMetaData appMetaData = bmd.getApplicationMetaData();
116 ResourceRefMetaData resRefMetaData;
117 String jndiName;
118
119 for (Iterator iter = bmd.getResourceReferences(); iter.hasNext();)
120 {
121 resRefMetaData = (ResourceRefMetaData) iter.next();
122 jndiName = resRefMetaData.getJndiName();
123 if (jndiName == null)
124 {
125 jndiName = appMetaData.getResourceByName(resRefMetaData.getResourceName());
126 }
127 if (jndiName != null && resRefMetaData.isShareable() == false)
128 {
129 int i = jndiName.indexOf(':');
130 if (jndiName.charAt(i + 1) == '/')
131 {
132 i++;
133 }
134 unsharableResources.add(jndiName.substring(i + 1));
135 }
136 }
137
138 }
139
140 public void stop()
141 {
142 if (container != null && pm != null && ((EntityContainer) container).getPersistenceManager() == this)
143 {
144 ((EntityContainer) container).setPersistenceManager(pm);
145 pm = null;
146 }
147 unsharableResources.clear();
148 }
149
150 public Object invoke(Invocation mi) throws Exception
151 {
152 Object key = ((EnterpriseContext) mi.getEnterpriseContext()).getInstance();
153 try
154 {
155 ccm.pushMetaAwareObject(key, unsharableResources);
156 try
157 {
158 return getNext().invoke(mi);
159 }
160 finally
161 {
162 ccm.popMetaAwareObject(unsharableResources);
163 }
164 }
165 catch (ResourceException e)
166 {
167 InvocationType type = mi.getType();
168 boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
169 if (isLocal)
170 throw new EJBException("Resource problem during invoke", e);
171 else
172 throw new RemoteException("Resource problem during invoke", e);
173 }
174 }
175
176 public Object invokeHome(Invocation mi) throws Exception
177 {
178 EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext();
179 if (ctx == null)
180 return getNext().invokeHome(mi);
181 else
182 {
183 Object key = ctx.getInstance();
184 try
185 {
186 ccm.pushMetaAwareObject(key, unsharableResources);
187 try
188 {
189 return getNext().invokeHome(mi);
190 }
191 finally
192 {
193 ccm.popMetaAwareObject(unsharableResources);
194 }
195 }
196 catch (ResourceException e)
197 {
198 InvocationType type = mi.getType();
199 boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
200 if (isLocal)
201 throw new EJBException("Resource problem during invokeHome", e);
202 else
203 throw new RemoteException("Resource problem during invokeHome", e);
204 }
205 }
206 }
207
208 public void setContainer(Container container)
209 {
210 this.container = container;
211 }
212
213 public Container getContainer()
214 {
215 return container;
216 }
217
218 public Object createBeanClassInstance() throws Exception
219 {
220 return pm.createBeanClassInstance();
221 }
222
223 public void createEntity(Method m, Object[] args, EntityEnterpriseContext instance) throws Exception
224 {
225 pm.createEntity(m, args, instance);
226 }
227
228 public void postCreateEntity(Method m, Object[] args, EntityEnterpriseContext instance) throws Exception
229 {
230 pm.postCreateEntity(m, args, instance);
231 }
232
233 public Object findEntity(Method finderMethod, Object[] args, EntityEnterpriseContext instance,
234 GenericEntityObjectFactory factory) throws Exception
235 {
236 return pm.findEntity(finderMethod, args, instance, factory);
237 }
238
239 public Collection findEntities(Method finderMethod, Object[] args, EntityEnterpriseContext instance,
240 GenericEntityObjectFactory factory) throws Exception
241 {
242 return pm.findEntities(finderMethod, args, instance, factory);
243 }
244
245 public void activateEntity(EntityEnterpriseContext instance) throws RemoteException
246 {
247 pm.activateEntity(instance);
248 }
249
250 public void loadEntity(EntityEnterpriseContext instance) throws RemoteException
251 {
252 pm.loadEntity(instance);
253 }
254
255 public boolean isStoreRequired(EntityEnterpriseContext instance) throws Exception
256 {
257 return pm.isStoreRequired(instance);
258 }
259
260 public boolean isModified(EntityEnterpriseContext ctx) throws Exception
261 {
262 return pm.isModified(ctx);
263 }
264
265 public void storeEntity(EntityEnterpriseContext ctx) throws RemoteException
266 {
267 Object key = ctx.getInstance();
268 try
269 {
270 ccm.pushMetaAwareObject(key, unsharableResources);
271 try
272 {
273 pm.storeEntity(ctx);
274 }
275 finally
276 {
277 ccm.popMetaAwareObject(unsharableResources);
278 }
279 }
280 catch (ResourceException e)
281 {
282 throw new RemoteException("Could not store!: ", e);
283 }
284 }
285
286 public void invokeEjbStore(EntityEnterpriseContext ctx) throws RemoteException
287 {
288 Object key = ctx.getInstance();
289 try
290 {
291 ccm.pushMetaAwareObject(key, unsharableResources);
292 try
293 {
294 pm.invokeEjbStore(ctx);
295 }
296 finally
297 {
298 ccm.popMetaAwareObject(unsharableResources);
299 }
300 }
301 catch (ResourceException e)
302 {
303 throw new RemoteException("Could not store!: ", e);
304 }
305 }
306
307 public void passivateEntity(EntityEnterpriseContext instance) throws RemoteException
308 {
309 pm.passivateEntity(instance);
310 }
311
312 public void removeEntity(EntityEnterpriseContext instance) throws RemoteException, RemoveException
313 {
314 pm.removeEntity(instance);
315 }
316
317 /**
318 Return the real EntityPersistenceManager to which this interceptor delegates.
319 @return the real EntityPersistenceManager
320 */
321 public EntityPersistenceManager getDelegatePersistenceManager()
322 {
323 return pm;
324 }
325 }