/*******************************************************************************
 * Copyright (c) 2001, 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.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.List;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;

import org.apache.xerces.impl.XMLErrorReporter;
import org.apache.xerces.parsers.SAXParser;
import org.apache.xerces.parsers.StandardParserConfiguration;
import org.apache.xerces.xni.XMLResourceIdentifier;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.grammars.XMLGrammarPool;
import org.apache.xerces.xni.parser.XMLEntityResolver;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.eclipse.wst.wsdl.validation.internal.ValidationMessageImpl;
import org.eclipse.wst.wsdl.validation.internal.logging.ILogger;
import org.eclipse.wst.wsdl.validation.internal.logging.LoggerFactory;
import org.eclipse.wst.wsdl.validation.internal.resolver.IURIResolutionResult;
import org.eclipse.wst.wsdl.validation.internal.resolver.URIResolver;
import org.eclipse.wst.wsdl.validation.internal.wsdl11.xsd.XSDValidator;
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.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import com.ibm.wsdl.Constants;

/**
 * The default implementation of IXMLValidator.
 */
public class DefaultXMLValidator implements IXMLValidator
{
  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 XMLGrammarPool grammarPool = null; 
  
  /**
   * A stack of start tag locations, used to move errors
   * reported at the close tag to be reported at the start tag.
   */
  protected Stack startElementLocations = new Stack();
  protected Set adjustLocationErrorKeySet = new TreeSet();

/**
   * 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);
    
    adjustLocationErrorKeySet.add("cvc-complex-type.2.4.b");
    adjustLocationErrorKeySet.add("cvc-complex-type.2.3");
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.validation.internal.xml.IXMLValidator#setFile(java.lang.String)
   */
  public void setFile(String uri)
  {
    this.uri = uri;
  }
  
  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.validation.internal.xml.IXMLValidator#setURIResolver(org.eclipse.wst.wsdl.validation.internal.resolver.URIResolver)
   */
  public void setURIResolver(URIResolver uriResolver)
  {
  	this.uriResolver = uriResolver;
  }
  
