Package com.eviware.soapui.impl.wsdl.support.soap

Source Code of com.eviware.soapui.impl.wsdl.support.soap.SoapUtils

/*
*  soapUI, copyright (C) 2004-2011 eviware.com
*
*  soapUI is free software; you can redistribute it and/or modify it under the
*  terms of version 2.1 of the GNU Lesser General Public License as published by
*  the Free Software Foundation.
*
*  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
*  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*  See the GNU Lesser General Public License for more details at gnu.org.
*/

package com.eviware.soapui.impl.wsdl.support.soap;

import java.util.List;

import javax.wsdl.BindingOperation;
import javax.wsdl.Message;
import javax.wsdl.Part;
import javax.xml.namespace.QName;

import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.mock.DispatchException;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
import com.eviware.soapui.model.iface.Attachment;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.types.StringToStringsMap;
import com.eviware.soapui.support.xml.XmlUtils;

/**
* SOAP-related utility-methods..
*
* @author ole.matzura
*/

public class SoapUtils
{
  public static boolean isSoapFault( String responseContent, SoapVersion soapVersion ) throws XmlException
  {
    if( StringUtils.isNullOrEmpty( responseContent ) )
      return false;

    // check manually before resource intensive xpath
    if( responseContent.indexOf( ":Fault" ) > 0 || responseContent.indexOf( "<Fault" ) > 0 )
    {
      // XmlObject xml = XmlObject.Factory.parse( responseContent );
      XmlObject xml = XmlUtils.createXmlObject( responseContent );
      XmlObject[] paths = xml.selectPath( "declare namespace env='" + soapVersion.getEnvelopeNamespace() + "';"
          + "//env:Fault" );
      if( paths.length > 0 )
        return true;
    }

    return false;
  }

  /**
   * Init soapversion from content-type header.. should envelope be checked
   * and/or override?
   *
   * @param xmlObject
   */

  public static SoapVersion deduceSoapVersion( String contentType, XmlObject xmlObject )
  {
    if( xmlObject != null )
    {
      Element elm = ( ( Document )( xmlObject.getDomNode() ) ).getDocumentElement();
      if( elm.getLocalName().equals( "Envelope" ) )
      {
        if( elm.getNamespaceURI().equals( SoapVersion.Soap11.getEnvelopeNamespace() ) )
          return SoapVersion.Soap11;
        else if( elm.getNamespaceURI().equals( SoapVersion.Soap12.getEnvelopeNamespace() ) )
          return SoapVersion.Soap12;
      }
    }

    SoapVersion soapVersion = null;

    if( StringUtils.isNullOrEmpty( contentType ) )
      return null;

    soapVersion = contentType.startsWith( SoapVersion.Soap11.getContentType() ) ? SoapVersion.Soap11 : null;
    soapVersion = soapVersion == null && contentType.startsWith( SoapVersion.Soap12.getContentType() ) ? SoapVersion.Soap12
        : soapVersion;
    if( soapVersion == null && contentType.startsWith( "application/xop+xml" ) )
    {
      if( contentType.indexOf( "type=\"" + SoapVersion.Soap11.getContentType() + "\"" ) > 0 )
        soapVersion = SoapVersion.Soap11;
      else if( contentType.indexOf( "type=\"" + SoapVersion.Soap12.getContentType() + "\"" ) > 0 )
        soapVersion = SoapVersion.Soap12;
    }

    return soapVersion;
  }

  public static String getSoapAction( SoapVersion soapVersion, StringToStringsMap headers )
  {
    String soapAction = null;
    String contentType = headers.get( "Content-Type", "" );

    if( soapVersion == SoapVersion.Soap11 )
    {
      soapAction = headers.get( "SOAPAction", "" );
    }
    else if( soapVersion == SoapVersion.Soap12 )
    {
      int ix = contentType.indexOf( "action=" );
      if( ix > 0 )
      {
        int endIx = contentType.indexOf( ';', ix );
        soapAction = endIx == -1 ? contentType.substring( ix + 7 ) : contentType.substring( ix + 7, endIx );
      }
    }

    soapAction = StringUtils.unquote( soapAction );

    return soapAction;
  }

  public static XmlObject getBodyElement( XmlObject messageObject, SoapVersion soapVersion ) throws XmlException
  {
    XmlObject[] envelope = messageObject.selectChildren( soapVersion.getEnvelopeQName() );
    if( envelope.length != 1 )
      throw new XmlException( "Missing/Invalid SOAP Envelope, expecting [" + soapVersion.getEnvelopeQName() + "]" );

    XmlObject[] body = envelope[0].selectChildren( soapVersion.getBodyQName() );
    if( body.length != 1 )
      throw new XmlException( "Missing/Invalid SOAP Body, expecting [" + soapVersion.getBodyQName() + "]" );

    return body[0];
  }

