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

Source Code of com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils

/*
*  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.wsdl;

import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.AttributeExtensible;
import javax.wsdl.extensions.ElementExtensible;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.ExtensionDeserializer;
import javax.wsdl.extensions.ExtensionRegistry;
import javax.wsdl.extensions.UnknownExtensibilityElement;
import javax.wsdl.extensions.mime.MIMEContent;
import javax.wsdl.extensions.mime.MIMEMultipartRelated;
import javax.wsdl.extensions.mime.MIMEPart;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPFault;
import javax.wsdl.extensions.soap.SOAPHeader;
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.wsdl.extensions.soap12.SOAP12Address;
import javax.wsdl.extensions.soap12.SOAP12Binding;
import javax.wsdl.extensions.soap12.SOAP12Body;
import javax.wsdl.extensions.soap12.SOAP12Fault;
import javax.wsdl.extensions.soap12.SOAP12Header;
import javax.wsdl.extensions.soap12.SOAP12Operation;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;

import org.apache.log4j.Logger;
import org.apache.xmlbeans.SchemaGlobalElement;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlString;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.AnonymousTypeConfig;
import com.eviware.soapui.config.DefinitionCacheConfig;
import com.eviware.soapui.config.DefinitionCacheTypeConfig;
import com.eviware.soapui.config.DefintionPartConfig;
import com.eviware.soapui.config.WsaVersionTypeConfig;
import com.eviware.soapui.impl.support.definition.DefinitionLoader;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.WsdlRequest;
import com.eviware.soapui.impl.wsdl.submit.WsdlMessageExchange;
import com.eviware.soapui.impl.wsdl.support.Constants;
import com.eviware.soapui.impl.wsdl.support.policy.PolicyUtils;
import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
import com.eviware.soapui.impl.wsdl.support.wsa.WsaConfig;
import com.eviware.soapui.impl.wsdl.support.wsa.WsaUtils;
import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
import com.eviware.soapui.settings.WsaSettings;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.types.StringList;
import com.eviware.soapui.support.xml.XmlUtils;
import com.ibm.wsdl.util.xml.QNameUtils;
import com.ibm.wsdl.xml.WSDLReaderImpl;
import com.ibm.wsdl.xml.WSDLWriterImpl;

/**
* Wsdl-related tools
*
* @author Ole.Matzura
*/

public class WsdlUtils
{
  private final static Logger log = Logger.getLogger( WsdlUtils.class );
  private static WSDLReader wsdlReader;
  private final static String WSDL_NAMESPACE = "http://schemas.xmlsoap.org/wsdl/";

  public static <T extends ExtensibilityElement> T getExtensiblityElement( List<?> list, Class<T> clazz )
  {
    List<T> elements = getExtensiblityElements( list, clazz );
    return elements.isEmpty() ? null : elements.get( 0 );
  }

  public static <T extends ExtensibilityElement> List<T> getExtensiblityElements( List list, Class<T> clazz )
  {
    List<T> result = new ArrayList<T>();

    for( Iterator<T> i = list.iterator(); i.hasNext(); )
    {
      T elm = i.next();
      if( clazz.isAssignableFrom( elm.getClass() ) )
      {
        result.add( elm );
      }
    }

    return result;
  }

  public static Element[] getExentsibilityElements( ElementExtensible item, QName qname )
  {
    if( item == null )
      return new Element[0];

    List<Element> result = new ArrayList<Element>();

    List<?> list = item.getExtensibilityElements();
    for( Iterator<?> i = list.iterator(); i.hasNext(); )
    {
      ExtensibilityElement elm = ( ExtensibilityElement )i.next();
      if( elm.getElementType().equals( qname ) && elm instanceof UnknownExtensibilityElement )
      {
        result.add( ( ( UnknownExtensibilityElement )elm ).getElement() );
      }
    }

    return result.toArray( new Element[result.size()] );
  }

  public static String[] getExentsibilityAttributes( AttributeExtensible item, QName qname )
  {
    if( item == null )
      return new String[0];

    StringList result = new StringList();

    Map map = item.getExtensionAttributes();

    for( Iterator<?> i = map.keySet().iterator(); i.hasNext(); )
    {
      QName name = ( QName )i.next();
      if( name.equals( qname ) )
      {
        result.add( map.get( name ).toString() );
      }
    }

    return result.toStringArray();
  }

  public static String getSoapAction( BindingOperation operation )
  {
    List list = operation.getExtensibilityElements();
    SOAPOperation soapOperation = WsdlUtils.getExtensiblityElement( list, SOAPOperation.class );
    if( soapOperation != null )
      return soapOperation.getSoapActionURI();

    SOAP12Operation soap12Operation = WsdlUtils.getExtensiblityElement( list, SOAP12Operation.class );
    if( soap12Operation != null )
      return soap12Operation.getSoapActionURI();

    return null;
  }

  public static String[] getEndpointsForBinding( Definition definition, Binding binding )
  {
    List<String> result = new ArrayList<String>();
    Map map = definition.getAllServices();
    for( Iterator i = map.values().iterator(); i.hasNext(); )
    {
      Service service = ( Service )i.next();
      Map portMap = service.getPorts();
      for( Iterator i2 = portMap.values().iterator(); i2.hasNext(); )
      {
        Port port = ( Port )i2.next();
        if( port.getBinding() == binding )
        {
          String endpoint = WsdlUtils.getSoapEndpoint( port );
          if( endpoint != null )
            result.add( endpoint );
        }
      }
    }

    return result.toArray( new String[result.size()] );
  }

