/*******************************************************************************
 * 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 java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
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.Import;
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.PortType;
import javax.wsdl.Service;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.factory.WSDLFactory;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.xerces.dom.ElementImpl;
import org.eclipse.wst.wsi.internal.core.xml.dom.ElementLocation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

import com.ibm.wsdl.Constants;
import com.ibm.wsdl.util.StringUtils;
import com.ibm.wsdl.util.xml.DOMUtils;
import com.ibm.wsdl.util.xml.QNameUtils;
import com.ibm.wsdl.util.xml.XPathUtils;

/**
 * This class is a specialization of com.ibm.wsdl.xml.WSDLReaderImpl in WSDL4J.
 * 
 * @version 1.0.1
 * @author Peter Brittenham  (peterbr@us.ibm.com)
 */
public class WSDLReaderImpl extends com.ibm.wsdl.xml.WSDLReaderImpl
{
  // WSDL element list.
  protected WSDLElementList wsdlElementList = new WSDLElementList();

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseDefinitions(java.lang.String, org.w3c.dom.Element, java.util.Map)
   */
  protected Definition parseDefinitions(
    String documentBaseURI,
    Element defEl,
    Map importedDefs)
    throws WSDLException
  {
	  Definition def = null;
	ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();   
	try
	{
   	  Thread.currentThread().setContextClassLoader(WSDLReaderImpl.class.getClassLoader());   
	
      def =
      super.parseDefinitions(documentBaseURI, defEl, importedDefs);

    // Try to add element to list
    addElementToList(defEl, def);


	}
catch (Exception e)
	{
	}
    finally
    { 
      Thread.currentThread().setContextClassLoader(currentLoader);
    }  
    return def;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseImport(org.w3c.dom.Element, javax.wsdl.Definition, java.util.Map)
   */
  protected Import parseImport(Element element, Definition definition, Map map)
    throws WSDLException
  {
    /*boolean wasEx = false;
    if (def.getDocumentBaseURI()!=null){
    	File f = new File(def.getDocumentBaseURI());
    	if (f.getParent()!=null && importEl.getAttribute("location")!=null){		
    	   f = new File(f.getParent()+"/"+importEl.getAttribute("location"));
    	   
    	}
    } else wasEx = false;
      
    Import importDef = super.parseImport(importEl, def, importedDefs);
    
    // Try to add element to list
    addElementToList(importEl, importDef);
    
    return importDef;*/

    /*Import import1 = definition.createImport();
    String s = DOMUtils.getAttribute(element, "namespace");
    String s1 = DOMUtils.getAttribute(element, "location");
    if (s != null)
    	import1.setNamespaceURI(s);
    if (s1 != null) {
    	if (importDocuments) {
    		String s2 = definition.getDocumentBaseURI();
    		try {
    
    			URL url1 = s2 == null ? null : StringUtils.getURL(null, s2);
    			URL url = StringUtils.getURL(url1, s1);
    			InputStream inputstream =
    				StringUtils.getContentAsInputStream(url);
    			inputstream.close();
    		} catch (IOException ex) {
    			//import1.setLocationURI(null);
    			addElementToList(element, import1);
    			return import1;
    		} catch (Throwable ex) {
    			throw new WSDLException(
    				"OTHER_ERROR",
    				"Unable to resolve imported document at '" + s1 + "'.",
    				ex);
    		}
    
    	}
    }
    Import importDef = super.parseImport(element, definition, map);
    addElementToList(element, importDef);*/
    Import import1 = definition.createImport();
    String s = DOMUtils.getAttribute(element, "namespace");
    String s1 = DOMUtils.getAttribute(element, "location");
    if (s != null)
      import1.setNamespaceURI(s);
    // ADD: check "location" attribute for empty 
    // string to prevent self-defenition assigning
    if ((s1 != null) && (s1.length() > 0))
    {
      import1.setLocationURI(s1);
      if (importDocuments)
        try
        {
          String s2 = definition.getDocumentBaseURI();
          Definition definition1 = null;
          InputStream inputstream = null;
          InputSource inputsource = null;
          URL url = null;
          if (loc != null)
          {
            inputsource = loc.getImportInputSource(s2, s1);
            String s3 = loc.getLatestImportURI();
            definition1 = (Definition) map.get(s3);
          }
          else
          {
            URL url1 = s2 == null ? null : StringUtils.getURL(null, s2);
            url = StringUtils.getURL(url1, s1);
            definition1 = (Definition) map.get(url.toString());
            if (definition1 == null)
            {
              try
              {

                inputstream = url.openStream();
              }
              catch (IOException ex)
              {
                //import1.setLocationURI(null);
                addElementToList(element, import1);
                return import1;
              }
              if (inputstream != null)
                inputsource = new InputSource(inputstream);
            }
          }
          if (definition1 == null)
          {
            if (inputsource == null)
              throw new WSDLException(
                "OTHER_ERROR",
                "Unable to locate imported document at '"
                  + s1
                  + "'"
                  + (s2 != null ? ", relative to '" + s2 + "'." : "."));
            Document document = null;
            try
            {
              document = getDocument(inputsource, s1);
            }
            catch (WSDLException ex)
            {
              addElementToList(element, import1);
              return import1;
            }
            if (inputstream != null)
              inputstream.close();
            Element element2 = document.getDocumentElement();
            if (QNameUtils.matches(Constants.Q_ELEM_DEFINITIONS, element2))
            {
              if (verbose)
                System.out.println(
                  "Retrieving document at '"
                    + s1
                    + "'"
                    + (s2 != null ? ", relative to '" + s2 + "'." : "."));
              String s4 =
                loc == null
                  ? url == null
                  ? s1
                  : url.toString() : loc.getLatestImportURI();
              definition1 = readWSDL(s4, element2, map);
            }
            else
            {
              QName qname = QNameUtils.newQName(element2);
              if (Constants.XSD_QNAME_LIST.contains(qname))
              {
                WSDLFactory wsdlfactory =
                  factoryImplName == null
                    ? WSDLFactory.newInstance()
                    : WSDLFactory.newInstance(factoryImplName);
                definition1 = wsdlfactory.newDefinition();
                if (extReg != null)
                  definition1.setExtensionRegistry(extReg);
                String s5 =
                  loc == null
                    ? url == null
                    ? s1
                    : url.toString() : loc.getLatestImportURI();
                definition1.setDocumentBaseURI(s5);
                /* Don't add types element since it doesn't exist.  Adding it causes problems
                 * since it will add a types element for processing that does not exist.
                Types types = definition1.createTypes();
                UnknownExtensibilityElement unknownextensibilityelement =
                	new UnknownExtensibilityElement();
                unknownextensibilityelement.setElement(element2);
                types.addExtensibilityElement(
                	unknownextensibilityelement);
                definition1.setTypes(types);
                */
              }
            }
          }
          if (definition1 != null)
            import1.setDefinition(definition1);
        }
        catch (WSDLException wsdlexception)
        {
          wsdlexception.setLocation(XPathUtils.getXPathExprFromNode(element));
          throw wsdlexception;
        }
        catch (Throwable throwable)
        {
          throw new WSDLException(
            "OTHER_ERROR",
            "Unable to resolve imported document at '" + s1 + "'.",
            throwable);
        }
    }
    for (Element element1 = DOMUtils.getFirstChildElement(element);
      element1 != null;
      element1 = DOMUtils.getNextSiblingElement(element1))
      if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, element1))
        import1.setDocumentationElement(element1);
      else
        DOMUtils.throwWSDLException(element1);