  public static XmlObject getHeaderElement( XmlObject messageObject, SoapVersion soapVersion, boolean create )
      throws XmlException
  {
    XmlObject[] envelope = messageObject.selectChildren( soapVersion.getEnvelopeQName() );
    if( envelope.length != 1 )
      throw new XmlException( "Missing/Invalid SOAP Envelope, expecting [" + soapVersion.getEnvelopeQName() + "]" );

    QName headerQName = soapVersion.getHeaderQName();
    XmlObject[] header = envelope[0].selectChildren( headerQName );
    if( header.length == 0 && create )
    {
      Element elm = ( Element )envelope[0].getDomNode();
      Element headerElement = elm.getOwnerDocument().createElementNS( headerQName.getNamespaceURI(),
          headerQName.getLocalPart() );

      elm.insertBefore( headerElement, elm.getFirstChild() );

      header = envelope[0].selectChildren( headerQName );
    }

    return header.length == 0 ? null : header[0];
  }

  public static XmlObject getContentElement( XmlObject messageObject, SoapVersion soapVersion ) throws XmlException
  {
    if( messageObject == null )
      return null;

    XmlObject bodyElement = SoapUtils.getBodyElement( messageObject, soapVersion );
    if( bodyElement != null )
    {
      XmlCursor cursor = bodyElement.newCursor();

      try
      {
        if( cursor.toFirstChild() )
        {
          while( !cursor.isContainer() )
            cursor.toNextSibling();

          if( cursor.isContainer() )
          {
            return cursor.getObject();
          }
        }
      }
      catch( Exception e )
      {
        SoapUI.logError( e );
      }
      finally
      {
        cursor.dispose();
      }
    }

    return null;
  }

  @SuppressWarnings( "unchecked" )
  public static WsdlOperation findOperationForRequest( SoapVersion soapVersion, String soapAction,
      XmlObject requestContent, List<WsdlOperation> operations, boolean requireSoapVersionMatch,
      boolean requireSoapActionMatch, Attachment[] attachments ) throws Exception
  {
    XmlObject contentElm = getContentElement( requestContent, soapVersion );
    if( contentElm == null )
    {
      for( WsdlOperation operation : operations )
      {
        if( operation.getAction().equals( soapAction )
            && operation.getBindingOperation().getOperation().getInput().getMessage().getParts().size() == 0 )
        {
          return operation;
        }
      }

      return null;
    }

    QName contentQName = XmlUtils.getQName( contentElm.getDomNode() );
    NodeList contentChildNodes = null;

    for( int c = 0; c < operations.size(); c++ )
    {
      WsdlOperation wsdlOperation = operations.get( c );
      String action = wsdlOperation.getAction();

      // matches soapAction?
      if( !requireSoapActionMatch
          || ( ( soapAction == null && wsdlOperation.getAction() == null ) || ( action != null && action
              .equals( soapAction ) ) ) )
      {
        QName qname = wsdlOperation.getRequestBodyElementQName();

        if( !contentQName.equals( qname ) )
          continue;

        SoapVersion ifaceSoapVersion = wsdlOperation.getInterface().getSoapVersion();

        if( requireSoapVersionMatch && ifaceSoapVersion != soapVersion )
        {
          continue;
        }

        // check content
        if( wsdlOperation.getStyle().equals( WsdlOperation.STYLE_DOCUMENT ) )
        {
          // check that all attachments match
          BindingOperation bindingOperation = wsdlOperation.getBindingOperation();
          Message message = bindingOperation.getOperation().getInput().getMessage();
          List<Part> parts = message.getOrderedParts( null );

          for( int x = 0; x < parts.size(); x++ )
          {
            // check for attachment part
            if( WsdlUtils.isAttachmentInputPart( parts.get( x ), bindingOperation ) )
            {
              for( Attachment attachment : attachments )
              {
                if( attachment.getPart().equals( parts.get( x ).getName() ) )
                {
                  parts.remove( x );
                  x-- ;
                }
              }
            }
            else
            {
              parts.remove( x );
              x-- ;
            }
          }

          // matches!
          if( parts.isEmpty() )
          {
            return wsdlOperation;
          }
        }
        else if( wsdlOperation.getStyle().equals( WsdlOperation.STYLE_RPC ) )
        {
          BindingOperation bindingOperation = wsdlOperation.getBindingOperation();
          Message message = bindingOperation.getOperation().getInput().getMessage();
          List<Part> parts = message.getOrderedParts( null );

          if( contentChildNodes == null )
            contentChildNodes = XmlUtils.getChildElements( ( Element )contentElm.getDomNode() );

          int i = 0;

          if( parts.size() > 0 )
          {
            for( int x = 0; x < parts.size(); x++ )
            {
              if( WsdlUtils.isAttachmentInputPart( parts.get( x ), bindingOperation ) )
              {
                for( Attachment attachment : attachments )
                {
                  if( attachment.getPart().equals( parts.get( x ).getName() ) )
                  {
                    parts.remove( x );
                    x-- ;
                  }
                }
              }

              // ignore header parts for now..
              if( x >= 0 && WsdlUtils.isHeaderInputPart( parts.get( x ), message, bindingOperation ) )
              {
                parts.remove( x );
                x-- ;
              }
            }

            for( ; i < contentChildNodes.getLength() && !parts.isEmpty(); i++ )
            {
              Node item = contentChildNodes.item( i );
              if( item.getNodeType() != Node.ELEMENT_NODE )
                continue;

              int j = 0;
              while( ( j < parts.size() ) && ( !item.getNodeName().equals( parts.get( j ).getName() ) ) )
              {
                Part part = parts.get( j );
                if( part.getElementName() != null )
                {
                  QName qn = part.getElementName();
                  if( item.getLocalName().equals( qn.getLocalPart() )
                      && item.getNamespaceURI().equals( qn.getNamespaceURI() ) )
                    break;
                }
                else
                {
                  if( item.getNodeName().equals( parts.get( j ).getName() ) )
                    break;
                }

                j++ ;
              }

              if( j == parts.size() )
                break;

              parts.remove( j );
            }
          }

          // match?
          if( i == contentChildNodes.getLength() && parts.isEmpty() )
          {
            return wsdlOperation;
          }
        }
      }
    }

    throw new DispatchException( "Missing operation for soapAction [" + soapAction + "] and body element ["
        + contentQName + "] with SOAP Version [" + soapVersion + "]" );
  }

