/*******************************************************************************
 * Copyright (c) 2006, 2008 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.lang.reflect.Method;
import java.util.AbstractMap;
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.Set;
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 org.eclipse.wst.wsdl.WSDLPlugin;
import org.eclipse.xsd.XSDPlugin;
import org.eclipse.xsd.util.DefaultJAXPConfiguration;
import org.eclipse.xsd.util.JAXPConfiguration;
import org.eclipse.xsd.util.JAXPPool;
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$

  private static final class LocationMap extends AbstractMap
  {
    protected static final int UNSET = Integer.MAX_VALUE;
    protected Map delegateMap;
    private int startLine = UNSET;
    private int startColumn = UNSET;
    private int endLine = UNSET;
    private int endColumn = UNSET;

    public Set entrySet()
    {
      return getDelegateMap().entrySet();
    }

    protected Map getDelegateMap()
    {
      if (delegateMap == null)
      {
        delegateMap = new HashMap();
        if (startLine != UNSET)
        {
          delegateMap.put(START_LINE, new Integer(startLine));
        }
        if (startColumn != UNSET)
        {
          delegateMap.put(START_COLUMN, new Integer(startColumn));
        }
        if (endLine != UNSET)
        {
          delegateMap.put(END_LINE, new Integer(endLine));
        }
        if (endColumn != UNSET)
        {
          delegateMap.put(END_COLUMN, new Integer(endColumn));
        }
      }
      return delegateMap;
    }

    protected int objectToInt(Object value)
    {
      return value == null ? UNSET : ((Integer)value).intValue();
    }

    protected Object intToObject(int value)
    {
      return value == UNSET ? null : new Integer(value);
    }

    public Object put(Object key, Object value)
    {
      Object result;
      if (delegateMap == null)
      {
        if (START_LINE.equals(key))
        {
          result = intToObject(startLine);
          startLine  = objectToInt(value);
        }
        else if (END_LINE.equals(key))
        {
          result = intToObject(endLine);
          endLine  = objectToInt(value);
        }
        else if (START_COLUMN.equals(key))
        {
          result = intToObject(startColumn);
          startColumn  = objectToInt(value);
        }
        else if (END_COLUMN.equals(key))
        {
          result = intToObject(endColumn);
          endColumn  = objectToInt(value);
        }
        else
        {
          result = getDelegateMap().put(key, value);
        }
      }
      else
      {
        result = getDelegateMap().put(key, value);
      }
      return result;
    }

    public int getStartLine()
    {
      return delegateMap == null ? startLine : objectToInt(delegateMap.get(START_LINE));
    }

    public void setStartLine(int startLine)
    {
      if (delegateMap == null)
      {
        this.startLine = startLine;
      }
      else
      {
        delegateMap.put(START_LINE, new Integer(startLine));
      }
    }

    public int getStartColumn()
    {
      return delegateMap == null ? startColumn : objectToInt(delegateMap.get(START_COLUMN));
    }

    public void setStartColumn(int startColumn)
    {
      if (delegateMap == null)
      {
        this.startColumn = startColumn;
      }
      else
      {
        delegateMap.put(START_COLUMN, new Integer(startColumn));
      }
    }

    public int getEndLine()
    {
      return delegateMap == null ? endLine : objectToInt(delegateMap.get(END_LINE));
    }

    public void setEndLine(int endLine)
    {
      if (delegateMap == null)
      {
        this.endLine = endLine;
      }
      else
      {
        delegateMap.put(END_LINE, new Integer(endLine));
      }
    }

    public int getEndColumn()
    {
      return delegateMap == null ? endColumn : objectToInt(delegateMap.get("endColumn"));
    }

    public void setEndColumn(int endColumn)
    {
      if (delegateMap == null)
      {
        this.endColumn = endColumn;
      }
      else
      {
        delegateMap.put(END_COLUMN, new Integer(endColumn));
      }
    }
  }

  /**
   * 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());

  private static LocationMap getLocationMap(Node node)
  {
    LocationMap result = (LocationMap)userDataMap.get(node);
    if (result == null)
    {
      result = new LocationMap();
      userDataMap.put(node, result);
    }
    return result;
  }

  /**
   * 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)
  {
    int result = getLocationMap(node).getEndColumn();
    return result == LocationMap.UNSET ? 1 : result;
  }

  /**
   * 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)
  {
    int result = getLocationMap(node).getEndLine();
    return result == LocationMap.UNSET ? 1 : result;
  }

  /**
   * 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)
  {
    int result = getLocationMap(node).getStartColumn();
    return result == LocationMap.UNSET ? 1 : result;
  }

  /**
   * 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)
  {
    int result = getLocationMap(node).getStartLine();
    return result == LocationMap.UNSET ? 1 : result;
  }

  /**
   * 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)
  {
    return getLocationMap(node);
  }

  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();

  protected JAXPPool jaxpPool;
    
  /**
   * Default constructor.
   */
  public WSDLParser()
  {
    this(Collections.EMPTY_MAP);
  }
  
  /**
   * Constructs a WSDL parser given a set of parsing options.
   * 
   * @param options a Map of String to Object, passed along through the ResourceSet and Resource. 
   */
  public WSDLParser(Map options)
  {
    JAXPConfiguration config = null;
    if (options != null)
    {
      jaxpPool = (JAXPPool)options.get(WSDLResourceImpl.WSDL_JAXP_POOL);
      config = (JAXPConfiguration)options.get(WSDLResourceImpl.WSDL_JAXP_CONFIG);
    }
    try
    {
      if (jaxpPool == null)
      {      
        if (config != null)
        {
          saxParser = config.createSAXParser(this);
        }
        else
        {
          saxParser = new DefaultJAXPConfiguration().createSAXParser(this);
        }
      }
      else
      {
        saxParser = jaxpPool.getSAXParser(this);
      }
    }
    catch (SAXException exception)
    {
      fatalError(exception);
    }
    catch (ParserConfigurationException exception)
    {
      fatalError(exception);
    }
  }

  /*
   * (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;
    }
  }

  /*
   * (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();

    if (inSchema)
    {
      Map userData = XSDParser.getUserData(element);
      userData.put(END_LINE, new Integer(line));
      userData.put(END_COLUMN, new Integer(column));
    }
    else
    {
      LocationMap locationMap = getLocationMap(element);
      locationMap.setEndLine(line);
      locationMap.setEndColumn(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);
      }
    }
    finally
    {
      if (jaxpPool != null)
      {
        jaxpPool.releaseSAXParser(saxParser);
      }
    }
  }

  /**
   * 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);
      }
    }
    finally
    {
      if (jaxpPool != null)
      {
        jaxpPool.releaseSAXParser(saxParser);
      }
    }
  }

  /*
   * (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()
  {
    if (locator != null)
    {
      line = locator.getLineNumber();
      column = locator.getColumnNumber();
      
      // The crimson parser seems to give poor coordinates 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.

    if (inSchema)
    {
      Map userData = XSDParser.getUserData(element);
      userData.put(START_LINE, new Integer(line));
      userData.put(START_COLUMN, new Integer(column));
    }
    else
    {
      LocationMap locationMap = getLocationMap(element);
      locationMap.setStartLine(line);
      locationMap.setStartColumn(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);
  }

  public String getEncoding()
  {
    if (locator != null)
    {
      try 
      {
        Method getEncodingMethod = locator.getClass().getMethod("getEncoding", new Class[]{});
        if (getEncodingMethod != null)
        {
          encoding = (String)getEncodingMethod.invoke(locator, new Object[] {});
        }
      }
      catch (Exception e) 
      {
        // If we can't find it, there's nothing we can do...
      }
    }

    return encoding;
  }
}