  /**
   * @param grammarPool
   */
  public void setGrammarPool(XMLGrammarPool grammarPool)
  {
	this.grammarPool = grammarPool;
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.validation.internal.xml.IXMLValidator#run()
   */
  public void run()
  {
    // Validate the XML file.
    try
    {
      Reader reader1 = null; // Used for validation parse.
      
      InputSource validateInputSource; 
     
      validateInputSource = new InputSource(uri);
      if (this.inputStream != null)
      {    
        String string = createStringForInputStream(inputStream);
        reader1 = new StringReader(string);
          
        validateInputSource.setByteStream(inputStream);
        validateInputSource.setCharacterStream(reader1);
      }
      
      XMLReader reader = createXMLReader();
      reader.parse(validateInputSource);
    }
    catch (SAXParseException e)
    {
      // No need to add an error here. SAXParseExceptions are reported by the error reporter.
    }
    catch (IOException e)
    {
      // No need to log this error. The WSDL validator will catch this error when creating the dom model.
      //LoggerFactory.getInstance().getLogger().log("The WSDL validator was unable to read file " + uri + ".", ILogger.SEV_ERROR, e);
    }
    catch (Exception e)
    {
      LoggerFactory.getInstance().getLogger().log("An exception occurred while performing WSDL XML conformance validation for file " + uri + ".", ILogger.SEV_ERROR, e);
    }
  }
  
  /**
   * @param inputStream
   * @return
   */
  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)
    {
      LoggerFactory.getInstance().getLogger().log("The WSDL valdiator was unable to create to create a string representation of an input stream. WSDL XML validation may not have run correctly.", ILogger.SEV_ERROR, e);
    }
    return fileString.toString();
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.validation.internal.xml.IXMLValidator#hasErrors()
   */
  public boolean hasErrors()
  {
    return !errors.isEmpty();
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.validation.internal.xml.IXMLValidator#getErrors()
   */
  public List getErrors()
  {
    return errors;
  }
  
  /**
   * @param message
   * @param line
   * @param column
   * @param uri
   */
  public void addError(String message, int line, int column, String uri)
  {
	// For the following errors the line number will be modified to use that of the start
  	// tag instead of the end tag.
  	if (currentErrorKey != null && adjustLocationErrorKeySet.contains(currentErrorKey))  
  	{
  	  LocationCoordinate adjustedCoordinates = (LocationCoordinate)startElementLocations.peek();
  	  line = adjustedCoordinates.getLineNumber();
  	  column = adjustedCoordinates.getColumnNumner();
  	}
  	
	errors.add(new ValidationMessageImpl(message, line, column, ValidationMessageImpl.SEV_WARNING, 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
  {
	private Locator locator = null;
	
    public void setDocumentLocator(Locator locator) 
    {
		this.locator = locator;
		super.setDocumentLocator(locator);
	}

	/**
     * @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);
		startElementLocations.pop();
	}
	/**
	 * @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 {
		startElementLocations.push(new LocationCoordinate(locator.getLineNumber(), locator.getColumnNumber()));
		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);
	}
  }
  
  /**
   * @param inputStream - set the inputStream to validate
   */
  public void setInputStream(InputStream inputStream)
  {
      this.inputStream = inputStream;
  }
  
  protected class XMLValidatorParserConfiguration extends StandardParserConfiguration
  {
	/* (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);
        }
      };
    }
  }
  
  /**
   * Create an XML Reader.
   * 
   * @return The newly created XML reader or null if unsuccessful.
   * @throws Exception
   */
  protected XMLReader createXMLReader() throws Exception
  {     
    SAXParser reader = null;
    try
    {
      reader = new org.apache.xerces.parsers.SAXParser(new XMLValidatorParserConfiguration());
      
      XMLConformanceDefaultHandler conformanceDefaultHandler = new XMLConformanceDefaultHandler();
      reader.setErrorHandler(conformanceDefaultHandler);
      reader.setContentHandler(conformanceDefaultHandler);
      
      // Older Xerces versions will thrown a NPE if a null grammar pool is set.
      if(grammarPool != null)
      {
        reader.setProperty(org.apache.xerces.impl.Constants.XERCES_PROPERTY_PREFIX + org.apache.xerces.impl.Constants.XMLGRAMMAR_POOL_PROPERTY, grammarPool);
      }
      reader.setProperty(org.apache.xerces.impl.Constants.XERCES_PROPERTY_PREFIX + org.apache.xerces.impl.Constants.ENTITY_RESOLVER_PROPERTY, new MyEntityResolver(uriResolver));
      reader.setFeature(org.apache.xerces.impl.Constants.XERCES_FEATURE_PREFIX + org.apache.xerces.impl.Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE, false);
      reader.setFeature(org.apache.xerces.impl.Constants.SAX_FEATURE_PREFIX + org.apache.xerces.impl.Constants.NAMESPACES_FEATURE, true);
      reader.setFeature(org.apache.xerces.impl.Constants.SAX_FEATURE_PREFIX + org.apache.xerces.impl.Constants.NAMESPACE_PREFIXES_FEATURE, true);
	  reader.setFeature(org.apache.xerces.impl.Constants.SAX_FEATURE_PREFIX + org.apache.xerces.impl.Constants.VALIDATION_FEATURE, true);
	  reader.setFeature(org.apache.xerces.impl.Constants.XERCES_FEATURE_PREFIX + org.apache.xerces.impl.Constants.SCHEMA_VALIDATION_FEATURE, true);
    } 
    catch(Exception e)
    { 
      LoggerFactory.getInstance().getLogger().log("Error creating XML reader for WSDL XML conformance validation.", ILogger.SEV_ERROR, e);
    }
    return reader;
  } 
  
  /**
   * A custom entity resolver that uses the URI resolver specified to resolve entities.
   */
  protected class MyEntityResolver implements XMLEntityResolver 
  {
    private URIResolver uriResolver;
    
    /**
     * Constructor.
     * 
     * @param uriResolver The URI resolver to use with this entity resolver.
     */
    public MyEntityResolver(URIResolver uriResolver)
    {
      this.uriResolver = uriResolver;
    }
    
    /* (non-Javadoc)
     * @see org.apache.xerces.xni.parser.XMLEntityResolver#resolveEntity(org.apache.xerces.xni.XMLResourceIdentifier)
     */
    public XMLInputSource resolveEntity(XMLResourceIdentifier rid) throws XNIException, IOException
    {
      // 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 XMLInputSource(rid);
	  }
	  
	  boolean nsUsed = false;
	  
	  String ns = rid.getNamespace();
	  if(ns != null && ignoredNamespaceList.contains(ns))
	  {
		return new XMLInputSource(rid);
	  }
	  
	  String systemId = rid.getLiteralSystemId();
	  if(systemId == null)
	  {
		systemId = ns;
		nsUsed = true;
	  }
	  String publicId = rid.getPublicId();
      if(publicId == null)
      {
        publicId = systemId;
      }
      
      // Xerces tends to try to resolve locations with no information.
      // No need to do any processing if we have no information.
      if(publicId != null || systemId != null)
      {
        IURIResolutionResult result = uriResolver.resolve("", publicId, systemId);
        String uri = result.getPhysicalLocation();
        if (uri != null && !uri.equals(""))
        {
          // If the namespace was used to resolve this reference ensure a schema
          // has been returned. Namespaces tend to point to Web resources that
          // may or may not be schemas.
          boolean createEntityResult = true;
          if(nsUsed)
          {
        	XSDValidator xsdVal = new XSDValidator();
        	xsdVal.validate(uri, uriResolver, null);
        	if(!xsdVal.isValid())
        	  createEntityResult = false;
          }
          
          if(createEntityResult)
          {
	        try
	        {
		      URL entityURL = new URL(uri);
              XMLInputSource is = new XMLInputSource(rid.getPublicId(), systemId, result.getLogicalLocation());
		      is.setByteStream(entityURL.openStream());
              if (is != null)
              {
                return is;
              }
	        }
	        catch(Exception e)
	        {
		      // No need to report this error. Simply continue below.
	        }
          }
        }
      }
      return null;
    }
  }  
  
  /** 
   * A line and column number coordinate.
   */
  protected class LocationCoordinate
  {	
	private int lineNo = -1;
    private int columnNo = -1;
    
    public LocationCoordinate(int lineNumber, int columnNumber)
    {
      this.lineNo = lineNumber;
      this.columnNo = columnNumber;
    }
    	
    public int getLineNumber()
    { 
      return this.lineNo;
    }
    	
    public int getColumnNumner()
    { 
      return this.columnNo;
    } 
  }
}
