/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.platform.xml.jaxp;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.validation.Schema;

import org.eclipse.persistence.internal.helper.XMLHelper;
import org.eclipse.persistence.platform.xml.DefaultErrorHandler;
import org.eclipse.persistence.platform.xml.SAXDocumentBuilder;
import org.eclipse.persistence.platform.xml.XMLParser;
import org.eclipse.persistence.platform.xml.XMLPlatformException;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * <p><b>Purpose</b>:  An implementation of XMLParser using JAXP 1.3 APIs.</p>
 *
 * <p>JAXPParser is NOT thread safe.</p>
 */
public class JAXPParser implements XMLParser {
    private static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
    private static final String XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
    private static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
    private DocumentBuilderFactory documentBuilderFactory;
    private EntityResolver entityResolver;
    private ErrorHandler errorHandler;
    private DocumentBuilder documentBuilder;
    private TransformerFactory transformerFactory;

    /**
     * Default constructor.
     */
    public JAXPParser() {
        super();
        errorHandler = DefaultErrorHandler.getInstance();
    }

    /**
     * This constructor can increase performance by providing existing documentBuilderFactory and errorHandler.
     *
     * @param documentBuilderFactory existing document builder factory
     * @param errorHandler existing error handler
     */
    public JAXPParser(DocumentBuilderFactory documentBuilderFactory, ErrorHandler errorHandler) {
        super();

        this.documentBuilderFactory = documentBuilderFactory;
        if (null != errorHandler) {
            this.errorHandler = errorHandler;
        } else {
            this.errorHandler = DefaultErrorHandler.getInstance();
        }
    }

    /**
     * This constructor provides way to specify features for parser.
     *
     * @param parserFeatures features for parser
     */
    public JAXPParser(Map<String, Boolean> parserFeatures) {
        this();
        loadDocumentBuilderFactory();
        try {
            if(null != parserFeatures) {
                for(Entry<String, Boolean> entry : parserFeatures.entrySet()) {
                    documentBuilderFactory.setFeature(entry.getKey(), entry.getValue());
                }
            }
        } catch(Exception e) {
            throw XMLPlatformException.xmlPlatformParseException(e);
        }
    }

    private void loadDocumentBuilderFactory() {
        documentBuilderFactory = XMLHelper.createDocumentBuilderFactory(false);
        setNamespaceAware(true);
        setWhitespacePreserving(false);
    }

    /**
     * Changes namespaceAware behavior of the parser.
     *
     * @param isNamespaceAware if the parser should be namespace aware
     */
    @Override
    public void setNamespaceAware(boolean isNamespaceAware) {
        if (null == documentBuilderFactory) {
            loadDocumentBuilderFactory();
        }
        documentBuilderFactory.setNamespaceAware(isNamespaceAware);
    }

    /**
     * Changes preservation of white spaces.
     *
     * @param isWhitespacePreserving if the parser should preserve white spaces
     */
    @Override
    public void setWhitespacePreserving(boolean isWhitespacePreserving) {
        if (null == documentBuilderFactory) {
            loadDocumentBuilderFactory();
        }
        documentBuilderFactory.setIgnoringElementContentWhitespace(!isWhitespacePreserving);
    }

    /**
     * Returns validtion mode of the parser.
     *
     * @return validation mode of the parser
     */
    @Override
    public int getValidationMode() {
        if (null == documentBuilderFactory) {
            loadDocumentBuilderFactory();
        }
        if (!documentBuilderFactory.isValidating()) {
            return XMLParser.NONVALIDATING;
        }

        try {
            if (null == documentBuilderFactory.getAttribute(SCHEMA_LANGUAGE)) {
                return XMLParser.DTD_VALIDATION;
            }
        } catch (IllegalArgumentException e) {
            return XMLParser.DTD_VALIDATION;
        }

        return XMLParser.SCHEMA_VALIDATION;
    }

