001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.test.tm.resource;
023:
024: import java.util.HashMap;
025:
026: import javax.transaction.xa.XAException;
027: import javax.transaction.xa.XAResource;
028: import javax.transaction.xa.Xid;
029:
030: /**
031: * A resource
032: *
033: * @author Adrian@jboss.org
034: * @version $Revision: 57211 $
035: */
036: public class Resource implements XAResource {
037: public static final int ERROR = -1;
038: public static final int INACTIVE = 0;
039: public static final int ACTIVE = 1;
040: public static final int SUSPENDED = 2;
041: public static final int PREPARED = 3;
042: public static final int COMMITTED = 4;
043: public static final int ROLLEDBACK = 5;
044: public static final int FORGOT = 6;
045: public static final int ENDED = 7;
046:
047: Integer id;
048:
049: boolean sameRM = false;
050:
051: HashMap xids = new HashMap();
052: Xid last = null;
053:
054: public Resource(Integer id) {
055: this .id = id;
056: }
057:
058: public int getStatus() throws XAException {
059: return getState(last, true, false).resState;
060: }
061:
062: public void setStatus(int status) throws XAException {
063: getState(last).status = status;
064: }
065:
066: public void newResourceManager() {
067: sameRM = false;
068: }
069:
070: public int prepare(Xid xid) throws XAException {
071: State state = getState(xid);
072: if (state.resState != ACTIVE && state.resState != SUSPENDED
073: && state.resState != ENDED) {
074: state.resState = ERROR;
075: throw new XAException(XAException.XAER_PROTO);
076: }
077: state.resState = PREPARED;
078: return state.status;
079: }
080:
081: public void commit(Xid xid, boolean onePhase) throws XAException {
082: State state = getState(xid);
083: if (onePhase == false && state.resState != PREPARED) {
084: state.resState = ERROR;
085: throw new XAException(XAException.XAER_PROTO);
086: }
087: if (onePhase && state.resState != ACTIVE
088: && state.resState != SUSPENDED
089: && state.resState != ENDED) {
090: state.resState = ERROR;
091: throw new XAException(XAException.XAER_PROTO);
092: }
093: state.resState = COMMITTED;
094: state.removed = true;
095: }
096:
097: public void rollback(Xid xid) throws XAException {
098: State state = getState(xid);
099: if (state.resState == INACTIVE) {
100: state.resState = ERROR;
101: throw new XAException(XAException.XAER_PROTO);
102: }
103: state.resState = ROLLEDBACK;
104: state.removed = true;
105: }
106:
107: public void forget(Xid xid) throws XAException {
108: State state = getState(xid, false, false);
109: state.resState = FORGOT;
110: state.removed = true;
111: }
112:
113: public void start(Xid xid, int flags) throws XAException {
114: if (xid == null)
115: throw new XAException(XAException.XAER_NOTA);
116: if (flags == TMJOIN) {
117: getState(xid); // Just checks the state
118: return;
119: }
120: if (flags == TMRESUME) {
121: State state = getState(xid);
122: if (state.resState != SUSPENDED) {
123: state.resState = ERROR;
124: throw new XAException("Xid not suspended " + xid);
125: }
126: return;
127: }
128: if (xids.containsKey(xid)) {
129: throw new XAException(XAException.XAER_DUPID);
130: }
131: xids.put(xid, new State());
132: last = xid;
133:
134: }
135:
136: public void end(Xid xid, int flags) throws XAException {
137: State state = getState(xid);
138: if (flags == TMSUSPEND) {
139: state.resState = SUSPENDED;
140: return;
141: }
142: state.resState = ENDED;
143: }
144:
145: public Xid[] recover(int flag) {
146: return new Xid[0];
147: }
148:
149: public boolean isSameRM(XAResource res) {
150: return sameRM;
151: }
152:
153: public int getTransactionTimeout() {
154: return 0;
155: }
156:
157: public boolean setTransactionTimeout(int timeout) {
158: return false;
159: }
160:
161: public State getState(Xid xid) throws XAException {
162: return getState(xid, false);
163: }
164:
165: public State getState(Xid xid, boolean includeRemoved)
166: throws XAException {
167: return getState(xid, includeRemoved, true);
168: }
169:
170: public State getState(Xid xid, boolean includeRemoved,
171: boolean checkStatus) throws XAException {
172: if (xid == null)
173: throw new XAException(XAException.XAER_NOTA);
174: State state = (State) xids.get(xid);
175: if (state.resState == ERROR)
176: throw new XAException(XAException.XAER_PROTO);
177: if (state == null
178: || (state.removed == true && includeRemoved == false))
179: throw new XAException(XAException.XAER_PROTO);
180: if (checkStatus && (state.status >= 5 || state.status < 0))
181: throw new XAException(state.status);
182: return state;
183: }
184:
185: public class State {
186: int status = XAResource.XA_OK;
187: int resState = ACTIVE;
188: boolean removed = false;
189: }
190: }
|