/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package org.apache.tools.ant.taskdefs.optional;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Vector;

import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.DTDLocation;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.XMLCatalog;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.JAXPUtils;
import org.apache.tools.ant.util.XmlConstants;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Parser;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.ParserAdapter;

/**
 * Checks XML files are valid (or only well formed). The
 * task uses the SAX2 parser implementation provided by JAXP by default
 * (probably the one that is used by Ant itself), but one can specify any
 * SAX1/2 parser if needed.
 *
 */
public class XMLValidateTask extends Task {

    /**
     * helper for path -> URI and URI -> path conversions.
     */
    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

    protected static final String INIT_FAILED_MSG =
        "Could not start xml validation: ";

    // ant task properties
    // defaults
    // CheckStyle:VisibilityModifier OFF - bc
    protected boolean failOnError = true;
    protected boolean warn = true;
    protected boolean lenient = false;
    protected String readerClassName = null;

    /** file to be validated */
    protected File file = null;
    /** sets of file to be validated */
    protected Vector filesets = new Vector();
    protected Path classpath;

    /**
     * the parser is viewed as a SAX2 XMLReader. If a SAX1 parser is specified,
     * it's wrapped in an adapter that make it behave as a XMLReader.
     * a more 'standard' way of doing this would be to use the JAXP1.1 SAXParser
     * interface.
     */
    protected XMLReader xmlReader = null;
    // XMLReader used to validation process
    protected ValidatorErrorHandler errorHandler = new ValidatorErrorHandler();
    // to report sax parsing errors
    // CheckStyle:VisibilityModifier ON

    /** The vector to store all attributes (features) to be set on the parser. **/
    private Vector attributeList = new Vector();

    /**
     * List of properties.
     */
    private final Vector propertyList = new Vector();

    private XMLCatalog xmlCatalog = new XMLCatalog();
    /** Message for successful validation */
    public static final String MESSAGE_FILES_VALIDATED
        = " file(s) have been successfully validated.";

    private AntClassLoader readerLoader = null;

    /**
     * Specify how parser error are to be handled.
     * Optional, default is <code>true</code>.
     * <p>
     * If set to <code>true</code> (default), throw a buildException if the
     * parser yields an error.
     * @param fail if set to <code>false</code> do not fail on error
     */
    public void setFailOnError(boolean fail) {
        failOnError = fail;
    }

    /**
     * Specify how parser error are to be handled.
     * <p>
     * If set to <code>true</code> (default), log a warn message for each SAX warn event.
     * @param bool if set to <code>false</code> do not send warnings
     */
    public void setWarn(boolean bool) {
        warn = bool;
    }

    /**
     * Specify whether the parser should be validating. Default
     * is <code>true</code>.
     * <p>
     * If set to false, the validation will fail only if the parsed document
     * is not well formed XML.
     * <p>
     * this option is ignored if the specified class
     * with {@link #setClassName(String)} is not a SAX2 XMLReader.
     * @param bool if set to <code>false</code> only fail on malformed XML
     */
    public void setLenient(boolean bool) {
        lenient = bool;
    }

    /**
     * Specify the class name of the SAX parser to be used. (optional)
     * @param className should be an implementation of SAX2
     * <code>org.xml.sax.XMLReader</code> or SAX2 <code>org.xml.sax.Parser</code>.
     * <p> if className is an implementation of
     * <code>org.xml.sax.Parser</code>, {@link #setLenient(boolean)},
     * will be ignored.
     * <p> if not set, the default will be used.
     * @see org.xml.sax.XMLReader
     * @see org.xml.sax.Parser
     */
    public void setClassName(String className) {
        readerClassName = className;
    }

    /**
     * Specify the classpath to be searched to load the parser (optional)
     * @param classpath the classpath to load the parser
     */
    public void setClasspath(Path classpath) {
        if (this.classpath == null) {
            this.classpath = classpath;
        } else {
            this.classpath.append(classpath);
        }
    }

    /**
     * @see #setClasspath
     * @return the classpath created
     */
    public Path createClasspath() {
        if (this.classpath == null) {
            this.classpath = new Path(getProject());
        }
        return this.classpath.createPath();
    }

    /**
     * Where to find the parser class; optional.
     * @see #setClasspath
     * @param r reference to a classpath defined elsewhere
     */
    public void setClasspathRef(Reference r) {
        createClasspath().setRefid(r);
    }

    /**
     * specify the file to be checked; optional.
     * @param file the file to be checked
     */
    public void setFile(File file) {
        this.file = file;
    }