    /**
     * Sets validation mode of the parser.
     *
     * @param validationMode validation mode to set
     */
    @Override
    public void setValidationMode(int validationMode) {
        if (null == documentBuilderFactory) {
            loadDocumentBuilderFactory();
        }
        switch (validationMode) {
        case XMLParser.NONVALIDATING: {
            documentBuilderFactory.setValidating(false);
            // documentBuilderFactory.setAttribute(SCHEMA_LANGUAGE, null);
            return;
        }
        case XMLParser.DTD_VALIDATION: {
            documentBuilderFactory.setValidating(true);
            XMLHelper.allowExternalDTDAccess(documentBuilderFactory, "all", false);
            // documentBuilderFactory.setAttribute(SCHEMA_LANGUAGE, null);
            return;
        }
        case XMLParser.SCHEMA_VALIDATION: {
            try {
                documentBuilderFactory.setAttribute(SCHEMA_LANGUAGE, XML_SCHEMA);
                documentBuilderFactory.setValidating(true);
                XMLHelper.allowExternalAccess(documentBuilderFactory, "all", false);
            } catch (IllegalArgumentException e) {
                // This parser does not support XML Schema validation so leave it as
                // a non-validating parser.
            }
            return;
        }
        }
    }

    /**
     * Returns entity resolver of the parser.
     *
     * @return entity resolver of the parser
     */
    @Override
    public EntityResolver getEntityResolver() {
        return entityResolver;
    }

    /**
     * Sets entity resolver for the parser.
     *
     * @param entityResolver entity resolver to set
     */
    @Override
    public void setEntityResolver(EntityResolver entityResolver) {
        this.entityResolver = entityResolver;
    }

    /**
     * Returns error handler of the parser.
     *
     * @return error handler of the parser
     */
    @Override
    public ErrorHandler getErrorHandler() {
        return errorHandler;
    }

    /**
     * Sets error handler for the parser.
     *
     * @param errorHandler error handler for the parser
     */
    @Override
    public void setErrorHandler(ErrorHandler errorHandler) {
        this.errorHandler = errorHandler;
    }

    /**
     * Sets XML Schema for the parser.
     *
     * @param url url of the XMLSchema
     * @throws XMLPlatformException exception occurred while setting XMLSchema
     */
    @Override
    public void setXMLSchema(URL url) throws XMLPlatformException {
        if (null == url) {
            return;
        }
        if (null == documentBuilderFactory) {
            loadDocumentBuilderFactory();
        }
        try {
            documentBuilderFactory.setAttribute(SCHEMA_LANGUAGE, XML_SCHEMA);
            documentBuilderFactory.setAttribute(JAXP_SCHEMA_SOURCE, url.toString());
        } catch (IllegalArgumentException e) {
            // The attribute isn't supported so do nothing
        } catch (Exception e) {
            XMLPlatformException.xmlPlatformErrorResolvingXMLSchema(url, e);
        }
    }

    /**
     * Sets XML Schema for the parser.
     *
     * @param schema schema for the parser
     * @throws XMLPlatformException exception occurred while setting XMLSchema
     */
    @Override
    public void setXMLSchema(Schema schema) throws XMLPlatformException {
        documentBuilderFactory.setSchema(schema);
    }

    /**
     * Returns XML Schema of the parser.
     *
     * @return schema of the parser
     * @throws XMLPlatformException exception occurred while getting XMLSchema
     */
    @Override
    public Schema getXMLSchema() throws XMLPlatformException {
        return documentBuilderFactory.getSchema();
    }

    /**
     * Sets XML Schema(s) for the parser.
     *
     * @param schemas XML schemas to set
     * @throws XMLPlatformException exception occurred while setting XMLSchema(s)
     */
    @Override
    public void setXMLSchemas(Object[] schemas) throws XMLPlatformException {
        if ((null == schemas) || (schemas.length == 0)) {
            return;
        }
        if (null == documentBuilderFactory) {
            loadDocumentBuilderFactory();
        }
        try {
            documentBuilderFactory.setAttribute(SCHEMA_LANGUAGE, XML_SCHEMA);
            documentBuilderFactory.setAttribute(JAXP_SCHEMA_SOURCE, schemas);
        } catch (IllegalArgumentException e) {
            // The attribute isn't supported so do nothing
        } catch (Exception e) {
            XMLPlatformException.xmlPlatformErrorResolvingXMLSchemas(schemas, e);
        }
    }

    /**
     * Parses given input source.
     *
     * @param inputSource input source to parse
     * @return parsed document
     * @throws XMLPlatformException exception occurred while parsing input source
     */
    @Override
    public Document parse(InputSource inputSource) throws XMLPlatformException {
        try {
            return getDocumentBuilder().parse(inputSource);
        } catch (SAXException e) {
            throw XMLPlatformException.xmlPlatformParseException(e);
        } catch (IOException e) {
            throw XMLPlatformException.xmlPlatformParseException(e);
        }
    }

