1 /***
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Exoffice Technologies. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Exoffice Technologies. Exolab is a registered
23 * trademark of Exoffice Technologies.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42 *
43 * $Id: JmsXAResource.java,v 1.1 2005/03/18 03:36:37 tanderson Exp $
44 */
45 package org.exolab.jms.client;
46
47 import javax.transaction.xa.XAException;
48 import javax.transaction.xa.XAResource;
49 import javax.transaction.xa.Xid;
50
51 import org.exolab.jms.server.ServerSession;
52
53 /***
54 * Client implementation of the <code>javax.transaction.xa.XAResource</code>
55 * interface.
56 *
57 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
58 * @version $Revision: 1.1 $ $Date: 2005/03/18 03:36:37 $
59 * @see JmsXASession
60 * @see JmsXAQueueSession
61 * @see JmsXATopicSession
62 */
63 class JmsXAResource implements XAResource {
64
65 /***
66 * The server session proxy.
67 */
68 private ServerSession _session;
69
70 /***
71 * The resource manager identifier, cached on first query.
72 */
73 private String _rmId = null;
74
75
76 /***
77 * Construct a new <code>JmsXAResource</code>.
78 *
79 * @param session the server session proxy
80 */
81 public JmsXAResource(ServerSession session) {
82 if (session == null) {
83 throw new IllegalArgumentException("Argument 'session' is null");
84 }
85 _session = session;
86
87 }
88
89 /***
90 * Starts work on behalf of a transaction branch specified in xid. If TMJOIN
91 * is specified, the start applies to joining a transaction previously seen
92 * by the resource manager. If TMRESUME is specified, the start applies to
93 * resuming a suspended transaction specified in the parameter xid. If
94 * neither TMJOIN nor TMRESUME is specified and the transaction specified by
95 * xid has previously been seen by the resource manager, the resource
96 * manager throws the XAException exception with XAER_DUPID error code.
97 *
98 * @param xid a global transaction identifier to be associated with the
99 * resource.
100 * @param flags one of TMNOFLAGS, TMJOIN, or TMRESUME.
101 * @throws XAException for any error
102 */
103 public void start(Xid xid, int flags)
104 throws XAException {
105 _session.start(xid, flags);
106 }
107
108 /***
109 * Ask the resource manager to prepare for a transaction commit of the
110 * transaction specified in xid.
111 *
112 * @param xid a global transaction identifier
113 * @return a value indicating the resource manager's vote on the outcome of
114 * the transaction. The possible values are: XA_RDONLY or XA_OK. If
115 * the resource manager wants to roll back the transaction, it
116 * should do so by raising an appropriate XAException in the prepare
117 * method.
118 * @throws XAException for amy error
119 */
120 public int prepare(Xid xid) throws XAException {
121 return _session.prepare(xid);
122 }
123
124 /***
125 * Commits the global transaction specified by xid.
126 *
127 * @param xid a global transaction identifier
128 * @param onePhase If true, the resource manager should use a one-phase
129 * commit protocol to commit the work done on behalf of
130 * xid.
131 * @throws XAException for any error
132 */
133 public void commit(Xid xid, boolean onePhase)
134 throws XAException {
135 _session.commit(xid, onePhase);
136 }
137
138
139 /***
140 * Ends the work performed on behalf of a transaction branch. The resource
141 * manager disassociates the XA resource from the transaction branch
142 * specified and lets the transaction complete.
143 *
144 * @param xid a global transaction identifier that is the same as the
145 * identifier used previously in the start method.
146 * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND.
147 * @throws XAException for amy error
148 */
149 public void end(Xid xid, int flags)
150 throws XAException {
151 _session.end(xid, flags);
152 }
153
154 /***
155 * Tells the resource manager to forget about a heuristically completed
156 * transaction branch.
157 *
158 * @param xid a global transaction identifier.
159 * @throws XAException for any error
160 */
161 public void forget(Xid xid)
162 throws XAException {
163 _session.forget(xid);
164 }
165
166 /***
167 * Obtains the current transaction timeout value set for this XAResource
168 * instance. If XAResource.setTransactionTimeout was not used prior to
169 * invoking this method, the return value is the default timeout set for the
170 * resource manager; otherwise, the value used in the previous
171 * setTransactionTimeout call is returned.
172 *
173 * @return the transaction timeout value in seconds.
174 * @throws XAException for any error
175 */
176 public int getTransactionTimeout()
177 throws XAException {
178 return _session.getTransactionTimeout();
179 }
180
181 /***
182 * Sets the current transaction timeout value for this XAResource instance.
183 * Once set, this timeout value is effective until setTransactionTimeout is
184 * invoked again with a different value. To reset the timeout value to the
185 * default value used by the resource manager, set the value to zero. If the
186 * timeout operation is performed successfully, the method returns true;
187 * otherwise false. If a resource manager does not support explicitly
188 * setting the transaction timeout value, this method returns false.
189 *
190 * @param seconds the transaction timeout value in seconds.
191 * @return true if the transaction timeout value is set successfully;
192 * otherwise false.
193 * @throws XAException for any error
194 */
195 public boolean setTransactionTimeout(int seconds)
196 throws XAException {
197 return _session.setTransactionTimeout(seconds);
198 }
199
200 /***
201 * This method is called to determine if the resource manager instance
202 * represented by the target object is the same as the resouce manager
203 * instance represented by the parameter xares.
204 *
205 * @param xares an XAResource object whose resource manager instance is to
206 * be compared with the resource manager instance of the target
207 * object.
208 * @return true if it's the same RM instance; otherwise false.
209 * @throws XAException for any error
210 */
211 public boolean isSameRM(XAResource xares) throws XAException {
212 boolean result = (xares instanceof JmsXAResource);
213 if (result) {
214 JmsXAResource other = (JmsXAResource) xares;
215 result = (other.getResourceManagerId() == getResourceManagerId());
216 }
217
218 return result;
219 }
220
221 /***
222 * Obtains a list of prepared transaction branches from a resource manager.
223 * The transaction manager calls this method during recovery to obtain the
224 * list of transaction branches that are currently in prepared or
225 * heuristically completed states.
226 *
227 * @param flag one of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS must be
228 * used when no other flags are set in the parameter.
229 * @return the resource manager returns zero or more XIDs of the transaction
230 * branches that are currently in a prepared or heuristically
231 * completed state. If an error occurs during the operation, the
232 * resource manager should throw the appropriate XAException.
233 * @throws XAException for any error
234 */
235 public Xid[] recover(int flag)
236 throws XAException {
237 return _session.recover(flag);
238 }
239
240 /***
241 * Informs the resource manager to roll back work done on behalf of a
242 * transaction branch.
243 *
244 * @param xid a global transaction identifier
245 * @throws XAException for any error
246 */
247 public void rollback(Xid xid)
248 throws XAException {
249 _session.rollback(xid);
250 }
251
252 /***
253 * Return the identity of the associated resource manager. If the value is
254 * not cached locally then grab it from the server.
255 *
256 * @return the identity of the resource manager
257 * @throws XAException for any error
258 */
259 public synchronized String getResourceManagerId() throws XAException {
260 if (_rmId == null) {
261 _rmId = _session.getResourceManagerId();
262 }
263 return _rmId;
264 }
265
266 }