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.mx.util.JMXExceptionDecoder;
47 import org.jboss.mx.util.MBeanServerLocator;
48
49 /**
50 * CachedConnectionInterceptor
51 *
52 * @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
53 * @author <a href="mailto:E.Guib@ceyoniq.com">Erwin Guib</a>
54 * @author <a href="mailto:adrian@jboss.com">Adrian Brock</a>
55 * @version $Revision: 76129 $
56 */
57 public class CachedConnectionInterceptor extends AbstractInterceptor implements EntityPersistenceManager
58 {
59 private final CachedConnectionManager ccm;
60
61 private final Logger log = Logger.getLogger(getClass());
62
63 private Container container;
64
65 private EntityPersistenceManager pm;
66
67 // contains the JNDI names of unshareable resources
68 private Set unsharableResources = new HashSet();
69
70 public CachedConnectionInterceptor() throws Exception
71 {
72 try
73 {
74 MBeanServer server = MBeanServerLocator.locateJBoss();
75 ccm = (CachedConnectionManager) server.getAttribute(CachedConnectionManagerMBean.OBJECT_NAME, "Instance");
76 }
77 catch (Exception e)
78 {
79 JMXExceptionDecoder.rethrow(e);
80 throw e;
81 }
82 }
83
84 @SuppressWarnings("deprecation")
85 public void start() throws Exception
86 {
87 log.debug("start called in CachedConnectionInterceptor");
88 if (container == null)
89 {
90 log.warn("container is null, can't steal persistence manager");
91 return;
92 }
93 if (container instanceof EntityContainer)
94 {
95 EntityContainer ec = (EntityContainer) container;
96
97 if (ec.getPersistenceManager() == null)
98 {
99 log.info("no persistence manager in container!");
100 return;
101 }
102 if (ec.getPersistenceManager() == this)
103 {
104 log.info(" persistence manager in container already set!");
105 return;
106 }
107 pm = ec.getPersistenceManager();
108 ec.setPersistenceManager(this);
109 }
110
111 // get the JNDI names for all resources that are referenced "Unshareable"
112 org.jboss.metadata.BeanMetaData bmd = container.getBeanMetaData();
113 org.jboss.metadata.ApplicationMetaData appMetaData = bmd.getApplicationMetaData();
114 org.jboss.metadata.ResourceRefMetaData resRefMetaData;
115 String jndiName;
116
117 for (Iterator iter = bmd.getResourceReferences(); iter.hasNext();)
118 {
119 resRefMetaData = (org.jboss.metadata.ResourceRefMetaData) iter.next();
120 jndiName = resRefMetaData.getJndiName();
121 if (jndiName == null)
122 {
123 jndiName = appMetaData.getResourceByName(resRefMetaData.getResourceName());
124 }
125 if (jndiName != null && resRefMetaData.isShareable() == false)
126 {
127 int i = jndiName.indexOf(':');
128 if (jndiName.charAt(i + 1) == '/')
129 {
130 i++;
131 }
132 unsharableResources.add(jndiName.substring(i + 1));
133 }
134 }
135
136 }
137
138 public void stop()
139 {
140 if (container != null && pm != null && ((EntityContainer) container).getPersistenceManager() == this)
141 {
142 ((EntityContainer) container).setPersistenceManager(pm);
143 pm = null;
144 }
145 unsharableResources.clear();
146 }
147
148 public Object invoke(Invocation mi) throws Exception
149 {
150 Object key = ((EnterpriseContext) mi.getEnterpriseContext()).getInstance();
151 try
152 {
153 ccm.pushMetaAwareObject(key, unsharableResources);
154 try
155 {
156 return getNext().invoke(mi);
157 }
158 finally
159 {
160 ccm.popMetaAwareObject(unsharableResources);
161 }
162 }
163 catch (ResourceException e)
164 {
165 InvocationType type = mi.getType();
166 boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
167 if (isLocal)
168 throw new EJBException("Resource problem during invoke", e);
169 else
170 throw new RemoteException("Resource problem during invoke", e);
171 }
172 }
173
174 public Object invokeHome(Invocation mi) throws Exception
175 {
176 EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext();
177 if (ctx == null)
178 return getNext().invokeHome(mi);
179 else
180 {
181 Object key = ctx.getInstance();
182 try
183 {
184 ccm.pushMetaAwareObject(key, unsharableResources);
185 try
186 {
187 return getNext().invokeHome(mi);
188 }
189 finally
190 {
191 ccm.popMetaAwareObject(unsharableResources);
192 }
193 }
194 catch (ResourceException e)
195 {
196 InvocationType type = mi.getType();
197 boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
198 if (isLocal)
199 throw new EJBException("Resource problem during invokeHome", e);
200 else
201 throw new RemoteException("Resource problem during invokeHome", e);
202 }
203 }
204 }
205
206 public void setContainer(Container container)
207 {
208 this.container = container;
209 }
210
211 public Container getContainer()
212 {
213 return container;
214 }
215
216 public Object createBeanClassInstance() throws Exception
217 {
218 return pm.createBeanClassInstance();
219 }
220
221 public void createEntity(Method m, Object[] args, EntityEnterpriseContext instance) throws Exception
222 {
223 pm.createEntity(m, args, instance);
224 }
225
226 public void postCreateEntity(Method m, Object[] args, EntityEnterpriseContext instance) throws Exception
227 {
228 pm.postCreateEntity(m, args, instance);
229 }
230
231 public Object findEntity(Method finderMethod, Object[] args, EntityEnterpriseContext instance,
232 GenericEntityObjectFactory factory) throws Exception
233 {
234 return pm.findEntity(finderMethod, args, instance, factory);
235 }
236
237 public Collection findEntities(Method finderMethod, Object[] args, EntityEnterpriseContext instance,
238 GenericEntityObjectFactory factory) throws Exception
239 {
240 return pm.findEntities(finderMethod, args, instance, factory);
241 }
242
243 public void activateEntity(EntityEnterpriseContext instance) throws RemoteException
244 {
245 pm.activateEntity(instance);
246 }
247
248 public void loadEntity(EntityEnterpriseContext instance) throws RemoteException
249 {
250 pm.loadEntity(instance);
251 }
252
253 public boolean isStoreRequired(EntityEnterpriseContext instance) throws Exception
254 {
255 return pm.isStoreRequired(instance);
256 }
257
258 public boolean isModified(EntityEnterpriseContext ctx) throws Exception
259 {
260 return pm.isModified(ctx);
261 }
262
263 public void storeEntity(EntityEnterpriseContext ctx) throws RemoteException
264 {
265 Object key = ctx.getInstance();
266 try
267 {
268 ccm.pushMetaAwareObject(key, unsharableResources);
269 try
270 {
271 pm.storeEntity(ctx);
272 }
273 finally
274 {
275 ccm.popMetaAwareObject(unsharableResources);
276 }
277 }
278 catch (ResourceException e)
279 {
280 throw new RemoteException("Could not store!: ", e);
281 }
282 }
283
284 public void invokeEjbStore(EntityEnterpriseContext ctx) throws RemoteException
285 {
286 Object key = ctx.getInstance();
287 try
288 {
289 ccm.pushMetaAwareObject(key, unsharableResources);
290 try
291 {
292 pm.invokeEjbStore(ctx);
293 }
294 finally
295 {
296 ccm.popMetaAwareObject(unsharableResources);
297 }
298 }
299 catch (ResourceException e)
300 {
301 throw new RemoteException("Could not store!: ", e);
302 }
303 }
304
305 public void passivateEntity(EntityEnterpriseContext instance) throws RemoteException
306 {
307 pm.passivateEntity(instance);
308 }
309
310 public void removeEntity(EntityEnterpriseContext instance) throws RemoteException, RemoveException
311 {
312 pm.removeEntity(instance);
313 }
314
315 /**
316 Return the real EntityPersistenceManager to which this interceptor delegates.
317 @return the real EntityPersistenceManager
318 */
319 public EntityPersistenceManager getDelegatePersistenceManager()
320 {
321 return pm;
322 }
323 }