text: /*
   * JBoss, Home of Professional Open Source
   * Copyright 2007, Red Hat Middleware LLC, and individual contributors
   * as indicated by the @author tags.
   * See the copyright.txt in the distribution for a full listing
   * of individual contributors.
   * This copyrighted material is made available to anyone wishing to use,
   * modify, copy, or redistribute it subject to the terms and conditions
   * of the GNU Lesser General Public License, v. 2.1.
   * This program is distributed in the hope that it will be useful, but WITHOUT A
   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
   * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
   * You should have received a copy of the GNU Lesser General Public License,
   * v.2.1 along with this distribution; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   * MA  02110-1301, USA.
   *
   * (C) 2007,
   * @author JBoss Inc.
   */
  package com.arjuna.mw.wst11.client;
  
  import java.util.Iterator;
  
  import javax.xml.soap.Name;
  import javax.xml.soap.SOAPEnvelope;
  import javax.xml.soap.SOAPException;
  import javax.xml.soap.SOAPHeader;
  import javax.xml.soap.SOAPHeaderElement;
  import javax.xml.soap.SOAPMessage;
  
  import org.oasis_open.docs.ws_tx.wscoor._2006._06.CoordinationContextType;
  
  import com.arjuna.mw.wsc11.context.Context;
  import com.arjuna.mw.wst.TxContext;
  import com.arjuna.mw.wst.common.SOAPUtil;
  import com.arjuna.mw.wst11.BusinessActivityManagerFactory;
  import com.arjuna.mw.wst11.TransactionManager;
  import com.arjuna.mw.wst11.TransactionManagerFactory;
  import com.arjuna.mw.wst11.common.CoordinationContextHelper;
  import com.arjuna.mw.wstx.logging.wstxLogger;
  import com.arjuna.mwlabs.wst11.at.context.TxContextImple;
  import com.arjuna.webservices11.wsat.AtomicTransactionConstants;
  import com.arjuna.webservices11.wsba.BusinessActivityConstants;
  import com.arjuna.webservices11.wscoor.CoordinationConstants;
  
  /**
   * Common base class for classes used to perform
   * WS-Transaction context manipulation on SOAP messages.
   *
   */
  class JaxBaseHeaderContextProcessor
  {
      /**
       * Handle the request.
       *
       * @param soapMessage The current message context.
       */
      public boolean handleOutboundMessage(final SOAPMessage soapMessage)
      {
          return handleOutboundMessage(soapMessage, true);
      }
  
      /**
       * Handle the request.
       *
       * @param soapMessage The current message context.
       * @param mustUnderstand Value of MustUnderstand attribute.
       * @return whether the message was handled
       */
      public boolean handleOutboundMessage(final SOAPMessage soapMessage, boolean mustUnderstand)
      {
          if (soapMessage == null)
          {
              return true ;
          }
  
          try
          {
              /*
               * There should either be an Atomic Transaction *or* a Business Activity
               * associated with the thread.
               */
              final TransactionManager transactionManager = TransactionManagerFactory.transactionManager() ;
              final com.arjuna.mw.wst11.BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager() ;
  
              final Context atContext ;
              if (transactionManager != null)
              {
                  final TxContextImple txContext =
                      (TxContextImple)transactionManager.currentTransaction() ;
                  atContext = (txContext == null ? null : txContext.context()) ;
              }
              else
              {
                  atContext = null ;
              }
  
              final Context baContext ;
              if (businessActivityManager != null)
              {
                  final com.arjuna.mwlabs.wst11.ba.context.TxContextImple txContext =
                      (com.arjuna.mwlabs.wst11.ba.context.TxContextImple)businessActivityManager.currentTransaction() ;
                  baContext = (txContext == null ? null : txContext.context()) ;
              }
              else
              {
                  baContext = null ;
              }
  
              final CoordinationContextType coordinationContext ;
              if (baContext != null)
              {
                  coordinationContext = baContext.getCoordinationContext() ;
              }
              else if (atContext != null)
              {
                  coordinationContext = atContext.getCoordinationContext() ;
              }
              else
              {
                  coordinationContext = null ;
              }
  
              if (coordinationContext != null)
              {
                  final SOAPEnvelope env = soapMessage.getSOAPPart().getEnvelope() ;
                  SOAPHeader header = env.getHeader() ;
                  if (header == null)
                  {
                      header = env.addHeader() ;
                  }
                  final Name name = env.createName(CoordinationConstants.WSCOOR_ELEMENT_COORDINATION_CONTEXT, CoordinationConstants.WSCOOR_PREFIX, CoordinationConstants.WSCOOR_NAMESPACE) ;
                  final SOAPHeaderElement headerElement = header.addHeaderElement(name) ;
                  headerElement.addNamespaceDeclaration(CoordinationConstants.WSCOOR_PREFIX, CoordinationConstants.WSCOOR_NAMESPACE) ;
                  headerElement.setMustUnderstand(mustUnderstand) ;
                  CoordinationContextHelper.serialise(coordinationContext, headerElement) ;
              }
          }
          catch (final Throwable th) {
              wstxLogger.i18NLogger.warn_mw_wst11_client_JaxHC11P_1("com.arjuna.mw.wst11.client.JaxBaseHeaderContextProcessor.handleRequest()", th);
          }
  
          return true ;
      }
  
      /**
       * Resume the current transaction.
       *
       */
  
      protected void resumeTransaction(final SOAPMessage soapMessage)
      {
          if (soapMessage != null)
          {
              try
              {
                  final SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope() ;
                  final SOAPHeaderElement soapHeaderElement = getHeaderElement(soapEnvelope, CoordinationConstants.WSCOOR_NAMESPACE, CoordinationConstants.WSCOOR_ELEMENT_COORDINATION_CONTEXT) ;
  
                  if (soapHeaderElement != null)
                  {
                      final CoordinationContextType cc = CoordinationContextHelper.deserialise(soapHeaderElement) ;
                      if (cc != null)
                      {
                          final String coordinationType = cc.getCoordinationType() ;
                          if (AtomicTransactionConstants.WSAT_PROTOCOL.equals(coordinationType))
                          {
                              final TxContext txContext = new TxContextImple(cc) ;
                              TransactionManagerFactory.transactionManager().resume(txContext) ;
                          }
                          else if (BusinessActivityConstants.WSBA_PROTOCOL_ATOMIC_OUTCOME.equals(coordinationType))
                          {
                              final TxContext txContext = new com.arjuna.mwlabs.wst11.ba.context.TxContextImple(cc);
                              BusinessActivityManagerFactory.businessActivityManager().resume(txContext) ;
                          }
                          else {
                              wstxLogger.i18NLogger.warn_mw_wst11_client_JaxHC11P_2("com.arjuna.mw.wst11.client.JaxBaseHeaderContextProcessor.resumeTransaction()", coordinationType);
                          }
                      }
                  }
              }
              catch (final Throwable th) {
                  wstxLogger.i18NLogger.warn_mw_wst11_client_JaxHC11P_1("com.arjuna.mw.wst11.client.JaxBaseHeaderContextProcessor.resumeTransaction()", th);
              }
          }
      }
  
      /**
       * Retrieve the first header matching the uri and name.
       * @param soapEnvelope The soap envelope containing the header.
       * @param uri The uri of the header element.
       * @param name The name of the header element.
       * @return The header element or null if not found.
       */
      private SOAPHeaderElement getHeaderElement(final SOAPEnvelope soapEnvelope, final String uri, final String name)
          throws SOAPException
      {
          final SOAPHeader soapHeader = soapEnvelope.getHeader() ;
          if (soapHeader != null)
          {
              final Iterator headerIter = SOAPUtil.getChildElements(soapHeader) ;
              while(headerIter.hasNext())
              {
                  final SOAPHeaderElement current = (SOAPHeaderElement)headerIter.next() ;
                  final Name currentName = current.getElementName() ;
                  if ((currentName != null) &&
                      match(name, currentName.getLocalName()) &&
                      match(uri, currentName.getURI()))
                  {
                      return current ;
                  }
              }
          }
          return null ;
      }
  
      /**
       * Do the two references match?
       * @param lhs The first reference.
       * @param rhs The second reference.
       * @return true if the references are both null or if they are equal.
       */
      private boolean match(final Object lhs, final Object rhs)
      {
          if (lhs == null)
          {
              return (rhs == null) ;
          }
          else
          {
              return lhs.equals(rhs) ;
          }
      }
  }
  