KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > jms > recovery > XAResourceWrapper


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2006, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.jms.recovery;
23
24 import javax.jms.ExceptionListener JavaDoc;
25 import javax.jms.JMSException JavaDoc;
26 import javax.jms.XAConnection JavaDoc;
27 import javax.jms.XAConnectionFactory JavaDoc;
28 import javax.jms.XASession JavaDoc;
29 import javax.naming.Context JavaDoc;
30 import javax.naming.InitialContext JavaDoc;
31 import javax.transaction.xa.XAException JavaDoc;
32 import javax.transaction.xa.XAResource JavaDoc;
33 import javax.transaction.xa.Xid JavaDoc;
34
35 import org.jboss.jms.jndi.JMSProviderAdapter;
36 import org.jboss.logging.Logger;
37 import org.jboss.util.naming.Util;
38
39 /**
40  * XAResourceWrapper.
41  *
42  * @author <a HREF="adrian@jboss.com">Adrian Brock</a>
43  * @version $Revision: 45341 $
44  */

45 public class XAResourceWrapper implements XAResource JavaDoc, ExceptionListener JavaDoc
46 {
47    /** The log */
48    private static final Logger log = Logger.getLogger(XAResourceWrapper.class);
49
50    /** The jms provider name */
51    private String JavaDoc providerName;
52    
53    /** The state lock */
54    private static final Object JavaDoc lock = new Object JavaDoc();
55    
56    /** The connection */
57    private XAConnection JavaDoc connection;
58    
59    /** The delegate XAResource */
60    private XAResource JavaDoc delegate;
61
62    /**
63     * Get the providerName.
64     *
65     * @return the providerName.
66     */

67    public String JavaDoc getProviderName()
68    {
69       return providerName;
70    }
71
72    /**
73     * Set the providerName.
74     *
75     * @param providerName the providerName.
76     */

77    public void setProviderName(String JavaDoc providerName)
78    {
79       this.providerName = providerName;
80    }
81    
82    public Xid JavaDoc[] recover(int flag) throws XAException JavaDoc
83    {
84       log.debug("Recover " + providerName);
85       XAResource JavaDoc xaResource = getDelegate();
86       try
87       {
88          return xaResource.recover(flag);
89       }
90       catch (XAException JavaDoc e)
91       {
92          throw check(e);
93       }
94    }
95
96    public void commit(Xid JavaDoc xid, boolean onePhase) throws XAException JavaDoc
97    {
98       log.debug("Commit " + providerName + " xid " + " onePhase=" + onePhase);
99       XAResource JavaDoc xaResource = getDelegate();
100       try
101       {
102          xaResource.commit(xid, onePhase);
103       }
104       catch (XAException JavaDoc e)
105       {
106          throw check(e);
107       }
108    }
109
110    public void rollback(Xid JavaDoc xid) throws XAException JavaDoc
111    {
112       log.debug("Rollback " + providerName + " xid ");
113       XAResource JavaDoc xaResource = getDelegate();
114       try
115       {
116          xaResource.rollback(xid);
117       }
118       catch (XAException JavaDoc e)
119       {
120          throw check(e);
121       }
122    }
123
124    public void forget(Xid JavaDoc xid) throws XAException JavaDoc
125    {
126       log.debug("Forget " + providerName + " xid ");
127       XAResource JavaDoc xaResource = getDelegate();
128       try
129       {
130          xaResource.forget(xid);
131       }
132       catch (XAException JavaDoc e)
133       {
134          throw check(e);
135       }
136    }
137
138    public boolean isSameRM(XAResource JavaDoc xaRes) throws XAException JavaDoc
139    {
140       if (xaRes instanceof XAResourceWrapper)
141          xaRes = ((XAResourceWrapper) xaRes).getDelegate();
142
143       XAResource JavaDoc xaResource = getDelegate();
144       try
145       {
146          return xaResource.isSameRM(xaRes);
147       }
148       catch (XAException JavaDoc e)
149       {
150          throw check(e);
151       }
152    }
153
154    public int prepare(Xid JavaDoc xid) throws XAException JavaDoc
155    {
156       XAResource JavaDoc xaResource = getDelegate();
157       try
158       {
159          return xaResource.prepare(xid);
160       }
161       catch (XAException JavaDoc e)
162       {
163          throw check(e);
164       }
165    }
166
167    public void start(Xid JavaDoc xid, int flags) throws XAException JavaDoc
168    {
169       XAResource JavaDoc xaResource = getDelegate();
170       try
171       {
172          xaResource.start(xid, flags);
173       }
174       catch (XAException JavaDoc e)
175       {
176          throw check(e);
177       }
178    }
179
180    public void end(Xid JavaDoc xid, int flags) throws XAException JavaDoc
181    {
182       XAResource JavaDoc xaResource = getDelegate();
183       try
184       {
185          xaResource.end(xid, flags);
186       }
187       catch (XAException JavaDoc e)
188       {
189          throw check(e);
190       }
191    }
192
193    public int getTransactionTimeout() throws XAException JavaDoc
194    {
195       XAResource JavaDoc xaResource = getDelegate();
196       try
197       {
198          return xaResource.getTransactionTimeout();
199       }
200       catch (XAException JavaDoc e)
201       {
202          throw check(e);
203       }
204    }
205
206    public boolean setTransactionTimeout(int seconds) throws XAException JavaDoc
207    {
208       XAResource JavaDoc xaResource = getDelegate();
209       try
210       {
211          return xaResource.setTransactionTimeout(seconds);
212       }
213       catch (XAException JavaDoc e)
214       {
215          throw check(e);
216       }
217    }
218
219    public void onException(JMSException JavaDoc exception)
220    {
221       log.warn("Notified of connection failure in recovery delegate for provider " + providerName, exception);
222       close();
223    }
224    
225    /**
226     * Get the delegate XAResource
227     *
228     * @return the delegate
229     * @throws XAException for any problem
230     */

231    public XAResource JavaDoc getDelegate() throws XAException JavaDoc
232    {
233       XAResource JavaDoc result = null;
234       Exception JavaDoc error = null;
235       try
236       {
237          result = connect();
238       }
239       catch (Exception JavaDoc e)
240       {
241          error = e;
242       }
243
244       if (result == null)
245       {
246          XAException JavaDoc xae = new XAException JavaDoc("Error trying to connect to provider " + providerName);
247          xae.errorCode = XAException.XAER_RMERR;
248          if (error != null)
249             xae.initCause(error);
250          log.debug("Cannot get delegate XAResource", xae);
251          throw xae;
252       }
253       
254       return result;
255    }
256    
257    /**
258     * Connect to the server if not already done so
259     *
260     * @return the delegate XAResource
261     * @throws Exception for any problem
262     */

263    protected XAResource JavaDoc connect() throws Exception JavaDoc
264    {
265       // Do we already have a valid delegate?
266
synchronized (lock)
267       {
268          if (delegate != null)
269             return delegate;
270       }
271       
272       // Create the connection
273
XAConnection JavaDoc xaConnection = getConnectionFactory().createXAConnection();
274       synchronized (lock)
275       {
276          connection = xaConnection;
277       }
278
279       // Retrieve the delegate XAResource
280
try
281       {
282          XASession JavaDoc session = connection.createXASession();
283          XAResource JavaDoc result = session.getXAResource();
284          synchronized (lock)
285          {
286             delegate = result;
287          }
288          return delegate;
289       }
290       catch (Exception JavaDoc e)
291       {
292          close();
293          throw e;
294       }
295    }
296
297    /**
298     * Get the XAConnectionFactory
299     *
300     * @return the connection
301     * @throws Exception for any problem
302     */

303    protected XAConnectionFactory JavaDoc getConnectionFactory() throws Exception JavaDoc
304    {
305       // Get the JMS Provider Adapter
306
if (providerName == null)
307          throw new IllegalArgumentException JavaDoc("Null provider name");
308       String JavaDoc providerAdapterJNDI = providerName;
309       if (providerAdapterJNDI.startsWith("java:") == false)
310          providerAdapterJNDI = "java:" + providerAdapterJNDI;
311       Context JavaDoc ctx = new InitialContext JavaDoc();
312       JMSProviderAdapter adapter = (JMSProviderAdapter) Util.lookup(providerAdapterJNDI, JMSProviderAdapter.class);
313
314       // Determine the XAConnectionFactory name
315
String JavaDoc connectionFactoryRef = adapter.getFactoryRef();
316       if (connectionFactoryRef == null)
317          throw new IllegalStateException JavaDoc("Provider '" + providerName + "' has no FactoryRef");
318       
319       // Lookup the connection factory
320
ctx = adapter.getInitialContext();
321       try
322       {
323          return (XAConnectionFactory JavaDoc) Util.lookup(ctx, connectionFactoryRef, XAConnectionFactory JavaDoc.class);
324       }
325       finally
326       {
327          ctx.close();
328       }
329    }
330    
331    /**
332     * Close the connection
333     */

334    public void close()
335    {
336       try
337       {
338          XAConnection JavaDoc oldConnection = null;
339          synchronized (lock)
340          {
341             oldConnection = connection;
342             connection = null;
343             delegate = null;
344          }
345          if (oldConnection != null)
346             oldConnection.close();
347       }
348       catch (Exception JavaDoc ignored)
349       {
350          log.trace("Ignored error during close", ignored);
351       }
352    }
353
354    /**
355     * Check whether an XAException is fatal. If it is an RM problem
356     * we close the connection so the next call will reconnect.
357     *
358     * @param e the xa exception
359     * @return never
360     * @throws XAException always
361     */

362    protected XAException JavaDoc check(XAException JavaDoc e) throws XAException JavaDoc
363    {
364       if (e.errorCode == XAException.XAER_RMERR || e.errorCode == XAException.XAER_RMFAIL)
365       {
366          log.debug("Fatal error in provider " + providerName, e);
367          close();
368       }
369       throw e;
370    }
371
372    protected void finalize() throws Throwable JavaDoc
373    {
374       close();
375    }
376 }
377
Popular Tags