/*
 * Copyright (c) 1998, 2021 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.sessions.factories;

// javase imports
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

// EclipseLink imports
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.sessions.factories.EclipseLinkObjectPersistenceRuntimeXMLProject;
import org.eclipse.persistence.internal.sessions.factories.MissingDescriptorListener;
import org.eclipse.persistence.internal.sessions.factories.ObjectPersistenceRuntimeXMLProject;
import org.eclipse.persistence.internal.sessions.factories.ObjectPersistenceRuntimeXMLProject_11_1_1;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.platform.xml.XMLParser;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.sessions.Project;

/**
 * <p><b>Purpose</b>: Allow for a EclipseLink Mapping Workbench generated deployment XML project file to be read.
 * This reader returns an instance of Project to be used to initialize a EclipseLink session.
 * This class supports reading the 11g 11.1.1 and 10g 10.1.3.
 *
 * @since TopLink 3.0
 * @author James Sutherland
 */
public class XMLProjectReader {

    /** Allow for usage of schema validation to be configurable. */
    protected static boolean shouldUseSchemaValidation = false; // switch back for 1.0

    /** Cache the creation and initialization of the EclipseLink XML mapping project. */
    protected static Project project;
    public static final String SCHEMA_DIR = "org/eclipse/persistence/";
    public static final String OPM_SCHEMA = "object-persistence_1_0.xsd";
    public static final String ECLIPSELINK_SCHEMA = "eclipselink_persistence_map_2.3.xsd";
    public static final String ECLIPSELINK_1_0_SCHEMA = "eclipselink_persistence_map_1.0.xsd";
    public static final String TOPLINK_11_SCHEMA = "toplink-object-persistence_11_1_1.xsd";
    public static final String TOPLINK_10_SCHEMA = "toplink-object-persistence_10_1_3.xsd";

    /**
     * PUBLIC:
     * Return if schema validation will be used when parsing the deployment XML.
     */
    public static boolean shouldUseSchemaValidation() {
        return shouldUseSchemaValidation;
    }

    /**
     * PUBLIC:
     * Set if schema validation will be used when parsing the deployment XML.
     * By default schema validation is on, but can be turned off if validation problems occur,
     * or to improve parsing performance.
     */
    public static void setShouldUseSchemaValidation(boolean value) {
        shouldUseSchemaValidation = value;
    }

    private XMLProjectReader() {
        super();
    }

    /**
     * PUBLIC:
     * Read the EclipseLink project deployment XML from the file or resource name.
     * If a resource name is used the default class loader will be used to resolve the resource.
     * Note the default class loader must be able to resolve the domain classes.
     * Note the file must be the deployment XML, not the Mapping Workbench project file.
     */
    public static Project read(String fileOrResourceName) {
        return read(fileOrResourceName, null);
    }