  public static Binding findBindingForOperation( Definition definition, BindingOperation bindingOperation )
  {
    Map services = definition.getAllServices();
    Iterator<Service> s = services.values().iterator();

    while( s.hasNext() )
    {
      Map ports = s.next().getPorts();
      Iterator<Port> p = ports.values().iterator();
      while( p.hasNext() )
      {
        Binding binding = p.next().getBinding();
        List bindingOperations = binding.getBindingOperations();
        for( Iterator iter = bindingOperations.iterator(); iter.hasNext(); )
        {
          BindingOperation op = ( BindingOperation )iter.next();
          if( op.getName().equals( bindingOperation.getName() ) )
            return binding;
        }
      }
    }

    Map bindings = definition.getAllBindings();
    Iterator<QName> names = bindings.keySet().iterator();
    while( names.hasNext() )
    {
      Binding binding = definition.getBinding( names.next() );
      List bindingOperations = binding.getBindingOperations();
      for( Iterator iter = bindingOperations.iterator(); iter.hasNext(); )
      {
        BindingOperation op = ( BindingOperation )iter.next();
        if( op.getName().equals( bindingOperation.getName() ) )
          return binding;
      }
    }

    return null;
  }

  public static BindingOperation findBindingOperation( Definition definition, String operationName )
  {
    Map services = definition.getAllServices();
    for( Iterator i = services.keySet().iterator(); i.hasNext(); )
    {
      QName qName = ( QName )i.next();
      Service service = definition.getService( qName );
      Map ports = service.getPorts();

      for( Iterator iterator = ports.keySet().iterator(); iterator.hasNext(); )
      {
        String key = ( String )iterator.next();
        Port port = service.getPort( key );
        BindingOperation bindingOperation = port.getBinding().getBindingOperation( operationName, null, null );
        if( bindingOperation != null )
          return bindingOperation;
      }
    }

    Map bindings = definition.getAllBindings();
    for( Iterator i = bindings.keySet().iterator(); i.hasNext(); )
    {
      Object key = i.next();
      Binding binding = ( Binding )bindings.get( key );
      BindingOperation bindingOperation = binding.getBindingOperation( operationName, null, null );
      if( bindingOperation != null )
        return bindingOperation;
    }

    return null;
  }

  public static boolean isInputSoapEncoded( BindingOperation bindingOperation )
  {
    if( bindingOperation == null )
      return false;

    BindingInput bindingInput = bindingOperation.getBindingInput();
    if( bindingInput == null )
      return false;

    SOAPBody soapBody = WsdlUtils.getExtensiblityElement( bindingInput.getExtensibilityElements(), SOAPBody.class );

    if( soapBody != null )
    {
      return soapBody.getUse() != null
          && soapBody.getUse().equalsIgnoreCase( "encoded" )
          && ( soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains(
              "http://schemas.xmlsoap.org/soap/encoding/" ) );
    }

    SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( bindingInput.getExtensibilityElements(),
        SOAP12Body.class );

    if( soap12Body != null )
    {
      return soap12Body.getUse() != null
          && soap12Body.getUse().equalsIgnoreCase( "encoded" )
          && ( soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals(
              "http://schemas.xmlsoap.org/soap/encoding/" ) );
    }

    return false;
  }

  public static boolean isOutputSoapEncoded( BindingOperation bindingOperation )
  {
    if( bindingOperation == null )
      return false;

    BindingOutput bindingOutput = bindingOperation.getBindingOutput();
    if( bindingOutput == null )
      return false;

    SOAPBody soapBody = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(), SOAPBody.class );

    if( soapBody != null )
    {
      return soapBody.getUse() != null
          && soapBody.getUse().equalsIgnoreCase( "encoded" )
          && ( soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains(
              "http://schemas.xmlsoap.org/soap/encoding/" ) );
    }

    SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(),
        SOAP12Body.class );

    if( soap12Body != null )
    {
      return soap12Body.getUse() != null
          && soap12Body.getUse().equalsIgnoreCase( "encoded" )
          && ( soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals(
              "http://schemas.xmlsoap.org/soap/encoding/" ) );
    }

    return false;
  }

  public static boolean isRpc( Definition definition, BindingOperation bindingOperation )
  {
    SOAPOperation soapOperation = WsdlUtils.getExtensiblityElement( bindingOperation.getExtensibilityElements(),
        SOAPOperation.class );

    if( soapOperation != null && soapOperation.getStyle() != null )
      return soapOperation.getStyle().equalsIgnoreCase( "rpc" );

    SOAP12Operation soap12Operation = WsdlUtils.getExtensiblityElement( bindingOperation.getExtensibilityElements(),
        SOAP12Operation.class );

    if( soap12Operation != null && soap12Operation.getStyle() != null )
      return soap12Operation.getStyle().equalsIgnoreCase( "rpc" );

    Binding binding = findBindingForOperation( definition, bindingOperation );
    if( binding == null )
    {
      log.error( "Failed to find binding for operation [" + bindingOperation.getName() + "] in definition ["
          + definition.getDocumentBaseURI() + "]" );
      return false;
    }

    return isRpc( binding );
  }

  public static boolean isRpc( Binding binding )
  {
    SOAPBinding soapBinding = WsdlUtils
        .getExtensiblityElement( binding.getExtensibilityElements(), SOAPBinding.class );

    if( soapBinding != null )
      return "rpc".equalsIgnoreCase( soapBinding.getStyle() );

    SOAP12Binding soap12Binding = WsdlUtils.getExtensiblityElement( binding.getExtensibilityElements(),
        SOAP12Binding.class );

    if( soap12Binding != null )
      return "rpc".equalsIgnoreCase( soap12Binding.getStyle() );

    return false;
  }

  /**
   * Returns a list of parts for the specifed operation, either as specified in
   * body or all
   */

  public static Part[] getInputParts( BindingOperation operation )
  {
    List<Part> result = new ArrayList<Part>();
    Input input = operation.getOperation().getInput();
    if( input == null || operation.getBindingInput() == null )
      return new Part[0];

    Message msg = input.getMessage();

    if( msg != null )
    {
      SOAPBody soapBody = WsdlUtils.getExtensiblityElement( operation.getBindingInput().getExtensibilityElements(),
          SOAPBody.class );

      if( soapBody == null || soapBody.getParts() == null )
      {
        SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( operation.getBindingInput()
            .getExtensibilityElements(), SOAP12Body.class );

        if( soap12Body == null || soap12Body.getParts() == null )
        {
          if( msg != null )
            result.addAll( msg.getOrderedParts( null ) );
        }
        else
        {
          Iterator i = soap12Body.getParts().iterator();
          while( i.hasNext() )
          {
            String partName = ( String )i.next();
            Part part = msg.getPart( partName );

            result.add( part );
          }
        }
      }
      else
      {
        Iterator i = soapBody.getParts().iterator();
        while( i.hasNext() )
        {
          String partName = ( String )i.next();
          Part part = msg.getPart( partName );

          result.add( part );
        }
      }
    }
    else
    {
    }

    return result.toArray( new Part[result.size()] );
  }

  public static boolean isAttachmentInputPart( Part part, BindingOperation operation )
  {
    return getInputMultipartContent( part, operation ).length > 0;
  }

  public static boolean isAttachmentOutputPart( Part part, BindingOperation operation )
  {
    return getOutputMultipartContent( part, operation ).length > 0;
  }

  public static MIMEContent[] getOutputMultipartContent( Part part, BindingOperation operation )
  {
    BindingOutput output = operation.getBindingOutput();
    if( output == null )
      return new MIMEContent[0];

    MIMEMultipartRelated multipartOutput = WsdlUtils.getExtensiblityElement( output.getExtensibilityElements(),
        MIMEMultipartRelated.class );

    return getContentParts( part, multipartOutput );
  }

  public static MIMEContent[] getInputMultipartContent( Part part, BindingOperation operation )
  {
    BindingInput bindingInput = operation.getBindingInput();
    if( bindingInput == null )
      return new MIMEContent[0];

    MIMEMultipartRelated multipartInput = WsdlUtils.getExtensiblityElement( bindingInput.getExtensibilityElements(),
        MIMEMultipartRelated.class );

    return getContentParts( part, multipartInput );
  }

  public static MIMEContent[] getContentParts( Part part, MIMEMultipartRelated multipart )
  {
    List<MIMEContent> result = new ArrayList<MIMEContent>();

    if( multipart != null )
    {
      List<MIMEPart> parts = multipart.getMIMEParts();

      for( int c = 0; c < parts.size(); c++ )
      {
        List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get( c )
            .getExtensibilityElements(), MIMEContent.class );

        for( MIMEContent content : contentParts )
        {
          if( content.getPart().equals( part.getName() ) )
            result.add( content );
        }
      }
    }

    return result.toArray( new MIMEContent[result.size()] );
  }

  public static Part[] getFaultParts( BindingOperation bindingOperation, String faultName ) throws Exception
  {
    List<Part> result = new ArrayList<Part>();

    BindingFault bindingFault = bindingOperation.getBindingFault( faultName );
    SOAPFault soapFault = WsdlUtils.getExtensiblityElement( bindingFault.getExtensibilityElements(), SOAPFault.class );

    Operation operation = bindingOperation.getOperation();
    if( soapFault != null && soapFault.getName() != null )
    {
      Fault fault = operation.getFault( soapFault.getName() );
      if( fault == null )
        throw new Exception( "Missing Fault [" + soapFault.getName() + "] in operation [" + operation.getName()
            + "]" );
      result.addAll( fault.getMessage().getOrderedParts( null ) );
    }
    else
    {
      SOAP12Fault soap12Fault = WsdlUtils.getExtensiblityElement( bindingFault.getExtensibilityElements(),
          SOAP12Fault.class );

      if( soap12Fault != null && soap12Fault.getName() != null )
      {
        result.addAll( operation.getFault( soap12Fault.getName() ).getMessage().getOrderedParts( null ) );
      }
      else
      {
        result.addAll( operation.getFault( faultName ).getMessage().getOrderedParts( null ) );
      }
    }

    return result.toArray( new Part[result.size()] );
  }

  public static String findSoapFaultPartName( SoapVersion soapVersion, BindingOperation bindingOperation,
      String message ) throws Exception
  {
    if( WsdlUtils.isOutputSoapEncoded( bindingOperation ) )
      throw new Exception( "SOAP-Encoded messages not supported" );

    // XmlObject xml = XmlObject.Factory.parse( message );
    XmlObject xml = XmlUtils.createXmlObject( message );
    XmlObject[] msgPaths = xml.selectPath( "declare namespace env='" + soapVersion.getEnvelopeNamespace() + "';"
        + "$this/env:Envelope/env:Body/env:Fault" );
    if( msgPaths.length == 0 )
      return null;

    XmlObject msgXml = msgPaths[0];

    Map faults = bindingOperation.getBindingFaults();
    for( Iterator<BindingFault> i = faults.values().iterator(); i.hasNext(); )
    {
      BindingFault bindingFault = i.next();
      String faultName = bindingFault.getName();
      Part[] faultParts = WsdlUtils.getFaultParts( bindingOperation, faultName );
      Part part = faultParts[0];

      QName elementName = part.getElementName();
      if( elementName != null )
      {
        XmlObject[] faultPaths = msgXml.selectPath( "declare namespace env='" + soapVersion.getEnvelopeNamespace()
            + "';" + "declare namespace ns='" + elementName.getNamespaceURI() + "';" + "//env:Fault/detail/ns:"
            + elementName.getLocalPart() );

        if( faultPaths.length == 1 )
          return faultName;
      }
      // this is not allowed by Basic Profile.. remove?
      else if( part.getTypeName() != null )
      {
        QName typeName = part.getTypeName();
        XmlObject[] faultPaths = msgXml.selectPath( "declare namespace env='" + soapVersion.getEnvelopeNamespace()
            + "';" + "declare namespace ns='" + typeName.getNamespaceURI() + "';" + "//env:Fault/detail/ns:"
            + part.getName() );

        if( faultPaths.length == 1 )
          return faultName;
      }
    }

    return null;
  }

  public static Part[] getOutputParts( BindingOperation operation )
  {
    BindingOutput bindingOutput = operation.getBindingOutput();
    if( bindingOutput == null )
      return new Part[0];

    List<Part> result = new ArrayList<Part>();
    Output output = operation.getOperation().getOutput();
    if( output == null )
      return new Part[0];

    Message msg = output.getMessage();
    if( msg != null )
    {
      SOAPBody soapBody = WsdlUtils
          .getExtensiblityElement( bindingOutput.getExtensibilityElements(), SOAPBody.class );

      if( soapBody == null || soapBody.getParts() == null )
      {
        SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(),
            SOAP12Body.class );

        if( soap12Body == null || soap12Body.getParts() == null )
        {
          result.addAll( msg.getOrderedParts( null ) );
        }
        else
        {
          Iterator i = soap12Body.getParts().iterator();
          while( i.hasNext() )
          {
            String partName = ( String )i.next();
            Part part = msg.getPart( partName );

            result.add( part );
          }
        }
      }
      else
      {
        Iterator i = soapBody.getParts().iterator();
        while( i.hasNext() )
        {
          String partName = ( String )i.next();
          Part part = msg.getPart( partName );

          result.add( part );
        }
      }
    }
    else
    {
      log.warn( "Missing output message for binding operation [" + operation.getName() + "]" );
    }

    return result.toArray( new Part[result.size()] );
  }

  public static boolean isMultipartRequest( Definition definition, BindingOperation bindingOperation )
  {
    return WsdlUtils.getExtensiblityElement( bindingOperation.getBindingInput().getExtensibilityElements(),
        MIMEMultipartRelated.class ) != null;
  }

  public static String getUsingAddressing( ElementExtensible item )
  {
    String version = WsaVersionTypeConfig.NONE.toString();

    Element[] usingAddressingElements = WsdlUtils.getExentsibilityElements( item, new QName(
        "http://www.w3.org/2006/05/addressing/wsdl", "UsingAddressing" ) );
    if( usingAddressingElements.length == 0 )
    {
      usingAddressingElements = WsdlUtils.getExentsibilityElements( item, new QName(
          "http://www.w3.org/2006/02/addressing/wsdl", "UsingAddressing" ) );
    }

    if( usingAddressingElements.length != 0 )
    {
      // this should resolve wsdl version, not addressing version??? what is
      // the connection?
      String addressingVersion = usingAddressingElements[0].getAttributeNS( WSDL_NAMESPACE, "required" );
      if( addressingVersion != null && addressingVersion.equals( "true" ) )
      {
        version = WsaVersionTypeConfig.X_200508.toString();
      }

    }
    return version;
  }

  private static String checkIfWsaPolicy( String version, Element policy )
  {
    // Policy builtPolicy = new
    // WsaPolicy().buildPolicy(policy.getTextContent());
    // policy = WsaPolicy.normalize(policy);

    // check if found reference is addressing policy
    // Element wsAddressing = XmlUtils.getFirstChildElementNS(policy,
    // WsaUtils.WSAM_NAMESPACE, "Addressing");
    // Element addressingPolicy = null;
    // if (wsAddressing != null)
    // {
    // String optional =
    // wsAddressing.getAttributeNS(WsaPolicy.WS_POLICY_NAMESPACE, "Optional");
    // addressingPolicy = XmlUtils.getFirstChildElementNS(wsAddressing,
    // WsaPolicy.WS_POLICY_NAMESPACE, "Policy");
    // if (addressingPolicy != null)
    // {
    // if (StringUtils.isNullOrEmpty(optional) || optional.equals("false") ||
    // (optional.equals("true") &&
    // SoapUI.getSettings().getBoolean(WsaSettings.ENABLE_FOR_OPTIONAL)) )
    // {
    // version = WsaVersionTypeConfig.X_200508.toString();
    // }
    // //check if policy has Anonymous
    // Element anonymousElm =
    // XmlUtils.getFirstChildElementNS(addressingPolicy, new
    // QName(WsaPolicy.WSAM_NAMESPACE,"AnonymousResponses"));
    // if (anonymousElm != null)
    // {
    // //TODO anonymous = required
    // } else {
    // Element nonAnonymousElement =
    // XmlUtils.getFirstChildElementNS(addressingPolicy, new
    // QName(WsaPolicy.WSAM_NAMESPACE,"NonAnonymousResponses"));
    // if (nonAnonymousElement != null)
    // {
    // //TODO anonymous = prohibited
    // }
    // }
    // }
    // }
    return version;
  }

  public static String getWsaPolicyAnonymous( Element policy )
  {
    String version = WsaVersionTypeConfig.NONE.toString();
    String anonymous = AnonymousTypeConfig.OPTIONAL.toString();
    // check if found reference is addressing policy
    Element wsAddressing = XmlUtils.getFirstChildElementNS( policy, WsaUtils.WS_A_NAMESPACE_200705, "Addressing" );
    Element addressingPolicy = null;
    if( wsAddressing != null )
    {
      String optional = wsAddressing.getAttributeNS( PolicyUtils.WS_W3_POLICY_NAMESPACE, "Optional" );
      addressingPolicy = XmlUtils
          .getFirstChildElementNS( wsAddressing, PolicyUtils.WS_W3_POLICY_NAMESPACE, "Policy" );
      if( addressingPolicy != null )
      {
        if( StringUtils.isNullOrEmpty( optional ) || optional.equals( "false" )
            || ( optional.equals( "true" ) && SoapUI.getSettings().getBoolean( WsaSettings.ENABLE_FOR_OPTIONAL ) ) )
        {
          version = WsaVersionTypeConfig.X_200508.toString();
        }
        // check if policy has Anonymous
        Element anonymousElm = XmlUtils.getFirstChildElementNS( addressingPolicy, new QName(
            WsaUtils.WS_A_NAMESPACE_200705, "AnonymousResponses" ) );
        if( anonymousElm != null )
        {
          anonymous = AnonymousTypeConfig.REQUIRED.toString();
        }
        else
        {
          Element nonAnonymousElement = XmlUtils.getFirstChildElementNS( addressingPolicy, new QName(
              WsaUtils.WS_A_NAMESPACE_200705, "NonAnonymousResponses" ) );
          if( nonAnonymousElement != null )
          {
            anonymous = AnonymousTypeConfig.PROHIBITED.toString();
          }
        }
      }
    }
    return anonymous;
  }

  public static String getSoapEndpoint( Port port )
  {
    SOAPAddress soapAddress = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
    if( soapAddress != null && StringUtils.hasContent( soapAddress.getLocationURI() ) )
    {
      try
      {
        return URLDecoder.decode( soapAddress.getLocationURI(), "UTF-8" );
      }
      catch( UnsupportedEncodingException e )
      {
        e.printStackTrace();
        return soapAddress.getLocationURI();
      }
    }

    SOAP12Address soap12Address = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(),
        SOAP12Address.class );
    if( soap12Address != null && StringUtils.hasContent( soap12Address.getLocationURI() ) )
    {
      try
      {
        return URLDecoder.decode( soap12Address.getLocationURI(), "UTF-8" );
      }
      catch( UnsupportedEncodingException e )
      {
        e.printStackTrace();
        return soap12Address.getLocationURI();
      }
    }

    return null;
  }

  public static boolean replaceSoapEndpoint( Port port, String endpoint )
  {
    SOAPAddress soapAddress = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
    if( soapAddress != null )
    {
      soapAddress.setLocationURI( endpoint );
      return true;
    }

    SOAP12Address soap12Address = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(),
        SOAP12Address.class );
    if( soap12Address != null )
    {
      soap12Address.setLocationURI( endpoint );
      return true;
    }

    return false;
  }

  public static String getSoapBodyNamespace( List<?> list )
  {
    SOAPBody soapBody = WsdlUtils.getExtensiblityElement( list, SOAPBody.class );
    if( soapBody != null )
      return soapBody.getNamespaceURI();

    SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( list, SOAP12Body.class );
    if( soap12Body != null )
      return soap12Body.getNamespaceURI();

    return null;
  }

  public static final class NonSchemaImportingWsdlReaderImpl extends WSDLReaderImpl
  {
    @SuppressWarnings( "unchecked" )
    @Override
    protected ExtensibilityElement parseSchema( Class parentType, Element el, Definition def, ExtensionRegistry extReg )
        throws WSDLException
    {
      QName elementType = QNameUtils.newQName( el );

      ExtensionDeserializer exDS = extReg.queryDeserializer( parentType, elementType );

      // Now unmarshall the DOM element.
      ExtensibilityElement ee = exDS.unmarshall( parentType, elementType, el, def, extReg );

      return ee;
    }

  }

  /**
   * A SOAP-Header wrapper
   *
   * @author ole.matzura
   */

  public interface SoapHeader
  {
    public QName getMessage();

    public String getPart();
  }

  /**
   * SOAP 1.1 Header implementation
   *
   * @author ole.matzura
   */

  public static class Soap11Header implements SoapHeader
  {
    private final SOAPHeader soapHeader;

    public Soap11Header( SOAPHeader soapHeader )
    {
      this.soapHeader = soapHeader;
    }

    public QName getMessage()
    {
      return soapHeader.getMessage();
    }

    public String getPart()
    {
      return soapHeader.getPart();
    }
  }

  /**
   * SOAP 1.2 Header implementation
   *
   * @author ole.matzura
   */

  public static class Soap12Header implements SoapHeader
  {
    private final SOAP12Header soapHeader;

    public Soap12Header( SOAP12Header soapHeader )
    {
      this.soapHeader = soapHeader;
    }

    public QName getMessage()
    {
      return soapHeader.getMessage();
    }

    public String getPart()
    {
      return soapHeader.getPart();
    }
  }

  public static List<SoapHeader> getSoapHeaders( List list )
  {
    List<SoapHeader> result = new ArrayList<SoapHeader>();

    List<SOAPHeader> soapHeaders = WsdlUtils.getExtensiblityElements( list, SOAPHeader.class );
    if( soapHeaders != null && !soapHeaders.isEmpty() )
    {
      for( SOAPHeader header : soapHeaders )
        result.add( new Soap11Header( header ) );
    }
    else
    {
      List<SOAP12Header> soap12Headers = WsdlUtils.getExtensiblityElements( list, SOAP12Header.class );
      if( soap12Headers != null && !soap12Headers.isEmpty() )
      {
        for( SOAP12Header header : soap12Headers )
          result.add( new Soap12Header( header ) );
      }
    }

    return result;
  }

  public static synchronized Definition readDefinition( String wsdlUrl ) throws Exception
  {
    if( wsdlReader == null )
    {
      WSDLFactory factory = WSDLFactory.newInstance();
      wsdlReader = factory.newWSDLReader();
      wsdlReader.setFeature( "javax.wsdl.verbose", true );
      wsdlReader.setFeature( "javax.wsdl.importDocuments", true );
    }

    return wsdlReader.readWSDL( new UrlWsdlLoader( wsdlUrl ) );
  }

  public static SchemaType getSchemaTypeForPart( WsdlContext wsdlContext, javax.wsdl.Part part ) throws Exception
  {
    SchemaType schemaType = null;
    QName elementName = part.getElementName();

    if( elementName != null )
    {
      SchemaGlobalElement elm = wsdlContext.getSchemaTypeLoader().findElement( elementName );
      if( elm != null )
      {
        schemaType = elm.getType();
      }
      else
        WsdlRequest.log.error( "Could not find element [" + elementName + "] specified in part [" + part.getName()
            + "]" );
    }
    else
    {
      QName typeName = part.getTypeName();

      if( typeName != null )
      {
        schemaType = wsdlContext.getSchemaTypeLoader().findType( typeName );

        if( schemaType == null )
        {
          WsdlRequest.log.error( "Could not find type [" + typeName + "] specified in part [" + part.getName()
              + "]" );
        }
      }
    }
    return schemaType;
  }

  public static SchemaGlobalElement getSchemaElementForPart( WsdlContext wsdlContext, javax.wsdl.Part part )
      throws Exception
  {
    QName elementName = part.getElementName();

    if( elementName != null )
    {
      return wsdlContext.getSchemaTypeLoader().findElement( elementName );
    }

    return null;
  }

  public static String replacePortEndpoint( WsdlInterface iface, InputSource inputSource, String endpoint )
      throws WSDLException
  {
    WSDLReader wsdlReader = new NonSchemaImportingWsdlReaderImpl();

    wsdlReader.setFeature( "javax.wsdl.verbose", true );
    wsdlReader.setFeature( "javax.wsdl.importDocuments", false );

    Definition definition = wsdlReader.readWSDL( null, inputSource );

    boolean updated = false;
    Map map = definition.getServices();
    for( Iterator i = map.values().iterator(); i.hasNext(); )
    {
      Service service = ( Service )i.next();
      Map portMap = service.getPorts();
      for( Iterator i2 = portMap.values().iterator(); i2.hasNext(); )
      {
        Port port = ( Port )i2.next();
        if( port.getBinding().getQName().equals( iface.getBindingName() ) )
        {
          if( replaceSoapEndpoint( port, endpoint ) )
            updated = true;
        }
      }
    }

    if( updated )
    {
      StringWriter writer = new StringWriter();

      Map nsMap = definition.getNamespaces();
      if( !nsMap.values().contains( Constants.SOAP_HTTP_BINDING_NS ) )
        definition.addNamespace( "soaphttp", Constants.SOAP_HTTP_BINDING_NS );

      new WSDLWriterImpl().writeWSDL( definition, writer );
      return writer.toString();
    }

    return null;
  }

  public static BindingOperation findBindingOperation( Binding binding, String bindingOperationName, String inputName,
      String outputName )
  {
    if( binding == null )
      return null;

    if( inputName == null )
      inputName = ":none";

    if( outputName == null )
      outputName = ":none";

    BindingOperation result = binding.getBindingOperation( bindingOperationName, inputName, outputName );

    if( result == null && ( inputName.equals( ":none" ) || outputName.equals( ":none" ) ) )
    {
      // fall back to this behaviour for WSDL4j 1.5.0 compatibility
      result = binding.getBindingOperation( bindingOperationName, inputName.equals( ":none" ) ? null : inputName,
          outputName.equals( ":none" ) ? null : outputName );
    }
    return result;
  }

  public static boolean isHeaderInputPart( Part part, Message message, BindingOperation bindingOperation )
  {
    List<SOAPHeader> headers = WsdlUtils.getExtensiblityElements( bindingOperation.getBindingInput()
        .getExtensibilityElements(), SOAPHeader.class );

    if( headers == null || headers.isEmpty() )
      return false;

    for( SOAPHeader header : headers )
    {
      if( message.getQName().equals( header.getMessage() ) && part.getName().equals( header.getPart() ) )
        return true;
    }

    return false;
  }

  public static boolean isHeaderOutputPart( Part part, Message message, BindingOperation bindingOperation )
  {
    BindingOutput bindingOutput = bindingOperation.getBindingOutput();
    List<SOAPHeader> headers = bindingOutput == null ? null : WsdlUtils.getExtensiblityElements(
        bindingOutput.getExtensibilityElements(), SOAPHeader.class );

    if( headers == null || headers.isEmpty() )
      return false;

    for( SOAPHeader header : headers )
    {
      if( message.getQName().equals( header.getMessage() ) && part.getName().equals( header.getPart() ) )
        return true;
    }

    return false;
  }

  public static DefinitionCacheConfig cacheWsdl( DefinitionLoader loader ) throws Exception
  {
    DefinitionCacheConfig definitionCache = DefinitionCacheConfig.Factory.newInstance();
    definitionCache.setRootPart( loader.getBaseURI() );
    definitionCache.setType( DefinitionCacheTypeConfig.TEXT );

    Map<String, XmlObject> urls = SchemaUtils.getDefinitionParts( loader );

    for( Iterator<String> i = urls.keySet().iterator(); i.hasNext(); )
    {
      DefintionPartConfig definitionPart = definitionCache.addNewPart();
      String url = i.next();
      definitionPart.setUrl( url );
      XmlObject xmlObject = urls.get( url );
      Node domNode = xmlObject.getDomNode();

      if( domNode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE )
      {
        Node node = ( ( DocumentFragment )domNode ).getFirstChild();
        if( node.getNodeType() == Node.TEXT_NODE )
        {
          domNode = XmlUtils.parseXml( node.getNodeValue() );
          // xmlObject = XmlObject.Factory.parse( domNode );
          xmlObject = XmlUtils.createXmlObject( domNode );
        }
      }

      Element contentElement = ( ( Document )domNode ).getDocumentElement();

      Node newDomNode = definitionPart.addNewContent().getDomNode();
      newDomNode.appendChild( newDomNode.getOwnerDocument().createTextNode( xmlObject.toString() ) );
      definitionPart.setType( contentElement.getNamespaceURI() );
    }

    return definitionCache;
  }

  public static void getAnonymous( WsdlOperation wsdlOperation )
  {
    String anonymous = "";

    Element[] anonymousElements = WsdlUtils.getExentsibilityElements( wsdlOperation.getBindingOperation(), new QName(
        "http://www.w3.org/2006/05/addressing/wsdl", "Anonymous" ) );
    if( anonymousElements.length == 0 )
    {
      anonymousElements = WsdlUtils.getExentsibilityElements( wsdlOperation.getBindingOperation(), new QName(
          "http://www.w3.org/2006/02/addressing/wsdl", "Anonymous" ) );
    }

    if( anonymousElements != null && anonymousElements.length > 0 )
    {
      anonymous = XmlUtils.getElementText( anonymousElements[0] );
    }
    wsdlOperation.setAnonymous( anonymous );
  }

  public static String getDefaultWsaAction( WsdlOperation operation, boolean output )
  {
    // SOAP 1.1 specific handling
    if( operation.getInterface().getSoapVersion() == SoapVersion.Soap11
        && StringUtils.hasContent( operation.getAction() )
        && SoapUI.getSettings().getBoolean( WsaSettings.SOAP_ACTION_OVERRIDES_WSA_ACTION ) )
      return operation.getAction();

    try
    {
      if( operation.getBindingOperation() == null || operation.getBindingOperation().getOperation() == null )
        return null;

      AttributeExtensible attributeExtensible = output ? operation.getBindingOperation().getOperation().getOutput()
          : operation.getBindingOperation().getOperation().getInput();

      if( attributeExtensible == null )
        return null;

      // String[] attrs =
      // WsdlUtils.getExentsibilityAttributes(attributeExtensible, new QName(
      // WsaUtils.WS_A_NAMESPACE_200408, "Action"));
      // if (attrs == null || attrs.length == 0)
      // attrs = WsdlUtils.getExentsibilityAttributes(attributeExtensible,
      // new QName(WsaUtils.WS_A_NAMESPACE_200508,
      // "Action"));
      // if (attrs != null && attrs.length > 0)
      // {
      // return attrs[0];
      // }
      String[] attrs;
      for( String namespace : WsaUtils.wsaNamespaces )
      {
        attrs = WsdlUtils.getExentsibilityAttributes( attributeExtensible, new QName( namespace, "Action" ) );
        if( attrs != null && attrs.length > 0 )
        {
          return attrs[0];
        }
      }

      WsdlInterface iface = operation.getInterface();

      Definition definition = iface.getWsdlContext().getDefinition();
      String targetNamespace = WsdlUtils.getTargetNamespace( definition );
      String portTypeName = iface.getBinding().getPortType().getQName().getLocalPart();
      String operationName = operation.getName();
      if( !StringUtils.isNullOrEmpty( operationName ) )
      {
        Operation op = iface.getBinding().getPortType().getOperation( operationName, null, null );
        if( op != null )
        {
          attributeExtensible = output ? op.getOutput() : op.getInput();
          attrs = WsdlUtils.getExentsibilityAttributes( attributeExtensible, new QName(
              WsaUtils.WS_A_NAMESPACE_200705, "Action" ) );
          if( attrs != null && attrs.length > 0 )
          {
            return attrs[0];
          }
        }
      }
      String operationInOutName = output ? operation.getOutputName() : operation.getInputName();
      if( operationInOutName == null )
        operationInOutName = operation.getName() + ( output ? "Response" : "Request" );

      StringBuffer result = new StringBuffer( targetNamespace );
      if( targetNamespace.length() > 0 && targetNamespace.charAt( targetNamespace.length() - 1 ) != '/'
          && portTypeName.charAt( 0 ) != '/' )
        result.append( '/' );
      result.append( portTypeName );
      if( portTypeName.charAt( portTypeName.length() - 1 ) != '/' && operationInOutName.charAt( 0 ) != '/' )
        result.append( '/' );
      result.append( operationInOutName );

      return result.toString();
    }
    catch( Exception e )
    {
      e.printStackTrace();
      log.warn( e.toString() );
      return null;
    }
  }

  public static void setDefaultWsaAction( WsaConfig wsaConfig, boolean b )
  {
    String defaultAction = getDefaultWsaAction( wsaConfig.getWsaContainer().getOperation(), b );
    if( StringUtils.hasContent( defaultAction ) )
      wsaConfig.setAction( defaultAction );
  }

  public static String getRequestWsaMessageId( WsdlMessageExchange messageExchange, String wsaVersionNameSpace )
  {
    String requestMessageId = null;
    try
    {
      // XmlObject xmlObject = XmlObject.Factory.parse(
      // messageExchange.getRequestContent() );
      XmlObject xmlObject = XmlUtils.createXmlObject( messageExchange.getRequestContent() );
      SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();

      Element header = ( Element )SoapUtils.getHeaderElement( xmlObject, soapVersion, true ).getDomNode();
      Element msgNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "MessageID" );
      if( msgNode != null )
      {
        requestMessageId = XmlUtils.getElementText( msgNode );
      }
    }
    catch( XmlException e )
    {
      e.printStackTrace();
      log.warn( e.toString() );
      return null;
    }
    return requestMessageId;
  }

  public static NodeList getRequestReplyToRefProps( WsdlMessageExchange messageExchange, String wsaVersionNameSpace )
  {
    try
    {
      // XmlObject xmlObject = XmlObject.Factory.parse(
      // messageExchange.getRequestContent() );
      XmlObject xmlObject = XmlUtils.createXmlObject( messageExchange.getRequestContent() );
      SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();

      Element header = ( Element )SoapUtils.getHeaderElement( xmlObject, soapVersion, true ).getDomNode();
      Element replyToNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "ReplyTo" );
      Element replyRefParamsNode = XmlUtils.getFirstChildElementNS( replyToNode, wsaVersionNameSpace,
          "ReferenceParameters" );
      if( replyRefParamsNode != null )
      {
        return XmlUtils.getChildElements( replyRefParamsNode );
      }
    }
    catch( XmlException e )
    {
      e.printStackTrace();
      log.warn( e.toString() );
    }
    return null;
  }

  public static NodeList getRequestFaultToRefProps( WsdlMessageExchange messageExchange, String wsaVersionNameSpace )
  {
    try
    {
      // XmlObject xmlObject = XmlObject.Factory.parse(
      // messageExchange.getRequestContent() );
      XmlObject xmlObject = XmlUtils.createXmlObject( messageExchange.getRequestContent() );
      SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();

      Element header = ( Element )SoapUtils.getHeaderElement( xmlObject, soapVersion, true ).getDomNode();
      Element faultToNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "FaultTo" );
      Element faultRefParamsNode = XmlUtils.getFirstChildElementNS( faultToNode, wsaVersionNameSpace,
          "ReferenceParameters" );
      if( faultRefParamsNode != null )
      {
        return XmlUtils.getChildElements( faultRefParamsNode );
      }
    }
    catch( XmlException e )
    {
      e.printStackTrace();
      log.warn( e.toString() );
    }
    return null;
  }

  public static String getFaultCode( WsdlMessageExchange messageExchange )
  {
    try
    {
      // XmlObject xmlObject = XmlObject.Factory.parse(
      // messageExchange.getResponseContent() );
      XmlObject xmlObject = XmlUtils.createXmlObject( messageExchange.getResponseContent() );
      SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();

      Element body = ( Element )SoapUtils.getBodyElement( xmlObject, soapVersion ).getDomNode();
      Element soapenvFault = XmlUtils.getFirstChildElementNS( body, "http://schemas.xmlsoap.org/soap/envelope/",
          "Fault" );
      Element faultCode = XmlUtils.getFirstChildElement( soapenvFault, "faultcode" );
      if( faultCode != null )
      {
        return XmlUtils.getElementText( faultCode );
      }
    }
    catch( XmlException e )
    {
      e.printStackTrace();
      log.warn( e.toString() );
    }
    return null;
  }

  public static String getTargetNamespace( Definition definition )
  {
    return definition.getTargetNamespace() == null ? XMLConstants.NULL_NS_URI : definition.getTargetNamespace();
  }

  public static SchemaType generateRpcBodyType( WsdlOperation operation )
  {
    return XmlString.type;
  }
}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils

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.