001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.entity.transaction;
019:
020: import org.ofbiz.base.util.Debug;
021:
022: import javax.transaction.xa.XAResource;
023: import javax.transaction.xa.Xid;
024: import javax.transaction.xa.XAException;
025: import javax.transaction.*;
026:
027: /**
028: * GenericXaResource - Abstract XA Resource implementation supporting a single transaction
029: */
030: public abstract class GenericXaResource implements XAResource {
031:
032: public static final String module = GenericXaResource.class
033: .getName();
034:
035: protected boolean active = false;
036: protected int timeout = 0;
037: protected Xid xid = null;
038:
039: /**
040: * Enlists this resource in the current transaction
041: * @throws XAException
042: */
043: public void enlist() throws XAException {
044: TransactionManager tm = TransactionFactory
045: .getTransactionManager();
046: try {
047: if (tm != null && tm.getStatus() == Status.STATUS_ACTIVE) {
048: Transaction tx = tm.getTransaction();
049: if (tx != null) {
050: tx.enlistResource(this );
051: } else {
052: throw new XAException(XAException.XAER_NOTA);
053: }
054: } else {
055: throw new XAException(
056: "No transaction manager or invalid status");
057: }
058: } catch (SystemException e) {
059: throw new XAException("Unable to get transaction status");
060: } catch (RollbackException e) {
061: throw new XAException(
062: "Unable to enlist resource with transaction");
063: }
064: }
065:
066: /**
067: * @see javax.transaction.xa.XAResource#start(javax.transaction.xa.Xid xid, int flag)
068: */
069: public void start(Xid xid, int flag) throws XAException {
070: if (this .active) {
071: if (this .xid != null && this .xid.equals(xid)) {
072: throw new XAException(XAException.XAER_DUPID);
073: } else {
074: throw new XAException(XAException.XAER_PROTO);
075: }
076: }
077: if (this .xid != null && !this .xid.equals(xid)) {
078: throw new XAException(XAException.XAER_NOTA);
079: }
080:
081: this .xid = xid;
082: this .active = true;
083: }
084:
085: /**
086: * @see javax.transaction.xa.XAResource#end(javax.transaction.xa.Xid xid, int flag)
087: */
088: public void end(Xid xid, int flag) throws XAException {
089: if (!this .active) {
090: throw new XAException(XAException.XAER_PROTO);
091: }
092:
093: if (this .xid == null || !this .xid.equals(xid)) {
094: throw new XAException(XAException.XAER_NOTA);
095: }
096: this .active = false;
097: }
098:
099: /**
100: * @see javax.transaction.xa.XAResource#forget(javax.transaction.xa.Xid xid)
101: */
102: public void forget(Xid xid) throws XAException {
103: if (this .xid == null || !this .xid.equals(xid)) {
104: throw new XAException(XAException.XAER_NOTA);
105: }
106: this .xid = null;
107: if (active) {
108: // non-fatal
109: Debug.logWarning("forget() called without end()", module);
110: }
111: }
112:
113: /**
114: * @see javax.transaction.xa.XAResource#prepare(javax.transaction.xa.Xid xid)
115: */
116: public int prepare(Xid xid) throws XAException {
117: if (this .xid == null || !this .xid.equals(xid)) {
118: throw new XAException(XAException.XAER_NOTA);
119: }
120: return XA_OK;
121: }
122:
123: /**
124: * @see javax.transaction.xa.XAResource#recover(int flag)
125: */
126: public Xid[] recover(int flag) throws XAException {
127: if (this .xid == null) {
128: return new Xid[0];
129: } else {
130: return new Xid[] { this .xid };
131: }
132: }
133:
134: /**
135: * @see javax.transaction.xa.XAResource#isSameRM(javax.transaction.xa.XAResource xaResource)
136: */
137: public boolean isSameRM(XAResource xaResource) throws XAException {
138: return xaResource == this ;
139: }
140:
141: /**
142: * @see javax.transaction.xa.XAResource#getTransactionTimeout()
143: */
144: public int getTransactionTimeout() throws XAException {
145: return this .timeout;
146: }
147:
148: /**
149: * @see javax.transaction.xa.XAResource#setTransactionTimeout(int seconds)
150: * Note: the valus is saved but in the current implementation this is not used.
151: */
152: public boolean setTransactionTimeout(int seconds)
153: throws XAException {
154: this .timeout = seconds;
155: return true;
156: }
157:
158: public Xid getXid() {
159: return this .xid;
160: }
161:
162: /**
163: * @see javax.transaction.xa.XAResource#commit(javax.transaction.xa.Xid xid, boolean onePhase)
164: */
165: public abstract void commit(Xid xid, boolean onePhase)
166: throws XAException;
167:
168: /**
169: * @see javax.transaction.xa.XAResource#rollback(javax.transaction.xa.Xid xid)
170: */
171: public abstract void rollback(Xid xid) throws XAException;
172: }
|