JMessageDrivenBean.java

00001 
00026 package org.objectweb.jonas_ejb.container;
00027 
00028 import java.security.Identity;
00029 import java.security.Principal;
00030 import java.util.Properties;
00031 
00032 import javax.ejb.EJBException;
00033 import javax.ejb.EJBHome;
00034 import javax.ejb.EJBLocalHome;
00035 import javax.ejb.MessageDrivenBean;
00036 import javax.ejb.MessageDrivenContext;
00037 import javax.ejb.TimedObject;
00038 import javax.ejb.Timer;
00039 import javax.ejb.TimerService;
00040 import javax.jms.JMSException;
00041 import javax.jms.Message;
00042 import javax.jms.MessageListener;
00043 import javax.jms.ServerSession;
00044 import javax.jms.Session;
00045 import javax.jms.XASession;
00046 import javax.transaction.Status;
00047 import javax.transaction.SystemException;
00048 import javax.transaction.UserTransaction;
00049 import javax.transaction.xa.XAResource;
00050 
00051 import org.objectweb.jonas_ejb.deployment.api.MethodDesc;
00052 
00053 import org.objectweb.transaction.jta.TransactionManager;
00054 import org.objectweb.util.monolog.api.BasicLevel;
00055 
00065 public class JMessageDrivenBean implements MessageListener, ServerSession, Runnable, MessageDrivenContext {
00066 
00067     protected Session sess = null;
00068 
00069     protected JMdbFactory bf = null;
00070 
00071     protected MessageDrivenBean mdb = null;
00072 
00077     protected int txattr;
00078 
00083     protected int timerTxAttr;
00084 
00085     protected TransactionManager tm = null;
00086 
00087     protected ThreadPool thpool = null;
00088 
00096     public JMessageDrivenBean(JMdbFactory bf, Session sess, MessageDrivenBean mdb, ThreadPool thpool) {
00097         this.bf = bf;
00098         this.sess = sess;
00099         this.mdb = mdb;
00100         this.thpool = thpool;
00101         // keep these locally for efficiency.
00102         txattr = bf.getTransactionAttribute();
00103         timerTxAttr = bf.getTimerTxAttribute();
00104         tm = bf.getTransactionManager();
00105     }
00106 
00107     // ------------------------------------------------------------------
00108     // EJBContext implementation
00109     // ------------------------------------------------------------------
00110 
00117     public TimerService getTimerService() throws IllegalStateException {
00118         TraceEjb.interp.log(BasicLevel.DEBUG, "");
00119         return bf.getTimerService();
00120     }
00121 
00122     // ----------------------------------------------------------------------
00123     // javax.jms.MessageListener implementation
00124     // ----------------------------------------------------------------------
00125 
00132     public synchronized void onMessage(Message message) {
00133         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00134 
00135         RequestCtx rctx = null;
00136         try {
00137 
00138             if (tm.getTransaction() != null) {
00139                 // This should not occur (DEBUG)
00140                 TraceEjb.logger.log(BasicLevel.ERROR, "Transaction already OPENED");
00141                 TraceEjb.logger.log(BasicLevel.ERROR, "Transaction = " + tm.getTransaction());
00142                 Thread.dumpStack();
00143                 return;
00144             }
00145 
00146             rctx = bf.preInvoke(txattr);
00147             bf.checkSecurity(null);
00148             if (rctx.mustCommit) {
00149                 TraceEjb.tx.log(BasicLevel.DEBUG, "enlistResource");
00150                 rctx.currTx.enlistResource(((XASession) sess).getXAResource());
00151             }
00152         } catch (Exception e) {
00153             TraceEjb.logger.log(BasicLevel.ERROR, "preInvoke failed: ", e);
00154             return;
00155         }
00156         try {
00157             TraceEjb.mdb.log(BasicLevel.DEBUG, "Call MDB");
00158             ((MessageListener) mdb).onMessage(message);
00159             TraceEjb.mdb.log(BasicLevel.DEBUG, "Return from MDB");
00160         } catch (RuntimeException e) {
00161             rctx.sysExc = e;
00162             TraceEjb.logger.log(BasicLevel.ERROR, "runtime exception thrown by an enterprise Bean", e);
00163         } catch (Error e) {
00164             rctx.sysExc = e;
00165             TraceEjb.logger.log(BasicLevel.ERROR, "error thrown by an enterprise Bean", e);
00166         } finally {
00167             try {
00168                 if (rctx.mustCommit) {
00169                     TraceEjb.tx.log(BasicLevel.DEBUG, "delistResource");
00170                     rctx.currTx.delistResource(((XASession) sess).getXAResource(), XAResource.TMSUCCESS);
00171                 }
00172                 bf.postInvoke(rctx);
00173             } catch (Exception e) {
00174                 TraceEjb.logger.log(BasicLevel.ERROR, "exception on postInvoke: ", e);
00175             }
00176         }
00177     }
00178 
00179     // ----------------------------------------------------------------------
00180     // javax.jms.ServerSession implementation
00181     // ----------------------------------------------------------------------
00182 
00192     public Session getSession() throws JMSException {
00193         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00194         return sess;
00195     }
00196 
00203     public void start() throws JMSException {
00204         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00205         thpool.addRunnable(this);
00206     }
00207 
00208     // ----------------------------------------------------------------------
00209     // Runnable implementation
00210     // ----------------------------------------------------------------------
00211 
00216     public void run() {
00217         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00218 
00219         // this thread must have the classloader of this container to
00220         // be able to retrieve beans called from a MDB.
00221         Thread.currentThread().setContextClassLoader(bf.myClassLoader());
00222 
00223         sess.run();
00224         bf.releaseServerSession(this);
00225     }
00226 
00227     // ----------------------------------------------------------------------
00228     // javax.ejb.MessageDrivenContext implementation
00229     // ----------------------------------------------------------------------
00230 
00231     private static final String DISALLOWED_MSG = " is disallowed in a message driven bean";
00232 
00238     public Identity getCallerIdentity() {
00239         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00240         throw new IllegalStateException("getCallerIdentity()" + DISALLOWED_MSG);
00241     }
00242 
00249     public Principal getCallerPrincipal() {
00250         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00251         throw new IllegalStateException("getCallerPrincipal()" + DISALLOWED_MSG);
00252     }
00253 
00259     public boolean isCallerInRole(Identity role) {
00260         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00261         throw new IllegalStateException("isCallerInRole()" + DISALLOWED_MSG);
00262     }
00263 
00269     public boolean isCallerInRole(java.lang.String roleLink) {
00270         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00271         throw new IllegalStateException("isCallerInRole()" + DISALLOWED_MSG);
00272     }
00273 
00280     public void setRollbackOnly() {
00281 
00282         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00283         try {
00284             tm.setRollbackOnly();
00285         } catch (IllegalStateException e) {
00286             TraceEjb.logger.log(BasicLevel.ERROR, "current thread not associated with transaction");
00287             throw e;
00288         } catch (SystemException e) {
00289             TraceEjb.logger.log(BasicLevel.ERROR, "unexpected exception:", e);
00290         }
00291     }
00292 
00297     public boolean getRollbackOnly() {
00298         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00299 
00300         try {
00301             if (tm.getTransaction() != null) {
00302                 switch (tm.getStatus()) {
00303                 case Status.STATUS_MARKED_ROLLBACK:
00304                 case Status.STATUS_ROLLEDBACK:
00305                 case Status.STATUS_ROLLING_BACK:
00306                     return true;
00307                 case Status.STATUS_NO_TRANSACTION:
00308                     throw new IllegalStateException("No transaction");
00309                 default:
00310                     return false;
00311                 }
00312             } else {
00313                 TraceEjb.logger.log(BasicLevel.ERROR, "the bean is not associated in a transaction");
00314                 throw new IllegalStateException("the message driven bean is not associated in a transaction");
00315             }
00316         } catch (SystemException e) {
00317             TraceEjb.logger.log(BasicLevel.ERROR, "cannot get status:", e);
00318             return false;
00319         }
00320     }
00321 
00326     public EJBHome getEJBHome() {
00327         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00328         throw new IllegalStateException("getEJBHome()" + DISALLOWED_MSG);
00329     }
00330 
00335     public EJBLocalHome getEJBLocalHome() {
00336         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00337         throw new IllegalStateException("getEJBLocalHome()" + DISALLOWED_MSG);
00338     }
00339 
00344     public Properties getEnvironment() {
00345         TraceEjb.logger.log(BasicLevel.ERROR, "deprecated use : Use the JNDI naming context java:comp/env");
00346         return new java.util.Properties();
00347     }
00348 
00357     public UserTransaction getUserTransaction() throws IllegalStateException {
00358 
00359         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00360 
00361         if (!bf.isTxBeanManaged()) {
00362             throw new IllegalStateException("This bean is not allowed to use UserTransaction interface");
00363         }
00364         return (UserTransaction) tm;
00365     }
00366 
00367     // -----------------------------------------------------------------------
00368     // other public methods
00369     // -----------------------------------------------------------------------
00370 
00375     public void deliverTimeout(Timer timer) {
00376         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00377 
00378         RequestCtx rctx = null;
00379         try {
00380             rctx = bf.preInvoke(timerTxAttr);
00381         } catch (Exception e) {
00382             TraceEjb.logger.log(BasicLevel.ERROR, "preInvoke failed: ", e);
00383             return;
00384         }
00385         try {
00386             bf.checkSecurity(null);
00387             if (mdb instanceof TimedObject) {
00388                 ((TimedObject) mdb).ejbTimeout(timer);
00389             } else {
00390                 throw new EJBException("The bean does not implement the `TimedObject` interface");
00391             }
00392         } catch (EJBException e) {
00393             rctx.sysExc = e;
00394             TraceEjb.logger.log(BasicLevel.ERROR, "EJB exception thrown by an enterprise Bean", e);
00395         } catch (RuntimeException e) {
00396             rctx.sysExc = e;
00397             TraceEjb.logger.log(BasicLevel.ERROR, "runtime exception thrown by an enterprise Bean", e);
00398         } catch (Error e) {
00399             rctx.sysExc = e;
00400             TraceEjb.logger.log(BasicLevel.ERROR, "error thrown by an enterprise Bean", e);
00401         } finally {
00402             try {
00403                 bf.postInvoke(rctx);
00404             } catch (Exception e) {
00405                 TraceEjb.logger.log(BasicLevel.ERROR, "exception on postInvoke: ", e);
00406             }
00407         }
00408     }
00409 }

Generated on Tue Feb 15 15:05:38 2005 for JOnAS by  doxygen 1.3.9.1