/*******************************************************************************
 * Copyright (c) 2001, 2004 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.validation.internal.xml;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.apache.xerces.impl.XMLErrorReporter;
import org.apache.xerces.jaxp.SAXParserFactoryImpl;
import org.apache.xerces.parsers.SAXParser;
import org.apache.xerces.parsers.StandardParserConfiguration;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.eclipse.core.resources.IFile;
import org.eclipse.wst.wsdl.validation.internal.ValidationMessageImpl;
import org.eclipse.wst.wsdl.validation.internal.resolver.IURIResolutionResult;
import org.eclipse.wst.wsdl.validation.internal.resolver.URIResolver;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import com.ibm.wsdl.Constants;

/**
 * The default implementation of IXMLValidator.
 */
public class DefaultXMLValidator implements IXMLValidator
{
  private final String _APACHE_FEATURE_CONTINUE_AFTER_FATAL_ERROR =
    "http://apache.org/xml/features/continue-after-fatal-error";
  private final String _APACHE_FEATURE_NAMESPACE_PREFIXES = "http://xml.org/sax/features/namespace-prefixes";
  private final String _APACHE_FEATURE_NAMESPACES = "http://xml.org/sax/features/namespaces";
  private final String _APACHE_FEATURE_VALIDATION = "http://xml.org/sax/features/validation";
  private final String _APACHE_FEATURE_VALIDATION_SCHEMA = "http://apache.org/xml/features/validation/schema";
  private final String _APACHE_PROPERTY_EXTERNAL_SCHEMALOCATION =
    "http://apache.org/xml/properties/schema/external-schemaLocation";
  private final String DEFINITIONS = "definitions";
  
  protected static final String IGNORE_ALWAYS = "IGNORE_ALWAYS";
  protected static final String PREMATURE_EOF = "PrematureEOF";
  
  protected Hashtable ingoredErrorKeyTable = new Hashtable();

  protected String uri;
  protected URIResolver uriResolver = null;
  protected List errors = new ArrayList();
  protected StringBuffer schemaLocationString = new StringBuffer();
  protected List ignoredNamespaceList = new ArrayList();
  
  protected InputStream inputStream = null;
  
  protected String currentErrorKey = null;
  protected Object[] currentMessageArguments = null;
  
  protected boolean isChildOfDoc = false;
//  protected String wsdlNamespace = null;




/**
   * Constructor.
   */
  public DefaultXMLValidator()
  {
    super();
    
    ignoredNamespaceList.add(Constants.NS_URI_XSD_1999);
    ignoredNamespaceList.add(Constants.NS_URI_XSD_2000);
    ignoredNamespaceList.add(Constants.NS_URI_XSD_2001);
    
    ingoredErrorKeyTable.put(PREMATURE_EOF, IGNORE_ALWAYS);
  }

  /**
   * @see org.eclipse.validate.wsdl.xmlconformance.IXMLValidatorAction#setFile(IFile)
   */
  public void setFile(String uri)
  {
    this.uri = uri;
  }
  
  public void setURIResolver(URIResolver uriResolver)
  {
  	this.uriResolver = uriResolver;
  }

