001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.connector.outbound;
019
020 import javax.resource.ResourceException;
021 import javax.resource.spi.LocalTransaction;
022 import javax.transaction.xa.XAException;
023 import javax.transaction.xa.XAResource;
024 import javax.transaction.xa.Xid;
025
026 import org.apache.geronimo.transaction.manager.NamedXAResource;
027
028 /**
029 * LocalXAResource adapts a local transaction to be controlled by a
030 * JTA transaction manager. Of course, it cannot provide xa
031 * semantics.
032 *
033 *
034 * @version $Rev: 547737 $ $Date: 2007-06-15 12:47:19 -0400 (Fri, 15 Jun 2007) $
035 */
036 public class LocalXAResource implements NamedXAResource {
037
038 //accessible in package for testing
039 final LocalTransaction localTransaction;
040 private final String name;
041 private Xid xid;
042 private int transactionTimeout;
043
044 public LocalXAResource(LocalTransaction localTransaction, String name) {
045 this.localTransaction = localTransaction;
046 this.name = name;
047 }
048
049 // Implementation of javax.transaction.xa.XAResource
050
051 public void commit(Xid xid, boolean flag) throws XAException {
052 if (this.xid == null || !this.xid.equals(xid)) {
053 throw new XAException("Invalid Xid");
054 }
055 try {
056 localTransaction.commit();
057 } catch (ResourceException e) {
058 throw (XAException)new XAException().initCause(e);
059 } finally {
060 this.xid = null;
061 }
062
063 }
064
065 public void forget(Xid xid) throws XAException {
066 this.xid = null;
067 }
068
069 public int getTransactionTimeout() throws XAException {
070 return transactionTimeout;
071 }
072
073 public boolean isSameRM(XAResource xares) throws XAException {
074 return this == xares;
075 }
076
077 public Xid[] recover(int n) throws XAException {
078 return new Xid[0];
079 }
080
081 public void rollback(Xid xid) throws XAException {
082 if (this.xid == null || !this.xid.equals(xid)) {
083 throw new XAException("Invalid Xid");
084 }
085 try {
086 localTransaction.rollback();
087 } catch (ResourceException e) {
088 throw (XAException)new XAException().initCause(e);
089 } finally {
090 this.xid = null;
091 }
092 }
093
094 public boolean setTransactionTimeout(int txTimeout) throws XAException {
095 this.transactionTimeout = txTimeout;
096 return true;
097 }
098
099 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 }