    /**
     * add an XMLCatalog as a nested element; optional.
     * @param catalog XMLCatalog to use
     */
    public void addConfiguredXMLCatalog(XMLCatalog catalog) {
        xmlCatalog.addConfiguredXMLCatalog(catalog);
    }

    /**
     * specify a set of file to be checked
     * @param set the fileset to check
     */
    public void addFileset(FileSet set) {
        filesets.addElement(set);
    }

    /**
     * Add an attribute nested element. This is used for setting arbitrary
     * features of the SAX parser.
     * Valid attributes
     * <a href=
     * "http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"
     * >include</a>
     * @return attribute created
     * @since ant1.6
     */
    public Attribute createAttribute() {
        final Attribute feature = new Attribute();
        attributeList.addElement(feature);
        return feature;
    }

    /**
     * Creates a property.
     *
     * @return a property.
     * @since ant 1.6.2
     */
    public Property createProperty() {
        final Property prop = new Property();
        propertyList.addElement(prop);
        return prop;
    }

    /**
     * Called by the project to let the task initialize properly.
     *
     * @exception BuildException if something goes wrong with the build
     */
    public void init() throws BuildException {
        super.init();
        xmlCatalog.setProject(getProject());
    }

    /**
     * Create a DTD location record; optional.
     * This stores the location of a DTD. The DTD is identified
     * by its public Id.
     * @return created DTD location
     */
    public DTDLocation createDTD() {
        DTDLocation dtdLocation = new DTDLocation();
        xmlCatalog.addDTD(dtdLocation);
        return dtdLocation;
    }
    /**
     * accessor to the xmlCatalog used in the task
     * @return xmlCatalog reference
     */
    protected EntityResolver getEntityResolver() {
        return xmlCatalog;
    }

    /**
     * get the XML reader. Non-null only after {@link #initValidator()}.
     * If the reader is an instance of  {@link ParserAdapter} then
     * the parser is a SAX1 parser, and you cannot call
     * {@link #setFeature(String, boolean)} or {@link #setProperty(String, String)}
     * on it.
     * @return the XML reader or null.
     */
    protected XMLReader getXmlReader() {
        return xmlReader;
    }

    /**
     * execute the task
     * @throws BuildException if <code>failonerror</code> is true and an error happens
     */
    public void execute() throws BuildException {
        try {
        int fileProcessed = 0;
        if (file == null && (filesets.size() == 0)) {
            throw new BuildException(
                "Specify at least one source - " + "a file or a fileset.");
        }



        if (file != null) {
            if (file.exists() && file.canRead() && file.isFile()) {
                doValidate(file);
                fileProcessed++;
            } else {
                String errorMsg = "File " + file + " cannot be read";
                if (failOnError) {
                    throw new BuildException(errorMsg);
                } else {
                    log(errorMsg, Project.MSG_ERR);
                }
            }
        }

        final int size = filesets.size();
        for (int i = 0; i < size; i++) {

            FileSet fs = (FileSet) filesets.elementAt(i);
            DirectoryScanner ds = fs.getDirectoryScanner(getProject());
            String[] files = ds.getIncludedFiles();

            for (int j = 0; j < files.length; j++) {
                File srcFile = new File(fs.getDir(getProject()), files[j]);
                doValidate(srcFile);
                fileProcessed++;
            }
        }
        onSuccessfulValidation(fileProcessed);
        } finally {
            cleanup();
        }
    }

    /**
     * handler called on successful file validation.
     * @param fileProcessed number of files processed.
     */
    protected void onSuccessfulValidation(int fileProcessed) {
        log(fileProcessed + MESSAGE_FILES_VALIDATED);
    }

    /**
     * init the parser :
     * load the parser class, and set features if necessary
     * It is only after this that the reader is valid
     * @throws BuildException if something went wrong
     */
    protected void initValidator() {

        xmlReader = createXmlReader();

        xmlReader.setEntityResolver(getEntityResolver());
        xmlReader.setErrorHandler(errorHandler);

        if (!isSax1Parser()) {
            // turn validation on
            if (!lenient) {
                setFeature(XmlConstants.FEATURE_VALIDATION, true);
            }
            // set the feature from the attribute list
            final int attSize = attributeList.size();
            for (int i = 0; i < attSize; i++) {
                Attribute feature = (Attribute) attributeList.elementAt(i);
                setFeature(feature.getName(), feature.getValue());

            }
            // Sets properties
            final int propSize = propertyList.size();
            for (int i = 0; i < propSize; i++) {
                final Property prop = (Property) propertyList.elementAt(i);
                setProperty(prop.getName(), prop.getValue());
            }
        }
    }

    /**
     * test that returns true if we are using a SAX1 parser.
     * @return true when a SAX1 parser is in use
     */
    protected boolean isSax1Parser() {
        return (xmlReader instanceof ParserAdapter);
    }