  /**
   * @see org.eclipse.validate.wsdl.xmlconformance.IXMLValidatorAction#run()
   */
  public void run()
  {
    // Validate the XML file.
    try
    {
      Reader reader1 = null; // Used for the preparse.
      Reader reader2 = null; // Used for validation parse.
      
      InputSource validateInputSource; 
     
      
      if (this.inputStream != null)
      {    
      

        String string = createStringForInputStream(inputStream);
        reader1 = new StringReader(string);
        reader2 = new StringReader(string); 
          
        validateInputSource = new InputSource(inputStream);
        validateInputSource.setCharacterStream(reader2);
      } else
      { validateInputSource = new InputSource(uri);
      }
      
      preparse(uri, reader1);
      
      SAXParser saxparser = createSAXParser();
      XMLConformanceDefaultHandler handler = new XMLConformanceDefaultHandler();

      saxparser.setErrorHandler(handler);
	  saxparser.setEntityResolver(handler);
	  saxparser.setContentHandler(handler);
      
      saxparser.parse(validateInputSource);
//      wsdlNamespace = handler.getWSDLNamespace();
    }
    catch (SAXParseException e)
    {
      addError(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), uri);
    }
    catch (IOException e)
    {
    }
    catch (Exception e)
    {
      //System.out.println(e);
    }
  }

  /**
   * Create and configure a SAX parser.
   * 
   * @return The new SAX parser.
   */
  protected SAXParser createSAXParser()
  {
    SAXParser saxParser = null;
    try
    {
      //SAXParserFactory parserfactory = new SAXParserFactoryImpl();
      try
      { MyStandardParserConfiguration configuration = new MyStandardParserConfiguration();
        saxParser = new org.apache.xerces.parsers.SAXParser(configuration);
        saxParser.setFeature(_APACHE_FEATURE_CONTINUE_AFTER_FATAL_ERROR, true);
        saxParser.setFeature(_APACHE_FEATURE_NAMESPACE_PREFIXES, true);
        saxParser.setFeature(_APACHE_FEATURE_NAMESPACES, true);
        saxParser.setFeature(_APACHE_FEATURE_VALIDATION, true);
        saxParser.setFeature(_APACHE_FEATURE_VALIDATION_SCHEMA, true);
      }
      catch (SAXNotRecognizedException e)
      {
      }
      catch (SAXNotSupportedException e)
      {
      }
      if (schemaLocationString.length() > 0)
      {
        saxParser.setProperty(_APACHE_PROPERTY_EXTERNAL_SCHEMALOCATION, schemaLocationString.toString());
      }
    }
    catch (FactoryConfigurationError e)
    {
    }
    catch (SAXNotRecognizedException e)
    {
    }
    catch (SAXNotSupportedException e)
    {
    }
//    catch (SAXException e)
//    {
//    }
    return saxParser;
  }

  
  final String createStringForInputStream(InputStream inputStream)
  {
    // Here we are reading the file and storing to a stringbuffer.
    StringBuffer fileString = new StringBuffer();
    try
    {
      InputStreamReader inputReader = new InputStreamReader(inputStream);
      BufferedReader reader = new BufferedReader(inputReader);
      char[] chars = new char[1024];
      int numberRead = reader.read(chars);
      while (numberRead != -1)
      {
        fileString.append(chars, 0, numberRead);
        numberRead = reader.read(chars);
      }
    }
    catch (Exception e)
    {
      //TODO: log error message
      //e.printStackTrace();
    }
    return fileString.toString();
  }
  
  /**
   * Preparse the file to find all of the namespaces that are defined in order
   * to specify the schemalocation.
   * 
   * @param uri The uri of the file to parse.
   */
  protected void preparse(String uri, Reader characterStream)
  {
      javax.xml.parsers.SAXParser saxParser = null;
    try
    {
        
      InputSource inputSource; 
      
      if (characterStream != null)
      {   
          inputSource = new InputSource(uri);
          inputSource.setCharacterStream(characterStream);
      }
      else
      {
          inputSource = new InputSource(uri);
      }
      
      SAXParserFactory parserfactory = new SAXParserFactoryImpl();

      parserfactory.setFeature(_APACHE_FEATURE_NAMESPACE_PREFIXES, true);
      parserfactory.setFeature(_APACHE_FEATURE_NAMESPACES, true);

      saxParser = parserfactory.newSAXParser();
      SchemaStringHandler handler = new SchemaStringHandler(uri);
      
      saxParser.parse(inputSource, handler);
    }
    catch (FactoryConfigurationError e)
    {
    }
    catch (SAXNotRecognizedException e)
    {
    }
    catch (ParserConfigurationException e)
    {
    }
    catch (SAXNotSupportedException e)
    {
    }
    catch (SAXException e)
    {
    }
    catch (IOException e)
    {
    }
  }

  /**
   * @see org.eclipse.validate.wsdl.xmlconformance.IXMLValidatorAction#hasErrors()
   */
  public boolean hasErrors()
  {
    return !errors.isEmpty();
  }

  /**
   * @see org.eclipse.validate.wsdl.xmlconformance.IXMLValidatorAction#getErrorList()
   */
  public List getErrors()
  {
    return errors;
  }

  /**
   * Add an error message.
   * 
   * @param error The error message to add.
   * @param line The line location of the error.
   * @param column The column location of the error.
   * @param uri The URI of the file containing the error.
   */
  protected void addError(String error, int line, int column, String uri)
  {
    errors.add(new ValidationMessageImpl(error, line, column, ValidationMessageImpl.SEV_ERROR, uri, currentErrorKey, currentMessageArguments));
  }

  /**
   * The handler for the SAX parser. This handler will obtain the WSDL
   * namespace, handle errors and resolve entities.
   */
  protected class XMLConformanceDefaultHandler extends DefaultHandler
  {
    /**
     * @see org.xml.sax.ErrorHandler#error(SAXParseException)
     */
    public void error(SAXParseException arg0) throws SAXException
    {
     String tempURI = arg0.getSystemId();
     if (inputStream!= null && arg0.getSystemId() == null)
     {
       //mh: In this case we are validating a stream so the URI may be null in this exception
       tempURI = uri;       
     }
     addError(arg0.getMessage(), arg0.getLineNumber(), arg0.getColumnNumber(), tempURI);
    }

    /**
     * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
     */
    public void fatalError(SAXParseException arg0) throws SAXException
    {
      addError(arg0.getMessage(), arg0.getLineNumber(), arg0.getColumnNumber(), arg0.getSystemId());
    }

    /**
     * @see org.xml.sax.ErrorHandler#warning(SAXParseException)
     */
    public void warning(SAXParseException arg0) throws SAXException
    {
      addError(arg0.getMessage(), arg0.getLineNumber(), arg0.getColumnNumber(), arg0.getSystemId());
    }
	
	/**
	 * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
	 */
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if(localName.equals("documentation") && (uri.equals(Constants.NS_URI_WSDL) || uri.equals(Constants.NS_URI_XSD_2001)|| uri.equals(Constants.NS_URI_XSD_1999) || uri.equals(Constants.NS_URI_XSD_2000)))
		{
		  isChildOfDoc = false;
		}
		super.endElement(uri, localName, qName);
	}
	/**
	 * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
	 */
	public void startElement(String uri, String localName, String qName,
			Attributes atts) throws SAXException {
		if(localName.equals("documentation") && (uri.equals(Constants.NS_URI_WSDL) || uri.equals(Constants.NS_URI_XSD_2001)|| uri.equals(Constants.NS_URI_XSD_1999) || uri.equals(Constants.NS_URI_XSD_2000)))
		{
		  isChildOfDoc = true;
		}
		super.startElement(uri, localName, qName, atts);
	}

    /**
     * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String,
     *      java.lang.String)
     */
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException
    {
      // If we're currently examining a subelement of the 
	  // WSDL or schema documentation element we don't want to resolve it
	  // as anything is allowed as a child of documentation.
	  if(isChildOfDoc)
	  {
	    return new InputSource();
	  }
    if(publicId == null)
    {
      publicId = systemId;
    }
      
    IURIResolutionResult result = uriResolver.resolve(null, publicId, systemId);
    String uri = result.getPhysicalLocation();
    if (uri != null && !uri.equals(""))
    {
	  try
	  {
//	    String entity = systemId;
//		if(publicId != null)
//		{
//		  entity = publicId;
//		 }
		URL entityURL = new URL(uri);
        InputSource is = new InputSource(result.getLogicalLocation());
		is.setByteStream(entityURL.openStream());
        if (is != null)
        {
          return is;
        }
	  }
	  catch(Exception e)
	  {
		 // Do nothing.
	  }
    }
      // This try/catch block with the IOException is here to handle a difference
      // between different versions of the EntityResolver interface.
      try
      {
        InputSource is = super.resolveEntity(publicId, systemId);
        if(is == null)
        {
          throw new IOException();
        }
        return is;
      }
      catch(IOException e)
      {
      }
      return null;
    }

  }

  /**
   * @see org.eclipse.validate.wsdl.xmlconformance.IXMLValidator#setSchemaLocation(String,
   *      String)
   */
  public void setSchemaLocation(String namespace, String location)
  {
    if (namespace != null && location != null && !namespace.equalsIgnoreCase("") && !location.equalsIgnoreCase(""))
    {
      schemaLocationString.append(" ").append(namespace).append(" ").append(formatURI(location));
    }
  }
  
  
  /**
   * @param inputStream - set the inputStream to validate
   */
  public void setInputStream(InputStream inputStream)
  {
      this.inputStream = inputStream;
  }

  /**
   * Remove space characters from a String and replace them with %20.
   * 
   * @param uri -
   *            the uri to format
   * @return the formatted string
   */
  protected String formatURI(String uri)
  {
    String space = "%20";
    StringBuffer newUri = new StringBuffer(uri);
    int newUriLength = newUri.length();

    // work backwards through the stringbuffer in case it grows to the
    // point
    // where the last space would be missed.
    for (int i = newUriLength - 1; i >= 0; i--)
    {
      if (newUri.charAt(i) == ' ')
      {
        newUri.replace(i, i + 1, space);
      }
    }

    return newUri.toString();
  }

  /**
   * A handler used in preparsing to get the schemaLocation string.
   */
  protected class SchemaStringHandler extends DefaultHandler
  {
    private final String XMLNS = "xmlns";
	  private final String TARGETNAMESPACE = "targetNamespace";
    private String baselocation = null;

    public SchemaStringHandler(String baselocation)
    {
      this.baselocation = baselocation;
    }
    /**
     * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
     *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
     */
    public void startElement(String uri, String localname, String arg2, Attributes attributes) throws SAXException
    {
      if (localname.equals(DEFINITIONS))
      {
        String targetNamespace = attributes.getValue(TARGETNAMESPACE);
        int numAtts = attributes.getLength();
        for (int i = 0; i < numAtts; i++)
        {

          String attname = attributes.getQName(i);
          if (attname.startsWith(XMLNS))
          {
            String namespace = attributes.getValue(i);
            if(!(namespace.equals(targetNamespace) || ignoredNamespaceList.contains(namespace)))
            {
              String resolvedURI = namespace;
              setSchemaLocation(namespace, resolvedURI);
            }
          }
        }

      }
      super.startElement(uri, localname, arg2, attributes);

    }
  }

  
  protected class MyStandardParserConfiguration extends StandardParserConfiguration
  {
    public MyStandardParserConfiguration()
    {
    }

    /* (non-Javadoc)
     * @see org.apache.xerces.parsers.DTDConfiguration#createErrorReporter()
     */
    protected XMLErrorReporter createErrorReporter()
    {
      return new XMLErrorReporter()
      {
        /* (non-Javadoc)
         * @see org.apache.xerces.impl.XMLErrorReporter#reportError(java.lang.String, java.lang.String, java.lang.Object[], short)
         */
        public void reportError(String domain, String key, Object[] arguments,
            short severity) throws XNIException
        {
          currentErrorKey = key;
          currentMessageArguments = arguments;
          super.reportError(domain, key, arguments, severity);
        }
      };
    }
  }
  
  
}