    return import1;

  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseTypes(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected Types parseTypes(Element typesEl, Definition def)
    throws WSDLException
  {
    Types types = super.parseTypes(typesEl, def);

    // Try to add element to list
    addElementToList(typesEl, types);

    return types;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseBinding(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected Binding parseBinding(Element bindingEl, Definition def)
    throws WSDLException
  {
    Binding binding = super.parseBinding(bindingEl, def);

    // Try to add element to list
    addElementToList(bindingEl, binding);

    return binding;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseBindingOperation(org.w3c.dom.Element, javax.wsdl.PortType, javax.wsdl.Definition)
   */
  protected BindingOperation parseBindingOperation(
    Element bindingOperationEl,
    PortType portType,
    Definition def)
    throws WSDLException
  {
    BindingOperation bindingOperation = null;

    // The follow try-catch was added to detect when a duplicate operation name was detected
    try
    {
      bindingOperation =
        super.parseBindingOperation(bindingOperationEl, portType, def);
    }

    catch (IllegalArgumentException iae)
    {
      if (iae.getMessage().startsWith("Duplicate"))
      {
        bindingOperation =
          parseBindingOperationWithDuplicateNames(
            bindingOperationEl,
            portType,
            def);
      }

      else
      {
        throw iae;
      }
    }

    // Try to add element to list
    if (bindingOperation != null)
    {
      addElementToList(bindingOperationEl, bindingOperation);
    }

    return bindingOperation;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseBindingInput(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected BindingInput parseBindingInput(
    Element bindingInputEl,
    Definition def)
    throws WSDLException
  {
    BindingInput bindingInput = super.parseBindingInput(bindingInputEl, def);

    // Try to add element to list
    addElementToList(bindingInputEl, bindingInput);

    return bindingInput;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseBindingOutput(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected BindingOutput parseBindingOutput(
    Element bindingOutputEl,
    Definition def)
    throws WSDLException
  {
    BindingOutput bindingOutput =
      super.parseBindingOutput(bindingOutputEl, def);

    // Try to add element to list
    addElementToList(bindingOutputEl, bindingOutput);

    return bindingOutput;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseBindingFault(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected BindingFault parseBindingFault(
    Element bindingFaultEl,
    Definition def)
    throws WSDLException
  {
    BindingFault bindingFault = super.parseBindingFault(bindingFaultEl, def);

    // Try to add element to list
    addElementToList(bindingFaultEl, bindingFault);

    return bindingFault;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseMessage(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected Message parseMessage(Element msgEl, Definition def)
    throws WSDLException
  {
    Message msg = super.parseMessage(msgEl, def);

    // Try to add element to list
    addElementToList(msgEl, msg);

    return msg;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parsePart(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected Part parsePart(Element partEl, Definition def) throws WSDLException
  {
    //Part part = super.parsePart(partEl, def);

    Part part = def.createPart();
    String name = DOMUtils.getAttribute(partEl, Constants.ATTR_NAME);

    // WS-I: The try-catch was added for WSI2416
    QName elementName;

    try
    {
      elementName =
        DOMUtils.getQualifiedAttributeValue(
          partEl,
          Constants.ATTR_ELEMENT,
          Constants.ELEM_MESSAGE,
          false);
    }

    catch (WSDLException we)
    {
      String prefixedValue =
        DOMUtils.getAttribute(partEl, Constants.ATTR_ELEMENT);
      int index = prefixedValue.indexOf(':');
      String prefix = (index != -1) ? prefixedValue.substring(0, index) : null;
      String localPart = prefixedValue.substring(index + 1);

      elementName = new QName(localPart);
    }

    QName typeName =
      DOMUtils.getQualifiedAttributeValue(
        partEl,
        Constants.ATTR_TYPE,
        Constants.ELEM_MESSAGE,
        false);

    if (name != null)
    {
      part.setName(name);
    }

    if (elementName != null)
    {
      part.setElementName(elementName);
    }

    if (typeName != null)
    {
      part.setTypeName(typeName);
    }

    Element tempEl = DOMUtils.getFirstChildElement(partEl);

    while (tempEl != null)
    {
      if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl))
      {
        part.setDocumentationElement(tempEl);
      }
      else
      {
        DOMUtils.throwWSDLException(tempEl);
      }

      tempEl = DOMUtils.getNextSiblingElement(tempEl);
    }

    Map extensionAttributes = part.getExtensionAttributes();

    extensionAttributes.putAll(getPartAttributes(partEl, def));

    // Need to do something here to locate part definition.

    // Try to add element to list
    addElementToList(partEl, part);

    return part;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parsePortType(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected PortType parsePortType(Element portTypeEl, Definition def)
    throws WSDLException
  {
    PortType portType = super.parsePortType(portTypeEl, def);

    // Try to add element to list
    addElementToList(portTypeEl, portType);

    return portType;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseOperation(org.w3c.dom.Element, javax.wsdl.PortType, javax.wsdl.Definition)
   */
  protected Operation parseOperation(
    Element opEl,
    PortType portType,
    Definition def)
    throws WSDLException
  {
    Operation op = super.parseOperation(opEl, portType, def);

    // Try to add element to list
    addElementToList(opEl, op);

    return op;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseService(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected Service parseService(Element serviceEl, Definition def)
    throws WSDLException
  {
    Service service = super.parseService(serviceEl, def);

    // Try to add element to list
    addElementToList(serviceEl, service);

    return service;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parsePort(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected Port parsePort(Element portEl, Definition def) throws WSDLException
  {
    Port port = super.parsePort(portEl, def);

    // Try to add element to list
    addElementToList(portEl, port);

    return port;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseExtensibilityElement(java.lang.Class, org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected ExtensibilityElement parseExtensibilityElement(
    Class parentType,
    Element el,
    Definition def)
    throws WSDLException
  {
    ExtensibilityElement extElement =
      super.parseExtensibilityElement(parentType, el, def);

    // Try to add element to list
    addElementToList(el, extElement);

    return extElement;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseInput(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected Input parseInput(Element inputEl, Definition def)
    throws WSDLException
  {
    Input input = super.parseInput(inputEl, def);

    // Try to add element to list
    addElementToList(inputEl, input);

    return input;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseOutput(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected Output parseOutput(Element outputEl, Definition def)
    throws WSDLException
  {
    Output output = super.parseOutput(outputEl, def);

    // Try to add element to list
    addElementToList(outputEl, output);

    return output;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#parseFault(org.w3c.dom.Element, javax.wsdl.Definition)
   */
  protected Fault parseFault(Element faultEl, Definition def)
    throws WSDLException
  {
    Fault fault = super.parseFault(faultEl, def);

    // Try to add element to list
    addElementToList(faultEl, fault);

    return fault;
  }

  /* (non-Javadoc)
   * @see com.ibm.wsdl.xml.WSDLReaderImpl#getDocument(org.xml.sax.InputSource, java.lang.String)
   */
  protected Document getDocument(InputSource inputSource, String desc)
    throws WSDLException
  {
    ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
    try
	{
      Thread.currentThread().setContextClassLoader(WSDLReaderImpl.class.getClassLoader());   	
	
  	  //DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilderFactory factory =
        new org.eclipse.wst.wsi.internal.core.xml.jaxp.DocumentBuilderFactoryImpl();

      factory.setNamespaceAware(true);
      factory.setValidating(false);

      DocumentBuilder builder = factory.newDocumentBuilder();
      Document doc = builder.parse(inputSource);

      return doc;
    }
    catch (Throwable t)
    {
      throw new WSDLException(
        WSDLException.PARSER_ERROR,
        "Problem parsing '" + desc + "'.",
        t);
    }
    finally
    { 
      Thread.currentThread().setContextClassLoader(currentLoader);
    }    
  }

  /**
   * Get element list.
   * @return the element list.
   */
  public WSDLElementList getElementList()
  {
    return this.wsdlElementList;
  }

  /** 
   * Add WSDL element to element list.
   */
  private void addElementToList(Element element, Object wsdlElement)
  {
    ElementLocation elementLocation = null;

    try
    {
      // See if the element object is an instanceof org.apache.xerces.dom.ElementImpl
      ElementImpl elementImpl = (ElementImpl) element;

      // If it is, then get the element location information
      elementLocation =
        (ElementLocation) elementImpl.getUserData(ElementLocation.KEY_NAME);

      // Add it to the list
      this.wsdlElementList.addElement(wsdlElement, elementLocation);
    }

    catch (ClassCastException cce)
    {
      // ADD: Should we add the element with a null or zero location?
    }
  }

  /**
   * This method is used when a WSDL document contains duplicate operation names.
   * It is the same as the original parseBindingOperation method, except that it will
   * just find the first operation that matches instead of throwing an exception.
   */
  private BindingOperation parseBindingOperationWithDuplicateNames(
    Element bindingOperationEl,
    PortType portType,
    Definition def)
    throws WSDLException
  {
    BindingOperation bindingOperation = def.createBindingOperation();
    String name =
      DOMUtils.getAttribute(bindingOperationEl, Constants.ATTR_NAME);

    if (name != null)
    {
      bindingOperation.setName(name);
    }

    Element tempEl = DOMUtils.getFirstChildElement(bindingOperationEl);

    while (tempEl != null)
    {
      if (QNameUtils.matches(Constants.Q_ELEM_DOCUMENTATION, tempEl))
      {
        bindingOperation.setDocumentationElement(tempEl);
      }
      else if (QNameUtils.matches(Constants.Q_ELEM_INPUT, tempEl))
      {
        bindingOperation.setBindingInput(parseBindingInput(tempEl, def));
      }
      else if (QNameUtils.matches(Constants.Q_ELEM_OUTPUT, tempEl))
      {
        bindingOperation.setBindingOutput(parseBindingOutput(tempEl, def));
      }
      else if (QNameUtils.matches(Constants.Q_ELEM_FAULT, tempEl))
      {
        bindingOperation.addBindingFault(parseBindingFault(tempEl, def));
      }
      else
      {
        bindingOperation.addExtensibilityElement(
          parseExtensibilityElement(BindingOperation.class, tempEl, def));
      }

      tempEl = DOMUtils.getNextSiblingElement(tempEl);
    }

    if (portType != null)
    {
      BindingInput bindingInput = bindingOperation.getBindingInput();
      BindingOutput bindingOutput = bindingOperation.getBindingOutput();
      String inputName = (bindingInput != null ? bindingInput.getName() : null);
      String outputName =
        (bindingOutput != null ? bindingOutput.getName() : null);

      //Operation op = portType.getOperation(name, inputName, outputName);
      // Get all operations, and then find the first one that matches
      Operation op = null, checkOperation;
      Iterator iterator = portType.getOperations().iterator();
      while (iterator.hasNext() && op == null)
      {
        // Get the next operation
        checkOperation = (Operation) iterator.next();

        // Get the operation name, input name, and output name
        String checkName = checkOperation.getName();
        String checkInputName =
          (checkOperation.getInput() == null
            ? null
            : checkOperation.getInput().getName());
        String checkOutputName =
          (checkOperation.getOutput() == null
            ? null
            : checkOperation.getOutput().getName());

        // If the names match, then that operation
        if ((checkName != null && checkName.equals(name))
          && ((checkInputName != null && checkInputName.equals(inputName))
            || (checkInputName == null && inputName == null))
          && ((checkOutputName != null && checkOutputName.equals(outputName))
            || (checkOutputName == null && outputName == null)))
        {
          op = checkOperation;
        }
      }

      if (op == null)
      {
        op = def.createOperation();
        op.setName(name);
        portType.addOperation(op);
      }

      bindingOperation.setOperation(op);
    }

    return bindingOperation;
  }

}