    /**
     * create the XML reader.
     * This is one by instantiating anything specified by {@link #readerClassName},
     * falling back to a default reader if not.
     * If the returned reader is an instance of {@link ParserAdapter} then
     * we have created and wrapped a SAX1 parser.
     * @return the new XMLReader.
     */
    protected XMLReader createXmlReader() {
        Object reader = null;
        if (readerClassName == null) {
            reader = createDefaultReaderOrParser();
        } else {

            Class readerClass = null;
            try {
                // load the parser class
                if (classpath != null) {
                    readerLoader = getProject().createClassLoader(classpath);
                    readerClass = Class.forName(readerClassName, true,
                                                readerLoader);
                } else {
                    readerClass = Class.forName(readerClassName);
                }

                reader = readerClass.newInstance();
            } catch (ClassNotFoundException e) {
                throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
            } catch (InstantiationException e) {
                throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
            } catch (IllegalAccessException e) {
                throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
            }
        }

        // then check it implements XMLReader
        XMLReader newReader;
        if (reader instanceof XMLReader) {
            newReader = (XMLReader) reader;
            log(
                "Using SAX2 reader " + reader.getClass().getName(),
                Project.MSG_VERBOSE);
        } else {

            // see if it is a SAX1 Parser
            if (reader instanceof Parser) {
                newReader = new ParserAdapter((Parser) reader);
                log(
                    "Using SAX1 parser " + reader.getClass().getName(),
                    Project.MSG_VERBOSE);
            } else {
                throw new BuildException(
                    INIT_FAILED_MSG
                        + reader.getClass().getName()
                        + " implements nor SAX1 Parser nor SAX2 XMLReader.");
            }
        }
        return newReader;
    }

    /**
     * Cleans up resources.
     *
     * @since Ant 1.8.0
     */
    protected void cleanup() {
        if (readerLoader != null) {
            readerLoader.cleanup();
            readerLoader = null;
        }
    }

    /**
     * Returns a SAX-based XMLReader or a SAX-based Parser.
     * @return reader or parser
     */
    private Object createDefaultReaderOrParser() {
        Object reader;
        try {
            reader = createDefaultReader();
        } catch (BuildException exc) {
            reader = JAXPUtils.getParser();
        }
        return reader;
    }

    /**
     * Create a reader if the use of the class did not specify another one.
     * If a BuildException is thrown, the caller may revert to an alternate
     * reader.
     * @return a new reader.
     * @throws BuildException if something went wrong
     */
    protected XMLReader createDefaultReader() {
        return JAXPUtils.getXMLReader();
    }

    /**
     * Set a feature on the parser.
     * @param feature the name of the feature to set
     * @param value the value of the feature
     * @throws BuildException if the feature was not supported
     */
    protected void setFeature(String feature, boolean value)
        throws BuildException {
        log("Setting feature " + feature + "=" + value, Project.MSG_DEBUG);
        try {
            xmlReader.setFeature(feature, value);
        } catch (SAXNotRecognizedException e) {
            throw new BuildException(
                "Parser "
                    + xmlReader.getClass().getName()
                    + " doesn't recognize feature "
                    + feature,
                e,
                getLocation());
        } catch (SAXNotSupportedException e) {
            throw new BuildException(
                "Parser "
                    + xmlReader.getClass().getName()
                    + " doesn't support feature "
                    + feature,
                e,
                getLocation());
        }
    }

    /**
     * Sets a property.
     *
     * @param name a property name
     * @param value a property value.
     * @throws BuildException if an error occurs.
     * @throws BuildException if the property was not supported
     */
    protected void setProperty(String name, String value) throws BuildException {
        // Validates property
        if (name == null || value == null) {
            throw new BuildException("Property name and value must be specified.");
        }

        try {
            xmlReader.setProperty(name, value);
        } catch (SAXNotRecognizedException e) {
            throw new BuildException(
                "Parser "
                    + xmlReader.getClass().getName()
                    + " doesn't recognize property "
                    + name,
                e,
                getLocation());
        } catch (SAXNotSupportedException e) {
            throw new BuildException(
                "Parser "
                    + xmlReader.getClass().getName()
                    + " doesn't support property "
                    + name,
                e,
                getLocation());
        }
    }

