/*******************************************************************************
 * Copyright (c) 2002-2005 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsi.internal.core.wsdl;

import org.eclipse.wst.wsi.internal.core.WSIConstants;

import javax.wsdl.Binding;
import javax.wsdl.BindingOperation;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.PortType;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPHeader;
import javax.wsdl.extensions.soap.SOAPHeaderFault;
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.xml.namespace.QName;

import java.util.*;

/**
 * Set of XML related utilities.
 * 
 * @author Peter  Brittenham (peterbr@us.ibm.com)
 * @version 1.0.1
 */
public final class WSDLUtils
{

  /**
   * Method isRpcLiteral.
   * @param bindingStyle a binding style.
   * @param operation a WSDL binding operation artifact.
   * @return true if binding is rpc literal.
   */
  public static boolean isRpcLiteral(
    String bindingStyle,
    BindingOperation operation)
  {
    return checkStyleAndUse(
      WSIConstants.ATTRVAL_SOAP_BIND_STYLE_RPC,
      WSIConstants.ATTRVAL_SOAP_BODY_USE_LIT,
      bindingStyle,
      operation);
  }

  /**
   * Method isDocLiteral.
   * @param bindingStyle  the binding style.
   * @param operation a WSDL binding operation.
   * @return true if binding is document literal. 
   */
  public static boolean isDocLiteral(
    String bindingStyle,
    BindingOperation operation)
  {
    return checkStyleAndUse(
      WSIConstants.ATTRVAL_SOAP_BIND_STYLE_DOC,
      WSIConstants.ATTRVAL_SOAP_BODY_USE_LIT,
      bindingStyle,
      operation);
  }

  /**
   * Method checkStyleAndUse.
   */
  private static boolean checkStyleAndUse(
    String checkStyle,
    String checkUse,
    String bindingStyle,
    BindingOperation bindingOperation)
  {
    boolean styleFound = false;
    boolean styleAndUseFound = false;

    // Find the soapbind:operation element
    SOAPOperation soapOperation = getSoapOperation(bindingOperation);

    // If there are no ext elements, then check against binding style
    if ((soapOperation == null) || (soapOperation.getStyle() == null))
    {
      if (checkStyle.equals(bindingStyle))
        styleFound = true;
    }

    else
    {
      if (checkStyle.equals(soapOperation.getStyle()))
        styleFound = true;
    }

    // If style found then check use
    if (styleFound)
    {
      // Find the soapbind:body element
      SOAPBody soapBody = getInputSoapBody(bindingOperation);

      // If there are no soapbind:body, then check against default use value
      if ((soapBody == null) || (soapBody.getUse() == null))
      {
        if (checkUse.equals(WSIConstants.ATTRVAL_SOAP_BODY_USE_LIT))
          styleAndUseFound = true;
      }

      else
      {
        if (checkUse.equals(soapBody.getUse()))
          styleAndUseFound = true;
      }
    }

    return styleAndUseFound;
  }

  /**
   * Get soapbind:binding.
   * @param binding  a Binding object.
   * @return soapbind:binding.
   */
  public static SOAPBinding getSoapBinding(Binding binding)
  {
    SOAPBinding soapBinding = null;

    List extElements = null;

    // Find the soapbind:operation element
    if ((extElements = binding.getExtensibilityElements()) != null)
    {
      for (Iterator iterator = extElements.iterator();
        iterator.hasNext() && (soapBinding == null);
        )
      {
        Object obj = iterator.next();

        if (obj instanceof SOAPBinding)
        {
          soapBinding = (SOAPBinding) obj;
        }
      }
    }

    return soapBinding;
  }

  /**
   * Get soapbind:operation.
   * @param bindingOperation  a BindingOperation object.
   * @return soapbind:operation.
   */
  public static SOAPOperation getSoapOperation(BindingOperation bindingOperation)
  {
    SOAPOperation soapOperation = null;

    List extElements = null;

    // Find the soapbind:operation element
    if ((extElements = bindingOperation.getExtensibilityElements()) != null)
    {
      for (Iterator iterator = extElements.iterator();
        iterator.hasNext() && (soapOperation == null);
        )
      {
        Object obj = iterator.next();

        if (obj instanceof SOAPOperation)
        {
          soapOperation = (SOAPOperation) obj;
        }
      }
    }

    return soapOperation;
  }

  /**
   * Get soapbind:body from input element.
   * @param bindingOperation  the BindingOperation object.
   * @return soapbind:body from input element.
   */
  public static SOAPBody getInputSoapBody(BindingOperation bindingOperation)
  {
    SOAPBody soapBody = null;

    List extElements = null;

    // Find the soapbind:body element
    if ((extElements =
      bindingOperation.getBindingInput().getExtensibilityElements())
      != null)
    {
      for (Iterator iterator = extElements.iterator();
        iterator.hasNext() && (soapBody == null);
        )
      {
        Object obj = iterator.next();

        if (obj instanceof SOAPBody)
        {
          soapBody = (SOAPBody) obj;
        }
      }
    }

    return soapBody;
  }