  @SuppressWarnings( "unchecked" )
  public static WsdlOperation findOperationForResponse( SoapVersion soapVersion, String soapAction,
      XmlObject responseContent, List<WsdlOperation> operations, boolean requireSoapVersionMatch,
      boolean requireSoapActionMatch ) throws Exception
  {
    XmlObject contentElm = getContentElement( responseContent, soapVersion );
    if( contentElm == null )
      return null;

    QName contentQName = XmlUtils.getQName( contentElm.getDomNode() );
    NodeList contentChildNodes = null;

    for( int c = 0; c < operations.size(); c++ )
    {
      WsdlOperation wsdlOperation = operations.get( c );
      String action = wsdlOperation.getAction();

      // matches soapAction?
      if( !requireSoapActionMatch
          || ( ( soapAction == null && wsdlOperation.getAction() == null ) || ( action != null && action
              .equals( soapAction ) ) ) )
      {
        QName qname = wsdlOperation.getResponseBodyElementQName();

        if( !contentQName.equals( qname ) )
          continue;

        SoapVersion ifaceSoapVersion = wsdlOperation.getInterface().getSoapVersion();

        if( requireSoapVersionMatch && ifaceSoapVersion != soapVersion )
        {
          continue;
        }

        // check content
        if( wsdlOperation.getStyle().equals( WsdlOperation.STYLE_DOCUMENT ) )
        {
          // matches!
          return wsdlOperation;
        }
        else if( wsdlOperation.getStyle().equals( WsdlOperation.STYLE_RPC ) )
        {
          BindingOperation bindingOperation = wsdlOperation.getBindingOperation();
          Message message = bindingOperation.getOperation().getOutput().getMessage();
          List<Part> parts = message.getOrderedParts( null );

          if( contentChildNodes == null )
            contentChildNodes = XmlUtils.getChildElements( ( Element )contentElm.getDomNode() );

          int i = 0;

          if( parts.size() > 0 )
          {
            for( int x = 0; x < parts.size(); x++ )
            {
              if( WsdlUtils.isAttachmentOutputPart( parts.get( x ), bindingOperation )
                  || WsdlUtils.isHeaderOutputPart( parts.get( x ), message, bindingOperation ) )
              {
                parts.remove( x );
                x-- ;
              }
            }

            for( ; i < contentChildNodes.getLength() && !parts.isEmpty(); i++ )
            {
              Node item = contentChildNodes.item( i );
              if( item.getNodeType() != Node.ELEMENT_NODE )
                continue;

              int j = 0;
              while( ( j < parts.size() ) && ( !item.getNodeName().equals( parts.get( j ).getName() ) ) )
              {
                Part part = parts.get( j );
                if( part.getElementName() != null )
                {
                  QName qn = part.getElementName();
                  if( item.getLocalName().equals( qn.getLocalPart() )
                      && item.getNamespaceURI().equals( qn.getNamespaceURI() ) )
                    break;
                }
                else
                {
                  if( item.getNodeName().equals( parts.get( j ).getName() ) )
                    break;
                }

                j++ ;
              }

              if( j == parts.size() )
                break;

              parts.remove( j );
            }
          }

          // match?
          if( i == contentChildNodes.getLength() && parts.isEmpty() )
          {
            return wsdlOperation;
          }
        }
      }
    }

    throw new DispatchException( "Missing response operation for soapAction [" + soapAction + "] and body element ["
        + contentQName + "] with SOAP Version [" + soapVersion + "]" );
  }