    /**
     * PUBLIC:
     * Read the EclipseLink project deployment XML from the reader on the file.
     * Note the class loader must be able to resolve the domain classes.
     * Note the file must be the deployment XML, not the Mapping Workbench project file.
     * This API supports 10g (10.0.3), 11g (11.1.1) formats.
     */
    public static Project read(Reader reader, ClassLoader classLoader) {
        // Since a reader is pass and it can only be streamed once (mark does not work)
        // It must be first read into a buffer so multiple readers can be used to
        // determine the format.  This does not effect performance severely.
        StringWriter writer;
        Document document;
        try {
            writer = new StringWriter(4096);
            char[] c = new char[4096];
            int r = 0;
            while ((r = reader.read(c)) != -1) {
                writer.write(c, 0, r);
            }
            String schema = null;
            if (shouldUseSchemaValidation()) {
                schema = SCHEMA_DIR + ECLIPSELINK_SCHEMA;
            }
            // Assume the format is OPM parse the document with OPM validation on.
            XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
            XMLParser parser = createXMLParser(xmlPlatform, true, false, schema);

            try {
                document = parser.parse(new StringReader(writer.toString()));
            } catch (Exception parseException) {
                // If the parse fails, it may be because the format was EclipseLink 1.0
                try {
                    if (shouldUseSchemaValidation()) {
                        schema = SCHEMA_DIR + ECLIPSELINK_1_0_SCHEMA;
                    }
                    parser = createXMLParser(xmlPlatform, true, false, schema);
                    document = parser.parse(new StringReader(writer.toString()));
                } catch (Exception parseException2){
                    // If the parse fails, it may be because the format was 11.1.1
                    try {
                        if (shouldUseSchemaValidation()) {
                            schema = SCHEMA_DIR + TOPLINK_11_SCHEMA;
                        }
                        parser = createXMLParser(xmlPlatform, true, false, schema);
                        document = parser.parse(new StringReader(writer.toString()));
                    } catch (Exception parseException3){
                        // If the parse validation fails, it may be because the format was 904 which is
                        // not support in eclipselink, just not valid, through original exception.
                        throw parseException;
                    }

                    String version = document.getDocumentElement().getAttribute("version");
                    // If 10.1.3 format use old format read.
                    if ((version == null) || (version.indexOf("1.0") == -1)) {
                        throw parseException;
                    }
                }
            }
        } catch (Exception exception) {
            throw XMLMarshalException.unmarshalException(exception);
        }

        String version = document.getDocumentElement().getAttribute("version");
        // If 10.1.3 format use old format read.
        if (version != null) {
            if (version.indexOf("10.1.3") != -1) {
                return read1013Format(document, classLoader);
            } else if (version.indexOf("11.1.1") != -1) {
                   return read1111Format(document, classLoader);
            }
            if (version.indexOf("TopLink") != -1) {
                //default to read 11.1.1
                return read1111Format(document, classLoader);
            }
        }


        if (project == null) {
            project = new EclipseLinkObjectPersistenceRuntimeXMLProject();
        }
        // bug261072: clone the project since readObjectPersistenceRuntimeFormat will change its datasourceLogin and Classloader
        return readObjectPersistenceRuntimeFormat(document, classLoader, project.clone());
    }

    private static XMLParser createXMLParser(XMLPlatform xmlPlatform, boolean namespaceAware, boolean whitespacePreserving, String schema){
        XMLParser parser = xmlPlatform.newXMLParser();
        parser.setNamespaceAware(namespaceAware);
        parser.setWhitespacePreserving(whitespacePreserving);
        if (schema != null) {
            parser.setValidationMode(XMLParser.SCHEMA_VALIDATION);
            // Workaround for bug #3503583.
            XMLSchemaResolver xmlSchemaResolver = new XMLSchemaResolver();
            URL eclipselinkSchemaURL = xmlSchemaResolver.resolveURL(schema);
            parser.setEntityResolver(xmlSchemaResolver);
            parser.setXMLSchema(eclipselinkSchemaURL);
        }
        return parser;
    }

