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.transactionlog;
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     * Works with JDBCLog to provide last resource optimization for a single 1-pc database.
030     * The database work is committed when the log writes its prepare record, not here.
031     *
032     * @version $Rev: 547737 $ $Date: 2007-06-15 18:47:19 +0200 (Fri, 15 Jun 2007) $
033     *
034     * */
035    public class LogXAResource implements NamedXAResource {
036    
037        final String name;
038        final LocalTransaction localTransaction;
039        private Xid xid;
040    
041        public LogXAResource(LocalTransaction localTransaction, String name) {
042            this.localTransaction = localTransaction;
043            this.name = name;
044        }
045        public void commit(Xid xid, boolean onePhase) throws XAException {
046        }
047    
048        public void end(Xid xid, int flags) throws XAException {
049        }
050    
051        public void forget(Xid xid) throws XAException {
052        }
053    
054        public int getTransactionTimeout() throws XAException {
055            return 0;
056        }
057    
058        public boolean isSameRM(XAResource xaResource) throws XAException {
059            return this == xaResource;
060        }
061    
062        public int prepare(Xid xid) throws XAException {
063            return 0;
064        }
065    
066        public Xid[] recover(int flag) throws XAException {
067            return new Xid[0];
068        }
069    
070        public void rollback(Xid xid) throws XAException {
071            if (this.xid == null || !this.xid.equals(xid)) {
072                throw new XAException("Invalid Xid");
073            }
074            try {
075                localTransaction.rollback();
076            } catch (ResourceException e) {
077                throw (XAException)new XAException().initCause(e);
078            } finally {
079                this.xid = null;
080            }
081        }
082    
083        public boolean setTransactionTimeout(int seconds) throws XAException {
084            return false;
085        }
086    
087        public void start(Xid xid, int flag) throws XAException {
088            if (flag == XAResource.TMNOFLAGS) {
089                // first time in this transaction
090                if (this.xid != null) {
091                    throw new XAException("already enlisted");
092                }
093                this.xid = xid;
094                try {
095                    localTransaction.begin();
096                } catch (ResourceException e) {
097                    throw (XAException) new XAException("could not start local tx").initCause(e);
098                }
099            } else if (flag == XAResource.TMRESUME) {
100                if (xid != this.xid) {
101                    throw new XAException("attempting to resume in different transaction");
102                }
103            } else {
104                throw new XAException("unknown state");
105            }
106         }
107    
108        public String getName() {
109            return name;
110        }
111    }