(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(
69                 "Rollback while not in a transaction");
70         }
71         try {
72             for (int i = 0; i < resources.length; i++) {
73                 resources[i].rollback(txStates[i]);
74             }
75         } finally {
76             status = Status.STATUS_NO_TRANSACTION;
77             callback.transactionFinished();
78         }
79     }
80
81     @Override
82     public void commit() throws RollbackException, HeuristicMixedException,
83         HeuristicRollbackException, SecurityException, IllegalStateException,
84         SystemException {
85         if (status == Status.STATUS_MARKED_ROLLBACK) {
86             rollback();
87             throw new RollbackException();
88         }
89         if (status != Status.STATUS_ACTIVE) {
90             throw new IllegalStateException("Commit while not in a transaction");
91         }
92         try {
93             boolean committing = true;
94             for (int i = 0; i < resources.length; i++) {
95                 try {
96                     if (committing) {
97                         resources[i].commit(txStates[i]);
98                     } else {
99                         resources[i].rollback(txStates[i]);
100                     }
101                 } catch (Exception e) {
102                     committing = false;
103                 }
104             }
105
106             if (!committing) {
107                 throw new HeuristicMixedException("Commit failed");
108             }
109         } finally {
110             status = Status.STATUS_NO_TRANSACTION;
111             callback.transactionFinished();
112         }
113     }
114
115     @Override
116     public int getStatus() throws SystemException {
117         return status;
118     }
119
120     @Override
121     public void setRollbackOnly() throws IllegalStateException, SystemException {
122         if (status == Status.STATUS_NO_TRANSACTION) {
123             throw new IllegalStateException(
124                 "setRollbackOnly() while not in a transaction");
125         }
126         status = Status.STATUS_MARKED_ROLLBACK;
127     }
128
129     @Override
130     public void setTransactionTimeout(int aSeconds) throws SystemException {
131         // Ignored.
132     }
133 }