View Javadoc

1   /**
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.apache.geronimo.connector.outbound;
19  
20  import javax.resource.ResourceException;
21  import javax.resource.spi.LocalTransaction;
22  import javax.transaction.xa.XAException;
23  import javax.transaction.xa.XAResource;
24  import javax.transaction.xa.Xid;
25  
26  import org.apache.geronimo.transaction.manager.NamedXAResource;
27  
28  /**
29   * LocalXAResource adapts a local transaction to be controlled by a
30   * JTA transaction manager.  Of course, it cannot provide xa
31   * semantics.
32   *
33   *
34   * @version $Rev: 547737 $ $Date: 2007-06-15 12:47:19 -0400 (Fri, 15 Jun 2007) $
35   */
36  public class LocalXAResource implements NamedXAResource {
37  
38      //accessible in package for testing
39      final LocalTransaction localTransaction;
40      private final String name;
41      private Xid xid;
42      private int transactionTimeout;
43  
44      public LocalXAResource(LocalTransaction localTransaction, String name) {
45          this.localTransaction = localTransaction;
46          this.name = name;
47      }
48  
49      // Implementation of javax.transaction.xa.XAResource
50  
51      public void commit(Xid xid, boolean flag) throws XAException {
52          if (this.xid == null || !this.xid.equals(xid)) {
53              throw new XAException("Invalid Xid");
54          }
55          try {
56              localTransaction.commit();
57          } catch (ResourceException e) {
58              throw (XAException)new XAException().initCause(e);
59           } finally {
60              this.xid = null;
61          }
62  
63      }
64  
65      public void forget(Xid xid) throws XAException {
66          this.xid = null;
67      }
68  
69      public int getTransactionTimeout() throws XAException {
70          return transactionTimeout;
71      }
72  
73      public boolean isSameRM(XAResource xares) throws XAException {
74          return this == xares;
75      }
76  
77      public Xid[] recover(int n) throws XAException {
78          return new Xid[0];
79      }
80  
81      public void rollback(Xid xid) throws XAException {
82          if (this.xid == null || !this.xid.equals(xid)) {
83              throw new XAException("Invalid Xid");
84          }
85          try {
86              localTransaction.rollback();
87          } catch (ResourceException e) {
88              throw (XAException)new XAException().initCause(e);
89          } finally {
90              this.xid = null;
91          }
92      }
93  
94      public boolean setTransactionTimeout(int txTimeout) throws XAException {
95          this.transactionTimeout = txTimeout;
96          return true;
97      }
98  
99      public void start(Xid xid, int flag) throws XAException {
100         if (flag == XAResource.TMNOFLAGS) {
101             // first time in this transaction
102             if (this.xid != null) {
103                 throw new XAException("already enlisted");
104             }
105             this.xid = xid;
106             try {
107                 localTransaction.begin();
108             } catch (ResourceException e) {
109                 throw (XAException) new XAException("could not start local tx").initCause(e);
110             }
111         } else if (flag == XAResource.TMRESUME) {
112             if (xid != this.xid) {
113                 throw new XAException("attempting to resume in different transaction");
114             }
115         } else {
116             throw new XAException("unknown state");
117         }
118     }
119 
120     public void end(Xid xid, int flag) throws XAException {
121         if (xid != this.xid) {
122             throw new XAException("Invalid Xid");
123         }
124         //we could keep track of if the flag is TMSUCCESS...
125     }
126 
127     public int prepare(Xid xid) throws XAException {
128         //log warning that semantics are incorrect...
129         return XAResource.XA_OK;
130     }
131 
132     public String getName() {
133         return name;
134     }
135 }