  /**
   * Find messages referenced by a header or headerfault.
   * @param definition  a Definition object.
   * @param binding  a Binding object.
   * @return messages referenced by a header or headerfault.
   */
  public static HashSet findMessages(Definition definition, Binding binding)
  {
    BindingOperation bindingOperation;

    HashSet tempMessages, bindingMessages = new HashSet();

    HashSet portTypeMessages = findMessages(binding.getPortType());

    // Process each operation
    Iterator iterator = binding.getBindingOperations().iterator();
    while (iterator.hasNext())
    {
      bindingOperation = (BindingOperation) iterator.next();

      // Process the input and then the output
      if (bindingOperation.getBindingInput() != null)
      {
        tempMessages =
          findMessages(
            bindingOperation
              .getBindingInput()
              .getExtensibilityElements()
              .iterator(),
            portTypeMessages,
            definition);

        // Add messages to binding message set
        bindingMessages.addAll(tempMessages);
      }

      // Process output
      if (bindingOperation.getBindingOutput() != null)
      {
        tempMessages =
          findMessages(
            bindingOperation
              .getBindingOutput()
              .getExtensibilityElements()
              .iterator(),
            portTypeMessages,
            definition);

        // Add messages to binding message set
        bindingMessages.addAll(tempMessages);
      }
    }

    return bindingMessages;
  }

  /**
   * Find the messages that are referenced by a header or headerfault.
   * @param portType a PortType object.
   * @return he messages that are referenced by a header or headerfault.
   */
  public static HashSet findMessages(PortType portType)
  {
    HashSet messageSet = new HashSet();
    ExtensibilityElement extElement;
    Operation operation;

    Iterator iterator = portType.getOperations().iterator();
    while (iterator.hasNext())
    {
      // Get next operation to process
      operation = (Operation) iterator.next();

      // Get input and output message
      if (operation.getInput() != null)
        messageSet.add(operation.getInput().getMessage());
      if (operation.getOutput() != null)
        messageSet.add(operation.getOutput().getMessage());

      // Process any faults
      Iterator faults = operation.getFaults().values().iterator();
      while (faults.hasNext())
      {
        messageSet.add(((Fault) faults.next()).getMessage());
      }
    }

    return messageSet;
  }

  /**
   * Find the messages that are referenced by a header or headerfault.
   * @param extElementList a list of external elements.
   * @param messageSet a set of messages.
   * @param definition a Definition object.
   * @return the messages that are referenced by a header or headerfault.
   */
  protected static HashSet findMessages(
    Iterator extElementList,
    HashSet messageSet,
    Definition definition)
  {
    HashSet returnSet = new HashSet();
    ExtensibilityElement extElement;
    Message saveMessage = null;

    while (extElementList.hasNext())
    {
      // Get ext. element
      extElement = (ExtensibilityElement) extElementList.next();

      QName messageQName;
      Message message;

      // If this is a soap:header element, then check for message reference
      if (extElement instanceof SOAPHeader)
      {
        SOAPHeader soapHeader = (SOAPHeader) extElement;
        if ((messageQName = soapHeader.getMessage()) != null)
        {
          // If message not found, then create a dummy message element
          if ((message = definition.getMessage(messageQName)) == null)
          {
            message = definition.createMessage();
            message.setQName(messageQName);
            message.setUndefined(true);
          }

          if (!messageSet.contains(message))
          {
            returnSet.add(message);
            saveMessage = message;
          }
        }

        // Process any header faults within this header
        Iterator headerFaultList = soapHeader.getSOAPHeaderFaults().iterator();
        while (headerFaultList.hasNext())
        {
          // Get soap header fault
          SOAPHeaderFault soapHeaderFault =
            (SOAPHeaderFault) headerFaultList.next();
          if ((messageQName = soapHeaderFault.getMessage()) != null)
          {
            // If message not found, then create a dummy message element
            if ((message = definition.getMessage(messageQName)) == null)
            {
              message = definition.createMessage();
              message.setQName(messageQName);
              message.setUndefined(true);
            }

            // If message not in message set and return set, then add it  
            if (!messageSet.contains(message)
              && ((saveMessage == null)
                || (saveMessage != null
                  && !saveMessage.getQName().equals(message.getQName()))))
              returnSet.add(message);
          }
        }
      }
    }

    return returnSet;
  }
}
