JMessageEndpoint.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.resource.spi.endpoint.MessageEndpoint;
00041 import javax.transaction.Status;
00042 import javax.transaction.SystemException;
00043 import javax.transaction.UserTransaction;
00044 import javax.transaction.xa.XAResource;
00045 
00046 import org.objectweb.jonas_ejb.deployment.api.MethodDesc;
00047 
00048 import org.objectweb.security.context.SecurityContext;
00049 import org.objectweb.security.context.SecurityCurrent;
00050 
00051 import org.objectweb.transaction.jta.TransactionManager;
00052 import org.objectweb.util.monolog.api.BasicLevel;
00053 
00061 public class JMessageEndpoint implements MessageDrivenContext {
00062 
00063     protected JMdbEndpointFactory bf = null;
00064 
00065     protected MessageDrivenBean mdb = null;
00066 
00067     protected MessageEndpoint mep = null;
00068 
00069     protected int txattr; // TX_NOT_SUPPORTED, TX_REQUIRED or TX_NOT_SET (= bean
00070                           // managed)
00071 
00072     protected TransactionManager tm = null;
00073 
00074     protected XAResource xar = null;
00075 
00076     protected boolean released = false;
00077 
00078     private static final int MAX_NB_RETRY = 2;
00079 
00085     public JMessageEndpoint(JMdbEndpointFactory bf, MessageDrivenBean mdb) {
00086         this.bf = bf;
00087         this.mdb = mdb;
00088         // keep these locally for efficiency.
00089         txattr = bf.getTransactionAttribute();
00090         tm = bf.getTransactionManager();
00091     }
00092 
00093     public void setProxy(MessageEndpoint mep) {
00094         this.mep = mep;
00095     }
00096 
00097     public XAResource getXAResource() {
00098         return xar;
00099     }
00100 
00101     public void setXAResource(XAResource xa) {
00102         xar = xa;
00103         // Check state of transaction to determine what to do
00104     }
00105 
00106     public boolean getReleasedState() {
00107         return released;
00108     }
00109 
00110     public void setReleasedState(boolean state) {
00111         released = state;
00112     }
00113 
00114     // ------------------------------------------------------------------
00115     // EJBContext implementation
00116     // ------------------------------------------------------------------
00117 
00124     public TimerService getTimerService() throws IllegalStateException {
00125         TraceEjb.interp.log(BasicLevel.DEBUG, "");
00126         return bf.getTimerService();
00127     }
00128 
00129     // ----------------------------------------------------------------------
00130     // javax.ejb.MessageDrivenContext implementation
00131     // ----------------------------------------------------------------------
00132 
00133     private static final String DISALLOWED_MSG = " is disallowed in a message driven bean";
00134 
00140     public Identity getCallerIdentity() {
00141         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00142         throw new IllegalStateException("getCallerIdentity()" + DISALLOWED_MSG);
00143     }
00144 
00149     public Principal getCallerPrincipal() {
00150         boolean inRunAs = false;
00151         if (bf.dd.getRunAsRole() != null) {
00152             inRunAs = true;
00153         }
00154         // Set a security context if there was no one set.
00155         SecurityCurrent current = SecurityCurrent.getCurrent();
00156         if (current != null) {
00157             SecurityContext sctx = current.getSecurityContext();
00158             if (sctx == null) {
00159                 TraceEjb.security.log(BasicLevel.DEBUG, "runas : Security context is null, create a new one");
00160                 sctx = new SecurityContext();
00161                 current.setSecurityContext(sctx);
00162             }
00163         }
00164 
00165         Principal principal =  bf.getContainer().getPrincipalFactory().getCallerPrincipal(inRunAs);
00166         if (principal == null) {
00167             throw new IllegalStateException("No principal exists in security context");
00168         }
00169         return principal;
00170     }
00171 
00177     public boolean isCallerInRole(Identity role) {
00178         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00179         throw new IllegalStateException("isCallerInRole()" + DISALLOWED_MSG);
00180     }
00181 
00187     public boolean isCallerInRole(java.lang.String roleLink) {
00188         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00189         throw new IllegalStateException("isCallerInRole()" + DISALLOWED_MSG);
00190     }
00191 
00198   public void setRollbackOnly() {
00199 
00200     TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00201 
00202     if(bf.isTxBeanManaged())
00203       throw new IllegalStateException("Bean-managed transaction, not use this method.");
00204     try {
00205       tm.setRollbackOnly();
00206     } catch (IllegalStateException e) {
00207       TraceEjb.logger.log(BasicLevel.ERROR, "current thread not associated with transaction");
00208       throw e;
00209     } catch (SystemException e) {
00210       TraceEjb.logger.log(BasicLevel.ERROR, "unexpected exception:", e);
00211     }
00212   }
00213 
00218   public boolean getRollbackOnly() {
00219     TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00220     if(bf.isTxBeanManaged())
00221       throw new IllegalStateException("Bean-managed transaction, not use this method.");
00222     try {
00223       if (tm.getTransaction() != null) {
00224         switch (tm.getStatus()) {
00225         case Status.STATUS_MARKED_ROLLBACK:
00226         case Status.STATUS_ROLLEDBACK:
00227         case Status.STATUS_ROLLING_BACK:
00228           return true;
00229         case Status.STATUS_NO_TRANSACTION:
00230           throw new IllegalStateException("No transaction");
00231         default:
00232           return false;
00233         }
00234       } else {
00235         TraceEjb.logger.log(BasicLevel.ERROR, "the bean is not associated in a transaction");
00236         throw new IllegalStateException("the message driven bean is not associated in a transaction");
00237       }
00238     } catch (SystemException e) {
00239       TraceEjb.logger.log(BasicLevel.ERROR, "cannot get status:", e);
00240       return false;
00241     }
00242   }
00243 
00248     public EJBHome getEJBHome() {
00249         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00250         throw new IllegalStateException("getEJBHome()" + DISALLOWED_MSG);
00251     }
00252 
00257     public EJBLocalHome getEJBLocalHome() {
00258         TraceEjb.logger.log(BasicLevel.ERROR, DISALLOWED_MSG);
00259         throw new IllegalStateException("getEJBLocalHome()" + DISALLOWED_MSG);
00260     }
00261 
00266     public Properties getEnvironment() {
00267         TraceEjb.logger.log(BasicLevel.ERROR, "deprecated use : Use the JNDI naming context java:comp/env");
00268         return new java.util.Properties();
00269     }
00270 
00279     public UserTransaction getUserTransaction() throws IllegalStateException {
00280 
00281         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00282 
00283         if (!bf.isTxBeanManaged()) {
00284             throw new IllegalStateException("This bean is not allowed to use UserTransaction interface");
00285         }
00286         return (UserTransaction) tm;
00287     }
00288 
00289     // -----------------------------------------------------------------------
00290     // other public methods
00291     // -----------------------------------------------------------------------
00292 
00297     public void deliverTimeout(Timer timer) {
00298         TraceEjb.mdb.log(BasicLevel.DEBUG, "");
00299 
00300         boolean committed = false;
00301         for (int nbretry = 0; ! committed && nbretry < MAX_NB_RETRY; nbretry++) {
00302             RequestCtx rctx = null;
00303             try {
00304                 // For MDB, transaction attribute must be required or NotSupported.
00305                 rctx = bf.preInvoke(MethodDesc.TX_REQUIRED);
00306             } catch (Exception e) {
00307                 TraceEjb.logger.log(BasicLevel.ERROR, "preInvoke failed: ", e);
00308                 return;
00309             }
00310             try {
00311                 bf.checkSecurity(null);
00312                 if (mdb instanceof TimedObject) {
00313                     ((TimedObject) mdb).ejbTimeout(timer);
00314                 } else {
00315                     throw new EJBException("The bean does not implement the `TimedObject` interface");
00316                 }
00317                 committed = ! getRollbackOnly();
00318             } catch (EJBException e) {
00319                 rctx.sysExc = e;
00320                 TraceEjb.logger.log(BasicLevel.ERROR, "EJB exception thrown by an enterprise Bean", e);
00321             } catch (RuntimeException e) {
00322                 rctx.sysExc = e;
00323                 TraceEjb.logger.log(BasicLevel.ERROR, "runtime exception thrown by an enterprise Bean", e);
00324             } catch (Error e) {
00325                 rctx.sysExc = e;
00326                 TraceEjb.logger.log(BasicLevel.ERROR, "error thrown by an enterprise Bean", e);
00327                         } finally {
00328                 try {
00329                     bf.postInvoke(rctx);
00330                 } catch (Exception e) {
00331                     TraceEjb.logger.log(BasicLevel.ERROR, "exception on postInvoke: ", e);
00332                 }
00333             }
00334         }
00335     }
00336 }

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