/*******************************************************************************
 * Copyright (c) 2006 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 Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.wst.wsdl.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.WeakHashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.wst.wsdl.WSDLPlugin;
import org.eclipse.xsd.XSDPlugin;
import org.eclipse.xsd.util.XSDConstants;
import org.eclipse.xsd.util.XSDParser;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;

/**
 * The <b>SAX Parser</b> for the WSDL model. This class' main responsibility is
 * to compute line/column information for all elements in the source XML
 * document. This information is stored in a map of each node to its user data.
 * <p>
 * <b>Note:</b> This class/interface is part of an interim API that is still
 * under development and expected to change significantly before reaching
 * stability. It is being made available at this early stage to solicit feedback
 * from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.
 * </p>
 * 
 * [ISSUE] Most of this class' implementation is a clone of XSDParser. There are
 * plans to work on closely integrating this class and XSDParser to provide for
 * the most efficient processing of inline schemas.
 */
public class WSDLParser extends DefaultHandler implements LexicalHandler
{
  /**
   * The name of the user data part holding end column location of an element.
   */
  private static final String END_COLUMN = "endColumn"; //$NON-NLS-1$

  /**
   * The name of the user data part holding end line location of an element.
   */
  private static final String END_LINE = "endLine"; //$NON-NLS-1$

  /**
   * The name of the user data part holding start column location of an element.
   */
  private static final String START_COLUMN = "startColumn"; //$NON-NLS-1$

  /**
   * The name of the user data part holding start line location of an element.
   */
  private static final String START_LINE = "startLine"; //$NON-NLS-1$

  /**
   * Holds pairs Node -> Map with user data.
   * 
   * @see #END_COLUMN
   * @see #END_LINE
   * @see #START_COLUMN
   * @see #START_LINE
   * 
   * A WeakHashMap is used in order to simplify this map's maintenance. As nodes
   * are garbage collected when not needed anymore, the JVM will take care of
   * removing entries from this map.
   */
  protected static final Map userDataMap = Collections.synchronizedMap(new WeakHashMap());

  /**
   * Returns the column at which the given node ends.
   * 
   * @param node
   *          the node to query.
   * @return the column at which the given node ends.
   */
  public static int getEndColumn(Node node)
  {
    Integer result = (Integer) getUserData(node).get(END_COLUMN);
    return result == null ? 1 : result.intValue();
  }

  /**
   * Returns the line at which the given node ends.
   * 
   * @param node
   *          the node to query.
   * @return the line at which the given node ends.
   */
  public static int getEndLine(Node node)
  {
    Integer result = (Integer) getUserData(node).get(END_LINE);
    return result == null ? 1 : result.intValue();
  }

  /**
   * Returns the column at which the given node starts.
   * 
   * @param node
   *          the node to query.
   * @return the column at which the given node starts.
   */
  public static int getStartColumn(Node node)
  {
    Integer result = (Integer) getUserData(node).get(START_COLUMN);
    return result == null ? 1 : result.intValue();
  }

  /**
   * Returns the line at which the given node starts.
   * 
   * @param node
   *          the node to query.
   * @return the line at which the given node starts.
   */
  public static int getStartLine(Node node)
  {
    Integer result = (Integer) getUserData(node).get(START_LINE);
    return result == null ? 1 : result.intValue();
  }

  /**
   * Returns the user data associated with the node. If the node has no user
   * data, a new empty map is created.
   * 
   * @param node
   *          the node to query.
   * @return the user data associated with the node.
   */
  public static Map getUserData(Node node)
  {
    Map result = (Map) userDataMap.get(node);
    if (result == null)
    {
      result = new HashMap();
      userDataMap.put(node, result);
    }
    return result;
  }

  protected int column;
  List diagnostics = new ArrayList();
  protected Document document;
  protected Element element;
  protected String encoding;
  protected boolean inSchema;
  protected int line;
  protected Locator locator;
  protected SAXParser saxParser;
  protected Stack stack = new Stack();

