content: /**
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.activemq.ra;
  
  import jakarta.jms.JMSException;
  import javax.transaction.xa.XAException;
  import javax.transaction.xa.XAResource;
  import javax.transaction.xa.Xid;
  
  import org.apache.activemq.TransactionContext;
  import org.apache.activemq.command.TransactionId;
  import org.apache.activemq.transaction.Synchronization;
  
  /**
   * Allows us to switch between using a shared transaction context, or using a
   * local transaction context.
   * 
   * 
   */
  public class ManagedTransactionContext extends TransactionContext {
  
      private final TransactionContext sharedContext;
      private boolean useSharedTxContext;
  
      public ManagedTransactionContext(TransactionContext sharedContext) {
          super(sharedContext.getConnection());
          this.sharedContext = sharedContext;
          setLocalTransactionEventListener(sharedContext.getLocalTransactionEventListener());
      }
  
      public void setUseSharedTxContext(boolean enable) throws JMSException {
          if (isInLocalTransaction() || isInXATransaction()) {
              throw new JMSException("The resource is already being used in transaction context.");
          }
          useSharedTxContext = enable;
      }
  
      public void begin() throws JMSException {
          if (useSharedTxContext) {
              sharedContext.begin();
          } else {
              super.begin();
          }
      }
  
      public void commit() throws JMSException {
          if (useSharedTxContext) {
              sharedContext.commit();
          } else {
              super.commit();
          }
      }
  
      public void commit(Xid xid, boolean onePhase) throws XAException {
          if (useSharedTxContext) {
              sharedContext.commit(xid, onePhase);
          } else {
              super.commit(xid, onePhase);
          }
      }
  
      public void end(Xid xid, int flags) throws XAException {
          if (useSharedTxContext) {
              sharedContext.end(xid, flags);
          } else {
              super.end(xid, flags);
          }
      }
  
      public void forget(Xid xid) throws XAException {
          if (useSharedTxContext) {
              sharedContext.forget(xid);
          } else {
              super.forget(xid);
          }
      }
  
      public TransactionId getTransactionId() {
          if (useSharedTxContext) {
              return sharedContext.getTransactionId();
          } else {
              return super.getTransactionId();
          }
      }
  
      public int getTransactionTimeout() throws XAException {
          if (useSharedTxContext) {
              return sharedContext.getTransactionTimeout();
          } else {
              return super.getTransactionTimeout();
          }
      }
  
      public boolean isInLocalTransaction() {
          if (useSharedTxContext) {
              return sharedContext.isInLocalTransaction();
          } else {
              return super.isInLocalTransaction();
          }
      }
  
      public boolean isRollbackOnly() {
          return sharedContext.isRollbackOnly() || super.isRollbackOnly();
      }
  
      public boolean isInXATransaction() {
          if (useSharedTxContext) {
              // context considers ended XA transactions as active, so just check for presence
              // of tx when it is shared
              return sharedContext.isInTransaction();
          } else {
              return super.isInXATransaction();
          }
      }
  
      @Override
      public boolean isInTransaction() {
          return isInXATransaction() || isInLocalTransaction();
      }
   
      public boolean isSameRM(XAResource xaResource) throws XAException {
          if (useSharedTxContext) {
              return sharedContext.isSameRM(xaResource);
          } else {
              return super.isSameRM(xaResource);
          }
      }
  
      public int prepare(Xid xid) throws XAException {
          if (useSharedTxContext) {
              return sharedContext.prepare(xid);
          } else {
              return super.prepare(xid);
          }
      }
  
      public Xid[] recover(int flag) throws XAException {
          if (useSharedTxContext) {
              return sharedContext.recover(flag);
          } else {
              return super.recover(flag);
          }
      }
  
      public void rollback() throws JMSException {
          if (useSharedTxContext) {
              sharedContext.rollback();
          } else {
              super.rollback();
          }
      }
  
      public void rollback(Xid xid) throws XAException {
          if (useSharedTxContext) {
              sharedContext.rollback(xid);
          } else {
              super.rollback(xid);
          }
      }
  
      public boolean setTransactionTimeout(int seconds) throws XAException {
          if (useSharedTxContext) {
              return sharedContext.setTransactionTimeout(seconds);
          } else {
              return super.setTransactionTimeout(seconds);
          }
      }
  
      public void start(Xid xid, int flags) throws XAException {
          if (useSharedTxContext) {
              sharedContext.start(xid, flags);
          } else {
              super.start(xid, flags);
          }
      }
  
      public void addSynchronization(Synchronization s) {
          if (useSharedTxContext) {
              sharedContext.addSynchronization(s);
          } else {
              super.addSynchronization(s);
          }
      }
  }
  