1 25 26 package org.objectweb.jonas_ejb.container; 27 28 import java.lang.reflect.InvocationHandler ; 29 import java.lang.reflect.InvocationTargetException ; 30 import java.lang.reflect.Method ; 31 import java.lang.reflect.Proxy ; 32 33 import javax.ejb.MessageDrivenBean ; 34 import javax.ejb.EJBException ; 35 import javax.resource.ResourceException ; 36 import javax.resource.spi.IllegalStateException ; 37 import javax.transaction.xa.XAResource ; 38 39 import org.objectweb.jonas_ejb.deployment.api.MethodDesc; 40 41 import org.objectweb.transaction.jta.TransactionManager; 42 import org.objectweb.util.monolog.api.BasicLevel; 43 44 51 public class JMessageEndpointProxy implements InvocationHandler { 52 53 protected JMdbEndpointFactory bf = null; 54 55 protected JMessageEndpoint ep = null; 56 57 protected MessageDrivenBean mdb = null; 58 59 protected TransactionManager tm = null; 60 61 boolean b4Delivery = false; 62 63 int msgCount = 0; 64 65 private transient static ThreadLocal requestCtx = new ThreadLocal (); 68 69 76 public JMessageEndpointProxy(JMdbEndpointFactory bf, MessageDrivenBean mdb, JMessageEndpoint ep) { 77 this.bf = bf; 78 this.mdb = mdb; 79 this.ep = ep; 80 tm = bf.getTransactionManager(); 82 } 83 84 88 public Object invoke(Object obj, Method method, Object [] aobj) throws Throwable , NoSuchMethodException , 89 ResourceException , Exception { 90 RequestCtx rctx = null; 91 String methodName = method.getName(); 92 Object ret = null; 93 Throwable invokeEx = null; 94 95 if (TraceEjb.isDebugJms()) { 96 TraceEjb.mdb.log(BasicLevel.DEBUG, "Calling " + methodName + " on " + this); 97 } 98 if (ep.released) { 99 throw new IllegalStateException ("Endpoint is in a released state and must be reactivated before using"); 100 } 101 if ("equals".equals(methodName)) { 103 Object obj1 = null; 104 if (Proxy.isProxyClass(aobj[0].getClass())) { 105 obj1 = (Object ) Proxy.getInvocationHandler(aobj[0]); 106 } else { 107 obj1 = aobj[0]; 108 } 109 ret = new Boolean (this.equals(obj1)); 110 } else if ("hashCode".equals(methodName)) { 111 ret = new Integer (this.hashCode()); 112 } else if ("toString".equals(methodName)) { 113 ret = this.toString(); 114 } else if ("afterDelivery".equals(methodName)) { 115 if (!b4Delivery) { 116 throw new IllegalStateException (methodName + " called w/o call to beforeDelivery"); 117 } 118 b4Delivery = false; 119 msgCount = 0; 120 rctx = (RequestCtx) requestCtx.get(); 121 try { 122 if (rctx.mustCommit && ep.getXAResource() != null) { 123 rctx.currTx.delistResource(ep.getXAResource(), XAResource.TMSUCCESS); 124 } 125 bf.postInvoke(rctx); 126 } catch (Exception e) { 127 TraceEjb.logger.log(BasicLevel.ERROR, "exception on postInvoke: ", e); 128 throw new RuntimeException (e); 129 } 130 } else if ("beforeDelivery".equals(methodName)) { 131 132 if (TraceEjb.isDebugJms()) { 133 TraceEjb.mdb.log(BasicLevel.DEBUG, "beforeDelivery called"); 134 } 135 if (b4Delivery) { 136 throw new IllegalStateException (methodName + " called w/o call to afterDelivery"); 137 } 138 if (bf.isTxBeanManaged()) { 139 throw new IllegalStateException (methodName + " cannot be called when using bean managed transactions"); 140 } 141 if (tm.getTransaction() != null) { 142 throw new IllegalStateException (methodName + " cannot be called when using an imported transaction"); 143 } 144 msgCount = 0; 145 Object obj1 = null; 147 if (Proxy.isProxyClass(aobj[0].getClass())) { 148 obj1 = (Object ) Proxy.getInvocationHandler(aobj[0]); 149 } else { 150 obj1 = aobj[0]; 151 } 152 Method intentedTargetMethod = (Method ) obj1; 153 String intentedTargetMethodName = intentedTargetMethod.getName(); 154 155 if (TraceEjb.isDebugJms()) { 156 TraceEjb.mdb.log(BasicLevel.DEBUG, "intentedTargetMethodName=" + intentedTargetMethodName); 157 } 158 try { 159 if (TraceEjb.isDebugJms()) { 160 TraceEjb.mdb.log(BasicLevel.DEBUG, "before preInvoke"); 161 } 162 rctx = bf.preInvoke(getTxAttr(intentedTargetMethod)); 163 requestCtx.set(rctx); 168 b4Delivery = true; 169 if (rctx.mustCommit && ep.getXAResource() != null) { 170 171 rctx.currTx.enlistResource(ep.getXAResource()); 172 if (TraceEjb.isDebugJms()) { 173 TraceEjb.mdb.log(BasicLevel.DEBUG, "enlistResource Ok"); 174 } 175 } 176 } catch (Exception e) { 177 TraceEjb.logger.log(BasicLevel.ERROR, "preInvoke failed: ", e); 178 throw new RuntimeException (e); 179 } 180 if (TraceEjb.isDebugJms()) { 181 TraceEjb.mdb.log(BasicLevel.DEBUG, "beforeDelivery ended"); 182 } 183 } else if ("release".equals(methodName)) { 184 bf.releaseEndpoint(ep); 185 } else { 186 msgCount++; 187 188 if (!b4Delivery) { 189 boolean isImportedTx = tm.getTransaction() != null; 190 rctx = bf.preInvoke(getTxAttr(method)); 191 if (rctx.mustCommit) { 195 if (!isImportedTx) { 196 197 if (ep.getXAResource() != null) { 198 rctx.currTx.enlistResource(ep.getXAResource()); 199 } 200 } else { 201 rctx.mustCommit = false; 202 } 203 } 204 bf.checkSecurity(null); 205 } else if (msgCount > 1) { 206 throw new IllegalStateException ("Unable to deliver multiple messages"); 207 } else { 208 rctx = (RequestCtx) requestCtx.get(); 209 } 210 try { 211 if (TraceEjb.isDebugJms()) { 212 TraceEjb.mdb.log(BasicLevel.DEBUG, "Before invoke"); 213 } 214 ret = method.invoke(mdb, aobj); 215 if (TraceEjb.isDebugJms()) { 216 TraceEjb.mdb.log(BasicLevel.DEBUG, "After invoke"); 217 } 218 } catch (InvocationTargetException ite) { 219 Throwable t = ite.getTargetException(); 220 if (t instanceof RuntimeException ) { 221 if (rctx != null) { 222 rctx.sysExc = new EJBException ((RuntimeException ) t); 223 } 224 } else { 225 if (rctx != null) { 226 rctx.sysExc = t; 227 } 228 } 229 invokeEx = rctx.sysExc; 230 TraceEjb.logger.log(BasicLevel.ERROR, "error thrown by an enterprise Bean", t); 231 } catch (Throwable ex) { 232 if (rctx != null) { 234 rctx.sysExc = ex; 235 } 236 invokeEx = ex; 237 238 TraceEjb.logger.log(BasicLevel.ERROR, "error thrown by an enterprise Bean", ex); 239 } finally { 240 if (!b4Delivery) { 241 try { 242 if (!bf.isTxBeanManaged() && rctx.mustCommit && ep.getXAResource() != null) { 243 rctx.currTx.delistResource(ep.getXAResource(), XAResource.TMSUCCESS); 244 } 245 bf.postInvoke(rctx); 246 } catch (Exception e) { 247 TraceEjb.logger.log(BasicLevel.ERROR, "exception on postInvoke: ", e); 248 if (invokeEx == null) { 249 invokeEx = e; 250 } 251 } 252 } else { 253 msgCount = 0; 255 } 256 } 257 } 258 if (invokeEx != null) { 259 TraceEjb.logger.log(BasicLevel.ERROR, "Exception raised: ", invokeEx); 260 throw invokeEx; 261 } 262 if (TraceEjb.isDebugJms()) { 263 TraceEjb.mdb.log(BasicLevel.DEBUG, "ret="+ret); 264 } 265 return ret; 266 } 267 268 private int getTxAttr(Method m) { 269 int ret = MethodDesc.TX_NOT_SUPPORTED; 270 try { 271 ret = bf.isDeliveryTransacted(m) ? MethodDesc.TX_REQUIRED : MethodDesc.TX_NOT_SUPPORTED; 272 } catch (NoSuchMethodException nsme) { 273 } 274 return ret; 275 } 276 } 277 278 | Popular Tags |