    /**
     * parse the file
     * @param afile the file to validate.
     * @return true if the file validates.
     */
    protected boolean doValidate(File afile) {
        //for every file, we have a new instance of the validator
        initValidator();
        boolean result = true;
        try {
            log("Validating " + afile.getName() + "... ", Project.MSG_VERBOSE);
            errorHandler.init(afile);
            InputSource is = new InputSource(new FileInputStream(afile));
            String uri = FILE_UTILS.toURI(afile.getAbsolutePath());
            is.setSystemId(uri);
            xmlReader.parse(is);
        } catch (SAXException ex) {
            log("Caught when validating: " + ex.toString(), Project.MSG_DEBUG);
            if (failOnError) {
                throw new BuildException(
                    "Could not validate document " + afile);
            }
            log("Could not validate document " + afile + ": " + ex.toString());
            result = false;
        } catch (IOException ex) {
            throw new BuildException(
                "Could not validate document " + afile,
                ex);
        }
        if (errorHandler.getFailure()) {
            if (failOnError) {
                throw new BuildException(
                    afile + " is not a valid XML document.");
            }
            result = false;
            log(afile + " is not a valid XML document", Project.MSG_ERR);
        }
        return result;
    }

    /**
     * ValidatorErrorHandler role :
     * <ul>
     * <li> log SAX parse exceptions,
     * <li> remember if an error occurred
     * </ul>
     */
    protected class ValidatorErrorHandler implements ErrorHandler {

        // CheckStyle:VisibilityModifier OFF - bc
        protected File currentFile = null;
        protected String lastErrorMessage = null;
        protected boolean failed = false;
        // CheckStyle:VisibilityModifier ON
        /**
         * initialises the class
         * @param file file used
         */
        public void init(File file) {
            currentFile = file;
            failed = false;
        }
        /**
         * did an error happen during last parsing ?
         * @return did an error happen during last parsing ?
         */
        public boolean getFailure() {
            return failed;
        }

        /**
         * record a fatal error
         * @param exception the fatal error
         */
        public void fatalError(SAXParseException exception) {
            failed = true;
            doLog(exception, Project.MSG_ERR);
        }
        /**
         * receive notification of a recoverable error
         * @param exception the error
         */
        public void error(SAXParseException exception) {
            failed = true;
            doLog(exception, Project.MSG_ERR);
        }
        /**
         * receive notification of a warning
         * @param exception the warning
         */
        public void warning(SAXParseException exception) {
            // depending on implementation, XMLReader can yield hips of warning,
            // only output then if user explicitly asked for it
            if (warn) {
                doLog(exception, Project.MSG_WARN);
            }
        }

        private void doLog(SAXParseException e, int logLevel) {

            log(getMessage(e), logLevel);
        }

        private String getMessage(SAXParseException e) {
            String sysID = e.getSystemId();
            if (sysID != null) {
                String name = sysID;
                if (sysID.startsWith("file:")) {
                    try {
                        name = FILE_UTILS.fromURI(sysID);
                    } catch (Exception ex) {
                        // if this is not a valid file: just use the uri
                    }
                }
                int line = e.getLineNumber();
                int col = e.getColumnNumber();
                return  name
                    + (line == -1
                       ? ""
                       : (":" + line + (col == -1 ? "" : (":" + col))))
                    + ": "
                    + e.getMessage();
            }
            return e.getMessage();
        }
    }

    /**
     * The class to create to set a feature of the parser.
     * @since ant1.6
     */
    public static class Attribute {
        /** The name of the attribute to set.
         *
         * Valid attributes <a href=
         * "http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"
         * >include.</a>
         */
        private String attributeName = null;

        /**
         * The value of the feature.
         **/
        private boolean attributeValue;

        /**
         * Set the feature name.
         * @param name the name to set
         */
        public void setName(String name) {
            attributeName = name;
        }
        /**
         * Set the feature value to true or false.
         * @param value feature value
         */
        public void setValue(boolean value) {
            attributeValue = value;
        }

        /**
         * Gets the attribute name.
         * @return the feature name
         */
        public String getName() {
            return attributeName;
        }

        /**
         * Gets the attribute value.
         * @return the feature value
         */
        public boolean getValue() {
            return attributeValue;
        }
    }

    /**
     * A Parser property.
     * See <a href="http://xml.apache.org/xerces-j/properties.html">
     * XML parser properties</a> for usable properties
     * @since ant 1.6.2
     */
    public static final class Property {

        private String name;
        private String value;
        /**
         * accessor to the name of the property
         * @return name of the property
         */
        public String getName() {
            return name;
        }
        /**
         * setter for the name of the property
         * @param name name of the property
         */
        public void setName(String name) {
            this.name = name;
        }

        /**
         * getter for the value of the property
         * @return value of the property
         */
        public String getValue() {
            return value;
        }
        /**
         * sets the value of the property
         * @param value value of the property
         */
        public void setValue(String value) {
            this.value = value;
        }

    } // Property



}
