001: /*
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: LocalXAWrapper.java 6661 2005-04-28 08:43:27Z benoitf $
023: * --------------------------------------------------------------------------
024: */
025:
026: package org.objectweb.jonas.resource;
027:
028: import javax.resource.ResourceException;
029: import javax.resource.spi.LocalTransaction;
030:
031: import javax.transaction.xa.XAResource;
032: import javax.transaction.xa.XAException;
033: import javax.transaction.xa.Xid;
034:
035: import org.objectweb.util.monolog.api.Logger;
036: import org.objectweb.util.monolog.api.BasicLevel;
037:
038: /**
039: * A LocalXAWrapper that intercepts the XA calls for an RAR that only
040: * supports LocalTransactions and translates them to the appropriate
041: * Local Transaction methods.
042: *
043: * @author Eric.Hardesty@bull.com
044: */
045: public final class LocalXAWrapper implements XAResource {
046:
047: /**
048: * The Logger instance where messages are written.
049: */
050: private static Logger logger = null;
051:
052: /**
053: * The boolean to determine if in a current transaction
054: */
055: protected boolean isInTransaction;
056:
057: /**
058: * The LocalTransaction object to make the begin(), commit(),
059: * and rollback() calls.
060: */
061: protected LocalTransaction localTrans = null;
062:
063: LocalXAWrapper(LocalTransaction _localTrans, Logger _logger) {
064: isInTransaction = false;
065: localTrans = _localTrans;
066: logger = _logger;
067: }
068:
069: /**
070: * Commit the localTransaction, the params aren't used for a
071: * local transaction.
072: *
073: *@param xid transaction xid
074: *@param flag for interface compliance
075: *@exception XAException Exception trying to commit local transaction
076: */
077: public void commit(Xid xid, boolean flag) throws XAException {
078: if (logger.isLoggable(BasicLevel.DEBUG)) {
079: logger
080: .log(BasicLevel.DEBUG, "Xid =" + xid + "flag="
081: + flag);
082: }
083:
084: if (isInTransaction) {
085: // Unbalance start/end. Probably a close is missing.
086: // We decide to unset isInTransaction here to avoid a further error
087: if (logger.isLoggable(BasicLevel.DEBUG)) {
088: logger.log(BasicLevel.DEBUG, "XA START without XA END");
089: }
090: isInTransaction = false;
091: }
092:
093: try {
094: localTrans.commit();
095: } catch (ResourceException res) {
096: XAException xaE = new XAException(res.getMessage());
097: xaE.initCause(res);
098: throw xaE;
099: }
100: }
101:
102: /**
103: * No method to map for a local transaction.
104: *@param xid transaction xid
105: */
106: public void end(Xid xid, int i) throws XAException {
107: if (logger.isLoggable(BasicLevel.DEBUG)) {
108: logger.log(BasicLevel.DEBUG, "Xid =" + xid + "i=" + i);
109: }
110: if (!isInTransaction) {
111: logger.log(BasicLevel.ERROR, "END without START");
112: XAException ex = new XAException(XAException.XA_RBPROTO);
113: throw (ex);
114: }
115: isInTransaction = false;
116:
117: }
118:
119: /**
120: * No method to map for a local transaction.
121: *@param xid transaction xid
122: */
123: public void forget(Xid xid) throws XAException {
124: if (logger.isLoggable(BasicLevel.DEBUG)) {
125: logger.log(BasicLevel.DEBUG, "");
126: }
127: }
128:
129: /**
130: * No method to map for a local transaction, just
131: * return no timeout.
132: */
133: public int getTransactionTimeout() throws XAException {
134: if (logger.isLoggable(BasicLevel.DEBUG)) {
135: logger.log(BasicLevel.DEBUG, "");
136: }
137: return -1;
138: }
139:
140: /**
141: * Determine if the wrapper instance is the same as the
142: * wrapper instance being passed in
143: * @param xaresource An XAResource object
144: * @return True if same RM instance, otherwise false.
145: * @throws XAException no throw in this implementation
146: */
147:
148: public boolean isSameRM(XAResource xaresource) throws XAException {
149: if (logger.isLoggable(BasicLevel.DEBUG)) {
150: logger.log(BasicLevel.DEBUG, "");
151: }
152:
153: if (xaresource.equals(this )) {
154: if (logger.isLoggable(BasicLevel.DEBUG)) {
155: logger.log(BasicLevel.DEBUG, "isSameRM = true " + this );
156: }
157: return true;
158: }
159: if (logger.isLoggable(BasicLevel.DEBUG)) {
160: logger.log(BasicLevel.DEBUG, "isSameRM = false " + this );
161: }
162: return false;
163: }
164:
165: /**
166: * No method to map for a local transaction, just return XA_OK.
167: *@param xid transaction xid
168: */
169: public int prepare(Xid xid) throws XAException {
170: if (logger.isLoggable(BasicLevel.DEBUG)) {
171: logger.log(BasicLevel.DEBUG, "");
172: }
173: return XAResource.XA_OK;
174: }
175:
176: /**
177: * No method to map for a local transaction.
178: */
179: public Xid[] recover(int i) throws XAException {
180: if (logger.isLoggable(BasicLevel.DEBUG)) {
181: logger.log(BasicLevel.DEBUG, "");
182: }
183: return null;
184: }
185:
186: /**
187: * Rollback the localTransaction, the param isn't used for a
188: * local transaction.
189: *@param xid transaction xid
190: *
191: *@exception XAException Exception trying to rollback local transaction
192: */
193: public void rollback(Xid xid) throws XAException {
194: if (logger.isLoggable(BasicLevel.DEBUG)) {
195: logger.log(BasicLevel.DEBUG, "Xid =" + xid);
196: }
197:
198: if (isInTransaction) {
199: // Unbalance start/end. Probably a close is missing.
200: // We decide to unset isInTransaction here to avoid a further error, but
201: // I'm not sure it's a good idea.
202: if (logger.isLoggable(BasicLevel.DEBUG)) {
203: logger.log(BasicLevel.DEBUG, "XA START without XA END");
204: }
205: isInTransaction = false;
206: }
207:
208: try {
209: localTrans.rollback();
210: } catch (ResourceException res) {
211: XAException xaE = new XAException("Rollback failed");
212: xaE.initCause(res);
213: throw xaE;
214: }
215: }
216:
217: /**
218: * No method to map for a local transaction, just
219: * return no timeout.
220: */
221: public boolean setTransactionTimeout(int i) throws XAException {
222: if (logger.isLoggable(BasicLevel.DEBUG)) {
223: logger.log(BasicLevel.DEBUG, "");
224: }
225: return false;
226: }
227:
228: /**
229: * Only start a local transaction if a new transaction is being
230: * attempted, just return if joining or resuming.
231: *
232: *@param xid transaction xid
233: *@exception XAException Transaction already started or error
234: * starting a new local transaction
235: */
236: public void start(Xid xid, int i) throws XAException {
237: if (logger.isLoggable(BasicLevel.DEBUG)) {
238: logger.log(BasicLevel.DEBUG, "Xid =" + xid + "i=" + i);
239: }
240: try {
241: if (i != XAResource.TMJOIN && i != XAResource.TMRESUME) {
242: if (isInTransaction) {
243: throw new XAException(
244: "LocalXAWrapper.start: Local transaction already started");
245: }
246: localTrans.begin();
247: isInTransaction = true;
248: }
249: } catch (ResourceException res) {
250: XAException xaE = new XAException(
251: "LocalTransaction.begin failed");
252: xaE.initCause(res);
253: throw xaE;
254: }
255:
256: if (logger.isLoggable(BasicLevel.DEBUG)) {
257: logger.log(BasicLevel.DEBUG, "OK");
258: }
259: }
260: }
|