001: /**********************************************************************
002: Copyright (c) 2007 Erik Bengtson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015: Contributors:
016: 2007 Andy Jefferson - implemented checks to pass JDO TCK
017: 2007 Andy Jefferson - reinstate optimistic exception handling
018: 2007 Andy Jefferson - added setOption methods
019: ...
020: **********************************************************************/package org.jpox.jdo;
021:
022: import javax.jdo.JDOOptimisticVerificationException;
023: import javax.jdo.PersistenceManager;
024: import javax.jdo.Transaction;
025: import javax.transaction.Synchronization;
026:
027: import org.jpox.exceptions.JPOXException;
028: import org.jpox.exceptions.JPOXOptimisticException;
029: import org.jpox.jdo.exceptions.TransactionActiveException;
030: import org.jpox.jdo.exceptions.TransactionCommitingException;
031:
032: /**
033: * Wrapper for the transaction for use by JDO.
034: *
035: * @version $Revision: 1.5 $
036: */
037: public class JDOTransaction implements Transaction {
038: /** The underlying transaction */
039: org.jpox.Transaction tx;
040:
041: /** JDO PersistenceManager. */
042: PersistenceManager pm;
043:
044: /**
045: * Constructor
046: * @param pm The JDO PersistenceManager
047: * @param tx The real transaction
048: */
049: public JDOTransaction(PersistenceManager pm, org.jpox.Transaction tx) {
050: this .tx = tx;
051: this .pm = pm;
052: }
053:
054: /**
055: * Accessor for whether the transaction is active
056: * @return Whether it is active
057: */
058: public boolean isActive() {
059: return tx.isActive();
060: }
061:
062: /**
063: * Method to start the transaction.
064: */
065: public void begin() {
066: tx.begin();
067: }
068:
069: /**
070: * Method to commit the transaction.
071: */
072: public void commit() {
073: try {
074: tx.commit();
075: } catch (JPOXException jpe) {
076: if (jpe.getNestedExceptions() != null) {
077: // TODO What if there is more than 1 exception?
078: if (jpe.getNestedExceptions()[0] instanceof JPOXOptimisticException) {
079: JPOXException ex;
080: if (jpe.getNestedExceptions()[0] instanceof JPOXException) {
081: ex = (JPOXException) jpe.getNestedExceptions()[0];
082: } else {
083: ex = new JPOXException(jpe
084: .getNestedExceptions()[0].getMessage(),
085: jpe.getNestedExceptions()[0]);
086: }
087: // Optimistic exceptions - return a single JDOOptimisticVerificationException
088: // with all individual exceptions nested
089: Throwable[] nested = ex.getNestedExceptions();
090: JDOOptimisticVerificationException[] jdoNested = new JDOOptimisticVerificationException[nested.length];
091: for (int i = 0; i < nested.length; i++) {
092: JPOXException nestedEx;
093: if (nested[i] instanceof JPOXException) {
094: nestedEx = (JPOXException) nested[i];
095: } else {
096: nestedEx = new JPOXException(nested[i]
097: .getMessage(), nested[i]);
098: }
099: jdoNested[i] = (JDOOptimisticVerificationException) JPOXJDOHelper
100: .getJDOExceptionForJPOXException(nestedEx);
101: }
102: throw new JDOOptimisticVerificationException(jpe
103: .getMessage(), jdoNested);
104: } else {
105: JPOXException ex;
106: if (jpe.getNestedExceptions()[0] instanceof JPOXException) {
107: ex = (JPOXException) jpe.getNestedExceptions()[0];
108: } else {
109: ex = new JPOXException(jpe
110: .getNestedExceptions()[0].getMessage(),
111: jpe.getNestedExceptions()[0]);
112: }
113: throw JPOXJDOHelper
114: .getJDOExceptionForJPOXException(ex);
115: }
116: } else {
117: throw JPOXJDOHelper
118: .getJDOExceptionForJPOXException(jpe);
119: }
120: }
121: }
122:
123: /**
124: * Method to rollback the transaction
125: */
126: public void rollback() {
127: try {
128: tx.rollback();
129: } catch (JPOXException jpe) {
130: throw JPOXJDOHelper.getJDOExceptionForJPOXException(jpe);
131: }
132: }
133:
134: /**
135: * Accessor for nontransactionalRead setting
136: * @return The setting for nontransactionalRead
137: */
138: public boolean getNontransactionalRead() {
139: return tx.getNontransactionalRead();
140: }
141:
142: /**
143: * Accessor for nontransactionalWrite setting
144: * @return The setting for nontransactionalWrite
145: */
146: public boolean getNontransactionalWrite() {
147: return tx.getNontransactionalWrite();
148: }
149:
150: /**
151: * Accessor for optimistic setting
152: * @return The setting for optimistic
153: */
154: public boolean getOptimistic() {
155: return tx.getOptimistic();
156: }
157:
158: /**
159: * Accessor for the JDO PersistenceManager
160: * @return The JDO PM
161: */
162: public PersistenceManager getPersistenceManager() {
163: return pm;
164: }
165:
166: /**
167: * Accessor for restoreValues setting
168: * @return The setting for restoreValues
169: */
170: public boolean getRestoreValues() {
171: return tx.getRestoreValues();
172: }
173:
174: /**
175: * Accessor for retainValues setting
176: * @return The setting for retainValues
177: */
178: public boolean getRetainValues() {
179: return tx.getRetainValues();
180: }
181:
182: /**
183: * Accessor for whether to allow rollback only
184: * @return Whether to allow rollback only
185: */
186: public boolean getRollbackOnly() {
187: return tx.getRollbackOnly();
188: }
189:
190: /**
191: * Accessor for the synchronization (if any)
192: * @return The synchronization
193: */
194: public Synchronization getSynchronization() {
195: return tx.getSynchronization();
196: }
197:
198: /**
199: * Mutator for the nontransactionalRead setting
200: * @param flag Whether to allow nontransactional read
201: */
202: public void setNontransactionalRead(boolean flag) {
203: assertNotCommitting();
204: tx.setNontransactionalRead(flag);
205: }
206:
207: /**
208: * Mutator for the nontransactionalWrite setting
209: * @param flag Whether to allow nontransactional write
210: */
211: public void setNontransactionalWrite(boolean flag) {
212: assertNotCommitting();
213: try {
214: tx.setNontransactionalWrite(flag);
215: } catch (JPOXException jpe) {
216: throw JPOXJDOHelper.getJDOExceptionForJPOXException(jpe);
217: }
218: }
219:
220: /**
221: * Mutator for the optimistic setting
222: * @param opt Whether to use optimistic transactions
223: */
224: public void setOptimistic(boolean opt) {
225: assertNotInUse();
226: assertNotCommitting();
227: tx.setOptimistic(opt);
228: }
229:
230: /**
231: * Mutator for the restore values setting
232: * @param restore Whether to restore values
233: */
234: public void setRestoreValues(boolean restore) {
235: assertNotInUse();
236: assertNotCommitting();
237: tx.setRestoreValues(restore);
238: }
239:
240: /**
241: * Mutator for the retain values setting
242: * @param retain Whether to retain values after commit
243: */
244: public void setRetainValues(boolean retain) {
245: assertNotCommitting();
246: tx.setRetainValues(retain);
247: }
248:
249: /**
250: * Mutator for the rollback-only setting
251: */
252: public void setRollbackOnly() {
253: if (tx.isActive()) {
254: // Only apply to active transactions
255: tx.setRollbackOnly();
256: }
257: }
258:
259: /**
260: * Mutator for the Synchronisation
261: * @param synch The Synchronisation
262: */
263: public void setSynchronization(Synchronization synch) {
264: tx.setSynchronization(synch);
265: }
266:
267: /**
268: * Throw an Exception if the underlying transaction is currently committing.
269: */
270: protected void assertNotCommitting() {
271: if (tx.isCommitting()) {
272: throw new TransactionCommitingException(this );
273: }
274: }
275:
276: /**
277: * Asserts that the transaction is not in use.
278: **/
279: protected void assertNotInUse() {
280: if (tx.isActive()) {
281: throw new TransactionActiveException(this );
282: }
283:
284: // TODO How to get the Connection now that it is not in the txn ?
285: /* if (conn != null)
286: {
287: throw new ConnectionInUseException();
288: }*/
289: }
290:
291: /**
292: * Convenience accessor for setting a transaction option.
293: * @param option option name
294: * @param value The value
295: */
296: public void setOption(String option, int value) {
297: tx.setOption(option, value);
298: }
299:
300: /**
301: * Convenience accessor for setting a transaction option.
302: * @param option option name
303: * @param value The value
304: */
305: public void setOption(String option, boolean value) {
306: tx.setOption(option, value);
307: }
308:
309: /**
310: * Convenience accessor for setting a transaction option.
311: * @param option option name
312: * @param value The value
313: */
314: public void setOption(String option, String value) {
315: tx.setOption(option, value);
316: }
317: }
|