/**
 *
 * Copyright 2003-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.geronimo.jetty.interceptor;

import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;

import org.apache.geronimo.transaction.context.TransactionContext;
import org.apache.geronimo.transaction.context.TransactionContextManager;
import org.mortbay.http.HttpRequest;
import org.mortbay.http.HttpResponse;

/**
 * @version $Rev:  $ $Date:  $
 */
public class TransactionContextBeforeAfter implements BeforeAfter {
    
    private final BeforeAfter next;
    private final int oldTxIndex;
    private final int newTxIndex;
    private final TransactionContextManager transactionContextManager;

    public TransactionContextBeforeAfter(BeforeAfter next, int oldTxIndex, int newTxIndex, TransactionContextManager transactionContextManager) {
        this.next = next;
        this.oldTxIndex = oldTxIndex;
        this.newTxIndex = newTxIndex;
        this.transactionContextManager = transactionContextManager;
    }

    public void before(Object[] context, HttpRequest httpRequest, HttpResponse httpResponse) {
        TransactionContext oldTransactionContext = transactionContextManager.getContext();
        TransactionContext newTransactionContext = null;
        if (oldTransactionContext == null || !oldTransactionContext.isInheritable()) {
            newTransactionContext = transactionContextManager.newUnspecifiedTransactionContext();
        }
        context[oldTxIndex] = oldTransactionContext;
        context[newTxIndex] = newTransactionContext;

        if (next != null) {
            next.before(context, httpRequest, httpResponse);
        }
    }

    public void after(Object[] context, HttpRequest httpRequest, HttpResponse httpResponse) {
        if (next != null) {
            next.after(context, httpRequest, httpResponse);
        }
        TransactionContext oldTransactionContext = (TransactionContext) context[oldTxIndex];
        TransactionContext newTransactionContext = (TransactionContext) context[newTxIndex];
        try {
            if (newTransactionContext != null) {
                if (newTransactionContext != transactionContextManager.getContext()) {
                    transactionContextManager.getContext().rollback();
                    newTransactionContext.rollback();
                    throw new RuntimeException("WRONG EXCEPTION! returned from servlet call with wrong tx context");
                }
                newTransactionContext.commit();

            } else {
                if (oldTransactionContext != transactionContextManager.getContext()) {
                    if (transactionContextManager.getContext() != null) {
                        transactionContextManager.getContext().rollback();
                    }
                    throw new RuntimeException("WRONG EXCEPTION! returned from servlet call with wrong tx context");
                }
            }
        } catch (SystemException e) {
            throw new RuntimeException("WRONG EXCEPTION!", e);
        } catch (HeuristicMixedException e) {
            throw new RuntimeException("WRONG EXCEPTION!", e);
        } catch (HeuristicRollbackException e) {
            throw new RuntimeException("WRONG EXCEPTION!", e);
        } catch (RollbackException e) {
            throw new RuntimeException("WRONG EXCEPTION!", e);
        } finally {
            //this is redundant when we enter with an inheritable context and nothing goes wrong.
            transactionContextManager.setContext(oldTransactionContext);
        }
    }

}

@@ -1186,20 +1186,16 @@
 After %7B%0A
-    
 %0A    pri
@@ -2423,32 +2423,50 @@
 httpResponse) %7B%0A
+        try %7B%0A    
         if (next
@@ -2469,32 +2469,36 @@
 next != null) %7B%0A
+    
             next
@@ -2541,34 +2541,62 @@
 ponse);%0A        
+    
 %7D%0A
+        %7D finally %7B%0A    
         Transact
@@ -2672,32 +2672,36 @@
 Index%5D;%0A        
+    
 TransactionConte
@@ -2769,38 +2769,46 @@
 Index%5D;%0A        
+ 
+   
 try %7B%0A
+    
             if (
@@ -2832,32 +2832,36 @@
 text != null) %7B%0A
+    
                 
@@ -2943,32 +2943,36 @@
                 
+    
 transactionConte
@@ -3018,32 +3018,36 @@
                 
+    
 newTransactionCo
@@ -3076,32 +3076,36 @@
                 
+   
+ 
 throw new Runtim
@@ -3193,34 +3193,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -3272,16 +3272,20 @@
         
+  
+  
 %7D else %7B
@@ -3285,16 +3285,20 @@
  else %7B%0A
+    
         
@@ -3392,24 +3392,28 @@
             
+    
 if (transact
@@ -3470,32 +3470,36 @@
                 
+ 
+   
 transactionConte
@@ -3545,34 +3545,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -3688,34 +3688,42 @@
                 
-%7D%0A
+    %7D%0A    
             %7D%0A  
@@ -3720,32 +3720,36 @@
       %7D%0A        
+   
+ 
 %7D catch (SystemE
@@ -3754,32 +3754,36 @@
 mException e) %7B%0A
+    
             thro
@@ -3829,32 +3829,36 @@
 !%22, e);%0A        
+ 
+   
 %7D catch (Heurist
@@ -3883,32 +3883,36 @@
 ) %7B%0A            
+  
+  
 throw new Runtim
@@ -3938,32 +3938,36 @@
 XCEPTION!%22, e);%0A
+    
         %7D catch 
@@ -4003,32 +4003,36 @@
 ) %7B%0A            
+    
 throw new Runtim
@@ -4066,32 +4066,36 @@
 !%22, e);%0A        
+ 
+   
 %7D catch (Rollbac
@@ -4102,32 +4102,36 @@
 kException e) %7B%0A
+    
             thro
@@ -4169,32 +4169,36 @@
 XCEPTION!%22, e);%0A
+    
         %7D finall
@@ -4213,16 +4213,20 @@
         
+    
 //this i
@@ -4307,32 +4307,36 @@
 ng.%0A            
+    
 transactionConte
@@ -4380,16 +4380,30 @@
 ntext);%0A
+            %7D%0A
         

make the tcba more reliable