  /**
   * Default constructor.
   */
  public WSDLParser()
  {
    saxParser = createSAXParser();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
   */
  public void characters(char[] characters, int start, int length) throws SAXException
  {
    Text textNode = document.createTextNode(new String(characters, start, length));
    element.appendChild(textNode);
    saveLocation();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
   */
  public void comment(char[] characters, int start, int length) throws SAXException
  {
    Comment commentNode = document.createComment(new String(characters, start, length));
    if (element == null)
    {
      document.appendChild(commentNode);
    }
    else
    {
      element.appendChild(commentNode);
    }
    saveLocation();
  }

  /**
   * Creates an empty DOM Document.
   * 
   * @return an empty DOM Document or null is a JAXP misconfiguration error
   *         occurs.
   */
  private Document createDocument()
  {
    try
    {
      DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
      documentBuilderFactory.setNamespaceAware(true);
      documentBuilderFactory.setValidating(false);
      DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
      return documentBuilder.newDocument();
    }
    catch (ParserConfigurationException exception)
    {
      WSDLPlugin.INSTANCE.log(exception);
      return null;
    }
  }

  /**
   * Creates the SAXParser instance used for parsing the source WSDL XML
   * document.
   * 
   * @return a configured SAXParser instance or null if an exception occurs.
   *         Problems are reported through the diagnostics collection.
   */
  private SAXParser createSAXParser()
  {
    SAXParser saxParser = null;
    try
    {
      SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
      saxParserFactory.setNamespaceAware(true);
      saxParserFactory.setValidating(false);

      saxParserFactory.setFeature("http://xml.org/sax/features/validation", false); //$NON-NLS-N$
      saxParserFactory.setFeature("http://xml.org/sax/features/namespaces", true); //$NON-NLS-N$
      saxParserFactory.setFeature("http://xml.org/sax/features/namespace-prefixes", true); //$NON-NLS-N$

      saxParser = saxParserFactory.newSAXParser();

      saxParser.setProperty("http://xml.org/sax/properties/lexical-handler", this); //$NON-NLS-N$
    }
    catch (SAXException exception)
    {
      fatalError(exception);
    }
    catch (ParserConfigurationException exception)
    {
      fatalError(exception);
    }

    return saxParser;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.ext.LexicalHandler#endCDATA()
   */
  public void endCDATA()
  {
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.helpers.DefaultHandler#endDocument()
   */
  public void endDocument()
  {
    element = null;
    saveLocation();
    this.locator = null;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.ext.LexicalHandler#endDTD()
   */
  public void endDTD()
  {
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
   *      java.lang.String, java.lang.String)
   */
  public void endElement(String uri, String localName, String qName) throws SAXException
  {
    saveLocation();

    Map extendedAttributes = null;

    if (inSchema)
    {
      extendedAttributes = XSDParser.getUserData(element);
    }
    else
    {
      extendedAttributes = getUserData(element);
    }

    extendedAttributes.put(END_LINE, new Integer(line));
    extendedAttributes.put(END_COLUMN, new Integer(column));

    if (isSchemaElement(uri, localName))
    {
      inSchema = false;
    }

    element = (Element) stack.pop();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
   */
  public void endEntity(String name)
  {
  }

  public void error(SAXParseException exception)
  {
    WSDLDiagnosticImpl diagnostic = new WSDLDiagnosticImpl();
    diagnostic.setSeverity(WSDLDiagnosticSeverity.ERROR_LITERAL);
    diagnostic.setMessage(WSDLPlugin.INSTANCE.getString("_UI_IOError_message", new Object[] { exception.getMessage() }));
    diagnostic.setLine(exception.getLineNumber());
    diagnostic.setColumn(exception.getColumnNumber());
    diagnostics.add(diagnostic);
  }

  protected void fatalError(IOException exception)
  {
    WSDLDiagnosticImpl diagnostic = new WSDLDiagnosticImpl();
    diagnostic.setSeverity(WSDLDiagnosticSeverity.FATAL_LITERAL);
    diagnostic.setMessage(WSDLPlugin.INSTANCE.getString("_UI_IOError_message", new Object[] { exception.getMessage() }));
    diagnostics.add(diagnostic);
  }

  protected void fatalError(ParserConfigurationException exception)
  {
    WSDLDiagnosticImpl diagnostic = new WSDLDiagnosticImpl();
    diagnostic.setSeverity(WSDLDiagnosticSeverity.FATAL_LITERAL);
    diagnostic.setMessage(WSDLPlugin.INSTANCE.getString("_UI_ParserError_message", new Object[] { exception.getMessage() }));
    diagnostics.add(diagnostic);
  }

  public void fatalError(SAXException exception)
  {
    WSDLDiagnosticImpl diagnostic = new WSDLDiagnosticImpl();
    diagnostic.setSeverity(WSDLDiagnosticSeverity.FATAL_LITERAL);
    diagnostic.setMessage(WSDLPlugin.INSTANCE.getString("_UI_ParserError_message", new Object[] { exception.getMessage() }));
    diagnostics.add(diagnostic);
  }

  public void fatalError(SAXParseException exception)
  {
    WSDLDiagnosticImpl diagnostic = new WSDLDiagnosticImpl();
    diagnostic.setSeverity(WSDLDiagnosticSeverity.FATAL_LITERAL);
    diagnostic.setMessage(WSDLPlugin.INSTANCE.getString("_UI_ParserError_message", new Object[] { exception.getMessage() }));
    diagnostic.setLine(exception.getLineNumber());
    diagnostic.setColumn(exception.getColumnNumber());
    diagnostics.add(diagnostic);
  }

  /**
   * Provides a collection with the diagnostics generated during parsing.
   * 
   * @return a Collection of {@link WSDLDiagnostic} objects.
   */
  public Collection getDiagnostics()
  {
    return diagnostics;
  }

  /**
   * Provides the DOM document created by parsing the WSDL document.
   * 
   * @return the resulting DOM document.
   */
  public Document getDocument()
  {
    return document;
  }

  /**
   * Determines if an element is the root XML schema element.
   * 
   * @param uri
   *          the URI to test.
   * @param localName
   *          the element's local name.
   * @return true if the element is the root XML schema element, false
   *         otherwise.
   */
  private boolean isSchemaElement(String uri, String localName)
  {
    if (uri.equals(XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001) && localName.equals(XSDConstants.SCHEMA_ELEMENT_TAG))
    {
      return true;
    }
    return false;
  }

  public void parse(InputSource inputSource)
  {
    try
    {
      saxParser.parse(inputSource, this);
    }
    catch (IOException exception)
    {
      fatalError(exception);
    }
    catch (SAXException exception)
    {
      if (diagnostics.isEmpty())
      {
        fatalError(exception);
      }
    }
  }

  /**
   * Parses the XML content read from the given input stream.
   * 
   * @param inputStream
   *          the source input stream. Must not be null.
   */
  public void parse(InputStream inputStream)
  {
    try
    {
      saxParser.parse(new InputSource(inputStream), this);
    }
    catch (IOException exception)
    {
      fatalError(exception);
    }
    catch (SAXException exception)
    {
      if (diagnostics.isEmpty())
      {
        fatalError(exception);
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.helpers.DefaultHandler#processingInstruction(java.lang.String,
   *      java.lang.String)
   */
  public void processingInstruction(String target, String data)
  {
    Node processingInstruction = document.createProcessingInstruction(target, data);

    if (stack.isEmpty())
    {
      document.appendChild(processingInstruction);
    }
    else
    {
      element.appendChild(processingInstruction);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.helpers.DefaultHandler#resolveEntity(java.lang.String,
   *      java.lang.String)
   */
  public InputSource resolveEntity(String publicId, String systemId) throws SAXException
  {
    InputSource inputSource;
    if ("-//W3C//DTD XMLSCHEMA 200102//EN".equalsIgnoreCase(publicId))
    {
      inputSource = new InputSource(XSDPlugin.INSTANCE.getBaseURL() + "cache/www.w3.org/2001/XMLSchema.dtd");
      inputSource.setPublicId(publicId);
    }
    else if (systemId != null && systemId.startsWith("file://bundleentry:"))
    {
      inputSource = new InputSource(systemId.substring(7));
      inputSource.setPublicId(publicId);
    }
    else
    {
      try
      {
        inputSource = super.resolveEntity(publicId, systemId);
        if (false)
        {
          throw new IOException();
        }
      }
      catch (IOException exception)
      {
        throw new SAXException(exception);
      }
    }

    return inputSource;
  }

  /**
   * Saves the current line and column numbers.
   */
  protected void saveLocation()
  {
    line = locator.getLineNumber();
    column = locator.getColumnNumber();

    // The crimson parser seems to give poor coodinates and is 0-based for line
    // count.

    if (column == -1)
    {
      column = 1;
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
   */
  public void setDocumentLocator(Locator locator)
  {
    this.locator = locator;
    super.setDocumentLocator(locator);
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.ext.LexicalHandler#startCDATA()
   */
  public void startCDATA()
  {
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.helpers.DefaultHandler#startDocument()
   */
  public void startDocument()
  {
    saveLocation();
    document = createDocument();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String,
   *      java.lang.String, java.lang.String)
   */
  public void startDTD(String name, String publicId, String systemId)
  {
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
   *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
   */
  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
  {
    if (!inSchema)
    {
      inSchema = isSchemaElement(uri, localName);
    }

    Element newElement = document.createElementNS(uri, qName);

    for (int index = 0, count = attributes.getLength(); index < count; ++index)
    {
      String attributeURI = attributes.getURI(index);
      String attributeQName = attributes.getQName(index);
      String attributeValue = attributes.getValue(index);

      if (attributeQName.equals("xmlns") || attributeQName.startsWith("xmlns:")) //$NON-NLS-1$ //$NON-NLS-2$
      {
        attributeURI = XSDConstants.XMLNS_URI_2000;
      }
      else if ("".equals(attributeURI)) //$NON-NLS-1$
      {
        attributeURI = null;
      }

      newElement.setAttributeNS(attributeURI, attributeQName, attributeValue);
    }

    if (stack.isEmpty())
    {
      document.appendChild(newElement);
    }
    else
    {
      element.appendChild(newElement);
    }

    stack.push(element);
    element = newElement;

    // Make sure we location attributes end up in the XSDParser's user data if
    // we are inside an inline schema. If not, they should go in the
    // WSDLParser's user data.

    Map extendedAttributes = null;

    if (inSchema)
    {
      extendedAttributes = XSDParser.getUserData(element);
    }
    else
    {
      extendedAttributes = getUserData(element);
    }
    extendedAttributes.put(START_LINE, new Integer(line));
    extendedAttributes.put(START_COLUMN, new Integer(column));

    saveLocation();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
   */
  public void startEntity(String name)
  {
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
   */
  public void warning(SAXParseException exception)
  {
    WSDLDiagnosticImpl diagnostic = new WSDLDiagnosticImpl();
    diagnostic.setSeverity(WSDLDiagnosticSeverity.WARNING_LITERAL);
    diagnostic.setMessage("DOM:" + exception.getMessage());
    diagnostic.setLine(exception.getLineNumber());
    diagnostic.setColumn(exception.getColumnNumber());
    diagnostics.add(diagnostic);
  }
}