    /**
     * PUBLIC:
     * Read the EclipseLink project deployment XML from the file or resource name.
     * If a resource name is used the class loader will be used to resolve the resource.
     * Note the class loader must be able to resolve the domain classes.
     * Note the file must be the deployment XML, not the Mapping Workbench project file.
     */
    public static Project read(String fileOrResourceName, ClassLoader classLoader) {
        if (fileOrResourceName.toLowerCase().indexOf(".mwp") != -1) {
            throw ValidationException.invalidFileName(fileOrResourceName);
        }
        InputStream fileStream = null;
        if (classLoader == null) {
            fileStream = (new ConversionManager()).getLoader().getResourceAsStream(fileOrResourceName);
        } else {
            fileStream = classLoader.getResourceAsStream(fileOrResourceName);
        }
        if (fileStream == null) {
            File file = new File(fileOrResourceName);
            if (!file.exists()) {
                throw ValidationException.projectXMLNotFound(fileOrResourceName, null);
            }
            try {
                fileStream = new FileInputStream(fileOrResourceName);
            } catch (FileNotFoundException exception) {
                throw ValidationException.projectXMLNotFound(fileOrResourceName, exception);
            }
        }

        InputStreamReader reader = null;
        try {
            try {
                // Bug2631348  Only UTF-8 is supported
                reader = new InputStreamReader(fileStream, "UTF-8");
            } catch (UnsupportedEncodingException exception) {
                throw ValidationException.fatalErrorOccurred(exception);
            }

            Project project = read(reader, classLoader);
            return project;
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException exception) {
                throw ValidationException.fileError(exception);
            }
        }
    }

    /**
     * INTERNAL:
     * Read the TopLink 10.1.3 deployment XML format.
     */
    public static Project read1013Format(Document document, ClassLoader classLoader) {
        Project opmProject = new ObjectPersistenceRuntimeXMLProject();
        return readObjectPersistenceRuntimeFormat(document, classLoader, opmProject);
    }
    /**
     * INTERNAL:
     * Read the TopLink 11.1.1 deployment XML format.
     */
    public static Project read1111Format(Document document, ClassLoader classLoader) {
        Project opmProject = new ObjectPersistenceRuntimeXMLProject_11_1_1();
        return readObjectPersistenceRuntimeFormat(document, classLoader, opmProject);
    }

    /**
     * Read a project in the format of an ObjectPersistenceRuntimeXMLProject.
     * This could include a TopLink 11.1.1 project or a TopLink 10.1.3 project
     */
    public static Project readObjectPersistenceRuntimeFormat(Document document, ClassLoader classLoader, Project opmProject){
        XMLLogin xmlLogin = new XMLLogin();
        xmlLogin.setDatasourcePlatform(new org.eclipse.persistence.oxm.platform.DOMPlatform());
        opmProject.setDatasourceLogin(xmlLogin);

        // Create the OPM project.
        if (classLoader != null) {
            xmlLogin.getDatasourcePlatform().getConversionManager().setLoader(classLoader);
        }
        // Marshal OPM format.
        XMLContext context = new XMLContext(opmProject);
        context.getSession(Project.class).getEventManager().addListener(new MissingDescriptorListener());
        XMLUnmarshaller unmarshaller = context.createUnmarshaller();
        Project project = (Project)unmarshaller.unmarshal(document);

        // Set the project's class loader.
        if ((classLoader != null) && (project.getDatasourceLogin() != null)) {
            project.getDatasourceLogin().getDatasourcePlatform().getConversionManager().setLoader(classLoader);
        }
        return project;
    }

    /**
     * PUBLIC:
     * Read the EclipseLink project deployment XML from the reader on the file.
     * Note the default class loader must be able to resolve the domain classes.
     * Note the file must be the deployment XML, not the Mapping Workbench project file.
     */
    public static Project read(Reader reader) {
        return read(reader, null);
    }

    /**
     * INTERNAL:
     * Workaround for bug #3503583.
     * This works around a bug in the xdk in resolving relative jar based xsd references in oc4j.
     */
    private static class XMLSchemaResolver implements EntityResolver {

        /**
         * INTERNAL:
         */
        public XMLSchemaResolver() {
            super();
        }

        /**
         * INTERNAL:
         * Resolve the XSD.
         */
        @Override
        public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
            if (OPM_SCHEMA.equals(systemId)) {
                URL url = resolveURL(SCHEMA_DIR + OPM_SCHEMA);
                if (null == url) {
                    return null;
                }
                return new InputSource(url.openStream());
            }
            return null;
        }

        /**
         * INTERNAL:
         * Return the URL for the resource.
         */
        public URL resolveURL(String resource) {
            // The xsd is always in the eclipselink.jar, use our class loader.
            return getClass().getClassLoader().getResource(resource);
        }
    }
}