    /**
     * Parses given file.
     *
     * @param file file to parse
     * @return parsed document
     * @throws XMLPlatformException exception occurred while parsing given file
     */
    @Override
    public Document parse(File file) throws XMLPlatformException {
        try {
            return getDocumentBuilder().parse(file);
        } catch (SAXParseException e) {
            throw XMLPlatformException.xmlPlatformSAXParseException(e);
        } catch (SAXException e) {
            throw XMLPlatformException.xmlPlatformParseException(e);
        } catch (IOException e) {
            throw XMLPlatformException.xmlPlatformFileNotFoundException(file, e);
        }
    }

    /**
     * Parses given input stream.
     *
     * @param inputStream input stream to parse
     * @return parsed document
     * @throws XMLPlatformException exception occurred while parsing input stream
     */
    @Override
    public Document parse(InputStream inputStream) throws XMLPlatformException {
        try {
            return getDocumentBuilder().parse(inputStream);
        } catch (SAXParseException e) {
            throw XMLPlatformException.xmlPlatformSAXParseException(e);
        } catch (SAXException e) {
            throw XMLPlatformException.xmlPlatformParseException(e);
        } catch (IOException e) {
            throw XMLPlatformException.xmlPlatformParseException(e);
        }
    }

    /**
     * Parses given reader.
     *
     * @param reader reader to parse
     * @return parsed document
     * @throws XMLPlatformException exception occurred while parsing given reader
     */
    @Override
    public Document parse(Reader reader) throws XMLPlatformException {
        InputSource inputSource = new InputSource(reader);
        return parse(inputSource);
    }

    /**
     * Parses given source.
     *
     * @param source source to parse
     * @return parsed document
     * @throws XMLPlatformException exception occurred while parsing given source
     */
    @Override
    public Document parse(Source source) throws XMLPlatformException {
        try {
            if (null == transformerFactory) {
                transformerFactory = XMLHelper.createTransformerFactory(false);
            }
            Transformer transformer = transformerFactory.newTransformer();
            SAXResult saxResult = new SAXResult();
            SAXDocumentBuilder builder = new SAXDocumentBuilder();
            saxResult.setHandler(builder);
            transformer.transform(source, saxResult);
            return builder.getDocument();
        } catch (TransformerException e) {
            throw XMLPlatformException.xmlPlatformParseException(e);
        }
    }

    /**
     * Parses given url.
     *
     * @param url url to parse
     * @return parsed document
     * @throws XMLPlatformException exception occurred while parsing stream with given url
     */
    @Override
    public Document parse(URL url) throws XMLPlatformException {
        InputStream inputStream = null;
        try {
            inputStream = url.openStream();
        } catch (IllegalArgumentException | IOException e) {
            throw XMLPlatformException.xmlPlatformParseException(e);
        }

        boolean hasThrownException = false;
        try {
            return parse(inputStream);
        } catch (RuntimeException e) {
            hasThrownException = true;
            throw e;
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                if (!hasThrownException) {
                    //don't override runtime exception
                    throw XMLPlatformException.xmlPlatformParseException(e);
                }
            }
        }
    }

    private DocumentBuilder getDocumentBuilder() {
        try {
            if (null == documentBuilder) {
                documentBuilder = getNewDocumentBuilder();
            } else {
                try {
                    documentBuilder.reset();
                } catch (UnsupportedOperationException uoe) {
                    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=490229
                    // if reset is not supported by the parser, just return new one
                    documentBuilder = getNewDocumentBuilder();
                }
            }

            return documentBuilder;
        } catch (ParserConfigurationException e) {
            throw XMLPlatformException.xmlPlatformParseException(e);
        }
    }

    private DocumentBuilder getNewDocumentBuilder() throws ParserConfigurationException {
        if (null == documentBuilderFactory) {
            loadDocumentBuilderFactory();
        }
        DocumentBuilder newDb = documentBuilderFactory.newDocumentBuilder();
        newDb.setEntityResolver(entityResolver);
        newDb.setErrorHandler(errorHandler);
        return newDb;
    }
}
