Save This Page
Home » openejb-3.1.2-src » org.apache.openejb.spring » [javadoc | source]
    1   /**
    2    *
    3    * Licensed to the Apache Software Foundation (ASF) under one or more
    4    * contributor license agreements.  See the NOTICE file distributed with
    5    * this work for additional information regarding copyright ownership.
    6    * The ASF licenses this file to You under the Apache License, Version 2.0
    7    * (the "License"); you may not use this file except in compliance with
    8    * the License.  You may obtain a copy of the License at
    9    *
   10    *     http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    *  Unless required by applicable law or agreed to in writing, software
   13    *  distributed under the License is distributed on an "AS IS" BASIS,
   14    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15    *  See the License for the specific language governing permissions and
   16    *  limitations under the License.
   17    */
   18   package org.apache.openejb.spring;
   19   
   20   import javax.transaction.HeuristicMixedException;
   21   import javax.transaction.HeuristicRollbackException;
   22   import javax.transaction.NotSupportedException;
   23   import javax.transaction.RollbackException;
   24   import javax.transaction.UserTransaction;
   25   import static javax.transaction.Status.STATUS_NO_TRANSACTION;
   26   import static javax.transaction.Status.STATUS_MARKED_ROLLBACK;
   27   import static javax.transaction.Status.STATUS_ACTIVE;
   28   
   29   import org.apache.openejb.SystemException;
   30   import org.apache.openejb.core.transaction.BeanTransactionPolicy;
   31   import org.apache.openejb.core.transaction.TransactionType;
   32   import org.springframework.transaction.HeuristicCompletionException;
   33   import org.springframework.transaction.NestedTransactionNotSupportedException;
   34   import org.springframework.transaction.PlatformTransactionManager;
   35   import org.springframework.transaction.TransactionException;
   36   import org.springframework.transaction.TransactionStatus;
   37   import org.springframework.transaction.UnexpectedRollbackException;
   38   import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRES_NEW;
   39   import org.springframework.transaction.support.DefaultTransactionDefinition;
   40   import org.springframework.transaction.support.DefaultTransactionStatus;
   41   
   42   public class SpringBeanTransactionPolicy extends SpringTransactionPolicy implements BeanTransactionPolicy {
   43       private final UserTransaction userTransaction;
   44       private DefaultTransactionStatus beanTransaction;
   45       private int timeout;
   46   
   47       public SpringBeanTransactionPolicy(PlatformTransactionManager transactionManager) {
   48           super(transactionManager, TransactionType.BeanManaged);
   49           userTransaction = new SpringUserTransaction();
   50       }
   51   
   52       protected DefaultTransactionStatus getTransactionStatus() {
   53           return beanTransaction != null ? beanTransaction : super.getTransactionStatus();
   54       }
   55   
   56       public SuspendedTransaction suspendUserTransaction() throws SystemException {
   57           throw new SystemException(new UnsupportedOperationException("SpringTransactionPolicy does not support transaction suspension"));
   58       }
   59   
   60       public void resumeUserTransaction(SuspendedTransaction suspendedTransaction) throws SystemException {
   61           throw new SystemException(new UnsupportedOperationException("SpringTransactionPolicy does not support transaction resumption"));
   62       }
   63   
   64       public UserTransaction getUserTransaction() {
   65           if (getTransactionStatus().isCompleted()) {
   66               throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
   67           }
   68           return userTransaction;
   69       }
   70   
   71       private class SpringUserTransaction implements UserTransaction {
   72           public int getStatus() {
   73               if (getTransactionStatus().isCompleted() || beanTransaction == null) {
   74                   return STATUS_NO_TRANSACTION;
   75               } else if (isRollbackOnly()) {
   76                   return STATUS_MARKED_ROLLBACK;
   77               } else {
   78                   return STATUS_ACTIVE;
   79               }
   80           }
   81   
   82           public void begin() throws NotSupportedException, javax.transaction.SystemException {
   83               if (getTransactionStatus().isCompleted()) {
   84                   throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
   85               }
   86   
   87               if (beanTransaction != null) {
   88                   // we could support nested transactions
   89                   throw new NotSupportedException("Current thread is already associated with a transaction");
   90               }
   91   
   92               try {
   93                   // create transaction definition
   94                   DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
   95                   definition.setPropagationBehavior(PROPAGATION_REQUIRES_NEW);
   96                   if (timeout > 0) {
   97                       definition.setTimeout(timeout);
   98                   }
   99   
  100                   // start the transaction
  101                   TransactionStatus transactionStatus = transactionManager.getTransaction(definition);
  102   
  103                   // TransactionStatus must be a DefaultTransactionStatus so we can implement isTransactionActive()
  104                   if (!(transactionManager instanceof DefaultTransactionStatus)) {
  105                       transactionManager.rollback(transactionStatus);
  106                       throw new IllegalArgumentException("SpringBeanTransactionPolicy only works with a PlatformTransactionManager that uses DefaultTransactionStatus");
  107                   }
  108                   beanTransaction = (DefaultTransactionStatus) transactionStatus;
  109               } catch (TransactionException e) {
  110                   // check if exception is simply wrapping a JTA exception
  111                   Throwable cause = e.getCause();
  112                   if (cause instanceof NotSupportedException) {
  113                       throw (NotSupportedException) cause;
  114                   } else if (cause instanceof javax.transaction.SystemException) {
  115                       throw (javax.transaction.SystemException) cause;
  116                   }
  117   
  118                   // convert to JTA exception
  119                   if (e instanceof NestedTransactionNotSupportedException) {
  120                       throw createJtaException(NotSupportedException.class, e);
  121                   }
  122                   throw createJtaException(javax.transaction.SystemException.class, e);
  123               }
  124           }
  125   
  126           public void commit() throws HeuristicMixedException, HeuristicRollbackException, IllegalStateException, RollbackException, SecurityException, javax.transaction.SystemException {
  127               if (getTransactionStatus().isCompleted()) {
  128                   throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
  129               }
  130   
  131               if (beanTransaction == null) {
  132                   throw new IllegalStateException("Current thread is not associated with a transaction");
  133               }
  134   
  135               try {
  136                   transactionManager.commit(beanTransaction);
  137               } catch (TransactionException e) {
  138                   // check if exception is simply wrapping a JTA exception
  139                   Throwable cause = e.getCause();
  140                   if (cause instanceof HeuristicMixedException) {
  141                       throw (HeuristicMixedException) cause;
  142                   } else if (cause instanceof HeuristicRollbackException) {
  143                       throw (HeuristicRollbackException) cause;
  144                   } else if (cause instanceof IllegalStateException) {
  145                       throw (IllegalStateException) cause;
  146                   } else if (cause instanceof RollbackException) {
  147                       throw (RollbackException) cause;
  148                   } else if (cause instanceof SecurityException) {
  149                       throw (SecurityException) cause;
  150                   } else if (cause instanceof javax.transaction.SystemException) {
  151                       throw (javax.transaction.SystemException) cause;
  152                   }
  153   
  154                   // convert to JTA exception
  155                   if (e instanceof HeuristicCompletionException) {
  156                       HeuristicCompletionException heuristicCompletionException = (HeuristicCompletionException) e;
  157                       if (heuristicCompletionException.getOutcomeState() == HeuristicCompletionException.STATE_MIXED) {
  158                           throw createJtaException(HeuristicMixedException.class, e);
  159                       } else if (heuristicCompletionException.getOutcomeState() == HeuristicCompletionException.STATE_ROLLED_BACK) {
  160                           throw createJtaException(HeuristicRollbackException.class, e);
  161                       }
  162                   } else if (e instanceof UnexpectedRollbackException) {
  163                       throw createJtaException(RollbackException.class, e);
  164                   }
  165                   throw createJtaException(javax.transaction.SystemException.class, e);
  166               }
  167           }
  168   
  169           public void rollback() throws IllegalStateException, javax.transaction.SystemException {
  170               if (getTransactionStatus().isCompleted()) {
  171                   throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
  172               }
  173   
  174               if (beanTransaction == null) {
  175                   throw new IllegalStateException("Current thread is not associated with a transaction");
  176               }
  177   
  178               try {
  179                   transactionManager.rollback(beanTransaction);
  180               } catch (TransactionException e) {
  181                   // check if exception is simply wrapping a JTA exception
  182                   Throwable cause = e.getCause();
  183                   if (cause instanceof IllegalStateException) {
  184                       throw (IllegalStateException) cause;
  185                   } else if (cause instanceof SecurityException) {
  186                       throw (SecurityException) cause;
  187                   } else if (cause instanceof javax.transaction.SystemException) {
  188                       throw (javax.transaction.SystemException) cause;
  189                   }
  190   
  191                   // convert to JTA exception
  192                   throw createJtaException(javax.transaction.SystemException.class, e);
  193               }
  194           }
  195   
  196           public void setRollbackOnly() throws IllegalStateException, javax.transaction.SystemException {
  197               if (getTransactionStatus().isCompleted()) {
  198                   throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
  199               }
  200   
  201               if (beanTransaction == null) {
  202                   throw new IllegalStateException("Current thread is not associated with a transaction");
  203               }
  204   
  205               try {
  206                   beanTransaction.setRollbackOnly();
  207               } catch (Exception e) {
  208                   // check if exception is simply wrapping a JTA exception
  209                   Throwable cause = e.getCause();
  210                   if (cause instanceof IllegalStateException) {
  211                       throw (IllegalStateException) cause;
  212                   } else if (cause instanceof javax.transaction.SystemException) {
  213                       throw (javax.transaction.SystemException) cause;
  214                   }
  215   
  216                   // convert to JTA exception
  217                   throw createJtaException(javax.transaction.SystemException.class, e);
  218               }
  219           }
  220   
  221           public void setTransactionTimeout(int timeout) throws javax.transaction.SystemException {
  222               if (getTransactionStatus().isCompleted()) {
  223                   throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
  224               }
  225   
  226               if (timeout < 0) {
  227                   throw new javax.transaction.SystemException("timeout is negative");
  228               }
  229               SpringBeanTransactionPolicy.this.timeout = timeout;
  230           }
  231   
  232           private <T extends Exception> T createJtaException(Class<T> type, Throwable cause) throws javax.transaction.SystemException {
  233               T exception;
  234               try {
  235                   exception = type.getConstructor(String.class).newInstance("Spring PlatformTransactionManager threw an exception");
  236               } catch (Exception e) {
  237                   javax.transaction.SystemException systemException = new javax.transaction.SystemException("Spring PlatformTransactionManager threw an exception");
  238                   systemException.initCause(cause);
  239                   throw systemException;
  240               }
  241               exception.initCause(cause);
  242               return exception;
  243           }
  244       }
  245   }

Save This Page
Home » openejb-3.1.2-src » org.apache.openejb.spring » [javadoc | source]