  public static String removeEmptySoapHeaders( String content, SoapVersion soapVersion ) throws XmlException
  {
    // XmlObject xmlObject = XmlObject.Factory.parse( content );
    XmlObject xmlObject = XmlUtils.createXmlObject( content );
    XmlObject[] selectPath = xmlObject.selectPath( "declare namespace soap='" + soapVersion.getEnvelopeNamespace()
        + "';/soap:Envelope/soap:Header" );
    if( selectPath.length > 0 )
    {
      Node domNode = selectPath[0].getDomNode();
      if( !domNode.hasChildNodes() && !domNode.hasAttributes() )
      {
        domNode.getParentNode().removeChild( domNode );
        return xmlObject.xmlText();
      }
    }

    return content;
  }

  public static SoapVersion deduceSoapVersion( String requestContentType, String requestContent )
  {
    try
    {
      // return deduceSoapVersion( requestContentType,
      // XmlObject.Factory.parse( requestContent ) );
      return deduceSoapVersion( requestContentType, XmlUtils.createXmlObject( requestContent ) );
    }
    catch( XmlException e )
    {
      return deduceSoapVersion( requestContentType, ( XmlObject )null );
    }
  }

  public static String transferSoapHeaders( String requestContent, String newRequest, SoapVersion soapVersion )
  {
    try
    {
      // XmlObject source = XmlObject.Factory.parse( requestContent );
      XmlObject source = XmlUtils.createXmlObject( requestContent );
      String headerXPath = "declare namespace ns='" + soapVersion.getEnvelopeNamespace() + "'; //ns:Header";
      XmlObject[] header = source.selectPath( headerXPath );
      if( header.length == 1 )
      {
        Element headerElm = ( Element )header[0].getDomNode();
        NodeList childNodes = headerElm.getChildNodes();
        if( childNodes.getLength() > 0 )
        {
          // XmlObject dest = XmlObject.Factory.parse( newRequest );
          XmlObject dest = XmlUtils.createXmlObject( newRequest );
          header = dest.selectPath( headerXPath );
          Element destElm = null;

          if( header.length == 0 )
          {
            Element docElm = ( ( Document )dest.getDomNode() ).getDocumentElement();

            destElm = ( Element )docElm.insertBefore(
                docElm.getOwnerDocument().createElementNS( soapVersion.getEnvelopeNamespace(),
                    docElm.getPrefix() + ":Header" ),
                XmlUtils.getFirstChildElementNS( docElm, soapVersion.getBodyQName() ) );
          }
          else
          {
            destElm = ( Element )header[0].getDomNode();
          }

          for( int c = 0; c < childNodes.getLength(); c++ )
          {
            Node childNode = childNodes.item( c );
            if( childNode.getNodeType() == Node.ELEMENT_NODE )
            {
              if( XmlUtils.getFirstChildElementNS( destElm, childNode.getNamespaceURI(),
                  childNode.getLocalName() ) != null )
                continue;

              destElm.appendChild( destElm.getOwnerDocument().importNode( childNode, true ) );
            }
          }

          return dest.xmlText();
        }
      }
    }
    catch( XmlException e )
    {
      SoapUI.logError( e );
    }

    return newRequest;
  }
}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.support.soap.SoapUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.