(no commit message)
[utils] / test / enterprise / src / main / java / org / wamblee / test / transactions / SimpleUserTransaction.java
1 /*
2  * Copyright 2005-2010 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.wamblee.test.transactions;
17
18 import javax.transaction.HeuristicMixedException;
19 import javax.transaction.HeuristicRollbackException;
20 import javax.transaction.NotSupportedException;
21 import javax.transaction.RollbackException;
22 import javax.transaction.Status;
23 import javax.transaction.SystemException;
24 import javax.transaction.UserTransaction;
25
26 /**
27  * Represents a user transaction spanning a number of resources.
28  */
29 public class SimpleUserTransaction implements UserTransaction {
30
31     private UserTransactionCallback callback;
32     private TransactionResource[] resources;
33     private Object[] txStates;
34     private int status;
35
36     /**
37      * Constructs the transaction.
38      * 
39      * @param aCallback
40      *            Callback to use.
41      * @param aResources
42      *            Resources to use.
43      */
44     public SimpleUserTransaction(UserTransactionCallback aCallback,
45         TransactionResource<?>... aResources) {
46         callback = aCallback;
47         resources = aResources;
48         txStates = new Object[resources.length];
49         status = Status.STATUS_NO_TRANSACTION;
50     }
51
52     @Override
53     public void begin() throws NotSupportedException, SystemException {
54         if (status == Status.STATUS_ACTIVE) {
55             throw new NotSupportedException(
56                 "Nested transactions not supported!");
57         }
58         for (int i = 0; i < resources.length; i++) {
59             txStates[i] = resources[i].begin();
60         }
61         status = Status.STATUS_ACTIVE;
62     }
63
64     @Override
65     public void rollback() throws IllegalStateException, SecurityException,
66         SystemException {
67         if ( status == Status.STATUS_NO_TRANSACTION) { 
68             throw new IllegalStateException("Rollback while not in a transaction");
69         }
70         try {
71             for (int i = 0; i < resources.length; i++) {
72                 resources[i].rollback(txStates[i]);
73             }
74         } finally {
75             status = Status.STATUS_NO_TRANSACTION;
76             callback.transactionFinished();
77         }
78     }
79
80     @Override
81     public void commit() throws RollbackException, HeuristicMixedException,
82         HeuristicRollbackException, SecurityException, IllegalStateException,
83         SystemException {
84         if (status == Status.STATUS_MARKED_ROLLBACK) {
85             rollback();
86             throw new RollbackException();
87         }
88         if (status != Status.STATUS_ACTIVE) {
89             throw new IllegalStateException("Commit while not in a transaction");
90         }
91         try {
92             boolean committing = true;
93             for (int i = 0; i < resources.length; i++) {
94                 try {
95                     if (committing) {
96                         resources[i].commit(txStates[i]);
97                     } else {
98                         resources[i].rollback(txStates[i]);
99                     }
100                 } catch (Exception e) {
101                     committing = false; 
102                 }
103             }
104             
105             if (!committing) { 
106                 throw new HeuristicMixedException("Commit failed");
107             }
108         } finally {
109             status = Status.STATUS_NO_TRANSACTION;
110             callback.transactionFinished();
111         }
112     }
113
114     @Override
115     public int getStatus() throws SystemException {
116         return status;
117     }
118
119     @Override
120     public void setRollbackOnly() throws IllegalStateException, SystemException {
121         if ( status == Status.STATUS_NO_TRANSACTION) { 
122             throw new IllegalStateException("setRollbackOnly() while not in a transaction");
123         }
124         status = Status.STATUS_MARKED_ROLLBACK;
125     }
126
127     @Override
128     public void setTransactionTimeout(int aSeconds) throws SystemException {
129         // Ignored.
130     }
131 }