1 22 package org.jboss.ejb.plugins; 23 24 import org.jboss.ejb.BeanLock; 25 import org.jboss.ejb.Container; 26 import org.jboss.ejb.EntityContainer; 27 import org.jboss.ejb.EntityEnterpriseContext; 28 import org.jboss.ejb.InstanceCache; 29 import org.jboss.ejb.AllowedOperationsAssociation; 30 import org.jboss.ejb.InstancePool; 31 import org.jboss.invocation.Invocation; 32 import org.jboss.invocation.InvocationType; 33 import org.jboss.util.NestedRuntimeException; 34 35 import javax.ejb.EJBException ; 36 import javax.ejb.NoSuchObjectLocalException ; 37 import javax.ejb.TimedObject ; 38 import javax.ejb.Timer ; 39 import javax.transaction.Transaction ; 40 import java.lang.reflect.Method ; 41 import java.rmi.NoSuchObjectException ; 42 import java.rmi.RemoteException ; 43 44 66 public class EntityInstanceInterceptor 67 extends AbstractInterceptor 68 { 69 71 73 protected EntityContainer container; 74 75 77 78 protected static final Method ejbTimeout; 79 80 static 81 { 82 try 83 { 84 ejbTimeout = TimedObject .class.getMethod("ejbTimeout", new Class []{Timer .class}); 85 } 86 catch (Exception e) 87 { 88 throw new ExceptionInInitializerError (e); 89 } 90 } 91 92 94 96 public void setContainer(Container container) 97 { 98 this.container = (EntityContainer) container; 99 } 100 101 public Container getContainer() 102 { 103 return container; 104 } 105 106 108 public Object invokeHome(Invocation mi) 109 throws Exception 110 { 111 EntityContainer container = (EntityContainer) getContainer(); 113 EntityEnterpriseContext ctx = (EntityEnterpriseContext) container.getInstancePool().get(); 114 InstancePool pool = container.getInstancePool(); 115 116 mi.setEnterpriseContext(ctx); 118 119 ctx.setTransaction(mi.getTransaction()); 121 122 ctx.setPrincipal(mi.getPrincipal()); 124 125 AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_HOME); 126 127 129 Object obj = null; 130 Exception exception = null; 131 132 try 133 { 134 obj = getNext().invokeHome(mi); 135 136 if (ctx.getId() != null) 138 { 139 BeanLock lock = container.getLockManager().getLock(ctx.getCacheKey()); 140 lock.sync(); try 142 { 143 InstanceCache cache = container.getInstanceCache(); 147 cache.remove(ctx.getCacheKey()); 148 149 cache.insert(ctx); 152 } 153 finally 154 { 155 lock.releaseSync(); 156 container.getLockManager().removeLockRef(ctx.getCacheKey()); 157 } 158 159 return obj; 161 } 162 } 163 catch (Exception e) 164 { 165 exception = e; 166 } 167 finally 168 { 169 AllowedOperationsAssociation.popInMethodFlag(); 170 } 171 172 ctx.setTransaction(null); 173 mi.setEnterpriseContext(null); 175 176 if (exception == null) 179 { 180 container.getInstancePool().free(ctx); 181 return obj; 182 } 183 184 if (exception instanceof RuntimeException ) 185 { 186 pool.discard(ctx); 189 } 190 else 191 { 192 pool.free(ctx); 196 } 197 198 throw exception; 199 } 200 201 202 public Object invoke(Invocation mi) 203 throws Exception 204 { 205 boolean trace = log.isTraceEnabled(); 206 207 Object key = mi.getId(); 209 210 EntityEnterpriseContext ctx; 212 try 213 { 214 ctx = (EntityEnterpriseContext) container.getInstanceCache().get(key); 215 } 216 catch (NoSuchObjectException e) 217 { 218 if (mi.isLocal()) 219 throw new NoSuchObjectLocalException (e.getMessage()); 220 else 221 throw e; 222 } 223 catch (EJBException e) 224 { 225 throw e; 226 } 227 catch (RemoteException e) 228 { 229 throw e; 230 } 231 catch (Exception e) 232 { 233 InvocationType type = mi.getType(); 234 boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME); 235 if (isLocal) 236 throw new EJBException ("Unable to get an instance from the pool/cache", e); 237 else 238 throw new RemoteException ("Unable to get an intance from the pool/cache", e); 239 } 240 241 if (trace) log.trace("Begin invoke, key=" + key); 242 243 246 Transaction tx = mi.getTransaction(); 249 if (!container.isReadOnly()) 250 { 251 Method method = mi.getMethod(); 252 if (method == null || 253 !container.getBeanMetaData().isMethodReadOnly(method.getName())) 254 { 255 ctx.setTransaction(tx); 256 } 257 } 258 259 ctx.setPrincipal(mi.getPrincipal()); 261 EnterpriseBeanPolicyContextHandler.setEnterpriseBean(ctx.getInstance()); 263 264 mi.setEnterpriseContext(ctx); 266 267 if (ejbTimeout.equals(mi.getMethod())) 268 AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_TIMEOUT); 269 else 270 AllowedOperationsAssociation.pushInMethodFlag(IN_BUSINESS_METHOD); 271 272 Throwable exceptionThrown = null; 273 boolean discardContext = false; 274 try 275 { 276 Object obj = getNext().invoke(mi); 277 return obj; 278 } 279 catch (RemoteException e) 280 { 281 exceptionThrown = e; 282 discardContext = true; 283 throw e; 284 } 285 catch (RuntimeException e) 286 { 287 exceptionThrown = e; 288 discardContext = true; 289 throw e; 290 } 291 catch (Error e) 292 { 293 exceptionThrown = e; 294 discardContext = true; 295 throw e; 296 } 297 catch (Exception e) 298 { 299 exceptionThrown = e; 300 throw e; 301 } 302 catch (Throwable e) 303 { 304 exceptionThrown = e; 305 discardContext = true; 306 throw new NestedRuntimeException(e); 307 } 308 finally 309 { 310 AllowedOperationsAssociation.popInMethodFlag(); 311 312 if (exceptionThrown != null && tx != null) 316 { 317 Transaction ctxTx = ctx.getTransaction(); 318 if (tx.equals(ctxTx) && ctx.hasTxSynchronization() == false) 319 ctx.setTransaction(null); 320 } 321 322 if (exceptionThrown != null && 324 !ctx.hasTxSynchronization() && discardContext) 329 { 330 container.getInstanceCache().remove(key); 333 334 if (trace) log.trace("Ending invoke, exceptionThrown, ctx=" + ctx, exceptionThrown); 335 } 336 else if (ctx.getId() == null) 337 { 338 container.getInstanceCache().remove(key); 340 341 if (trace) log.trace("Ending invoke, cache removal, ctx=" + ctx); 342 } 344 345 if (trace) log.trace("End invoke, key=" + key + ", ctx=" + ctx); 346 347 } } 349 } 350 351 | Popular Tags |