/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2018 IBM 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
//     05/16/2008-1.0M8 Guy Pelletier
//       - 218084: Implement metadata merging functionality between mapping file
//     09/23/2008-1.1 Guy Pelletier
//       - 241651: JPA 2.0 Access Type support
//     12/10/2008-1.1 Michael O'Brien
//       - 257606: Add orm.xml schema validation true/(false) flag support in persistence.xml
//     03/27/2009-2.0 Guy Pelletier
//       - 241413: JPA 2.0 Add EclipseLink support for Map type attributes
//     10/09/2012-2.5 Guy Pelletier
//       - 374688: JPA 2.1 Converter support
//     02/14/2013-2.5 Guy Pelletier
//       - 338610: JPA 2.1 Functionality for Java EE 7 (JSR-338)
//     09/06/2017-2.7 Jody Grassel
//       - 521954: Eclipselink is not able to parse ORM XML files using the 2.2 schema
package org.eclipse.persistence.internal.jpa.metadata.xml;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Map;
import java.util.Properties;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.helper.XMLHelper;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;

/**
 * ORM.xml reader.
 *
 * @author Guy Pelletier
 * @since EclipseLink 1.0
 */
public class XMLEntityMappingsReader {
    public static final String ORM_1_0_XSD = "org/eclipse/persistence/jpa/orm_1_0.xsd";
    public static final String ORM_1_0_NAMESPACE = "http://java.sun.com/xml/ns/persistence/orm";
    public static final String ORM_2_0_XSD = "org/eclipse/persistence/jpa/orm_2_0.xsd";
    public static final String ORM_2_0_NAMESPACE = "http://java.sun.com/xml/ns/persistence/orm";
    public static final String ORM_2_1_XSD = "org/eclipse/persistence/jpa/orm_2_1.xsd";
    public static final String ORM_2_1_NAMESPACE = "http://xmlns.jcp.org/xml/ns/persistence/orm";
    public static final String ORM_2_2_XSD = "org/eclipse/persistence/jpa/orm_2_2.xsd";
    public static final String ORM_2_2_NAMESPACE = "http://xmlns.jcp.org/xml/ns/persistence/orm";
    public static final String ORM_3_0_XSD = "org/eclipse/persistence/jpa/orm_3_0.xsd";
    public static final String ORM_3_0_NAMESPACE = "https://jakarta.ee/xml/ns/persistence/orm";
    public static final String ECLIPSELINK_ORM_XSD = "org/eclipse/persistence/jpa/eclipselink_orm_2_5.xsd";
    public static final String ECLIPSELINK_ORM_NAMESPACE = "http://www.eclipse.org/eclipselink/xsds/persistence/orm";

    private static XMLContext m_orm1_0Project;
    private static XMLContext m_orm2_0Project;
    private static XMLContext m_orm2_1Project;
    private static XMLContext m_orm2_2Project;
    private static XMLContext m_orm3_0Project;
    private static XMLContext m_eclipseLinkOrmProject;

    private static Schema m_orm1_0Schema;
    private static Schema m_orm2_0Schema;
    private static Schema m_orm2_1Schema;
    private static Schema m_orm2_2Schema;
    private static Schema m_orm3_0Schema;
    private static Schema m_eclipseLinkOrmSchema;

    private XMLEntityMappingsReader() {
    }

    /**
     * Check the orm.xml to determine which project and schema to use.
     * EclipseLink ORM is used if input Reader is null
     */
    private static Object[] determineXMLContextAndSchema(String file, Reader input, boolean validateSchema) throws Exception {
        Object[] context = new Object[2];
        if (input == null) {
            // No input, default it to the eclipselink orm project.
            context[0] = getEclipseLinkOrmProject();
            if (validateSchema) {
                context[1] = getEclipseLinkOrmSchema();
            }
        } else {
            SAXParserFactory factory = XMLHelper.createParserFactory(false);

            // create a SAX parser
            SAXParser parser = factory.newSAXParser();

            // create an XMLReader
            XMLReader xmlReader = parser.getXMLReader();

            ORMContentHandler contentHandler = new ORMContentHandler();
            xmlReader.setContentHandler(contentHandler);
            InputSource inputSource = new InputSource(input);
            xmlReader.parse(inputSource);

            if (contentHandler.isEclipseLink()) {
                context[0] = getEclipseLinkOrmProject();
                if (validateSchema) {
                    context[1] = getEclipseLinkOrmSchema();
                }
            } else if (contentHandler.getVersion() == null || contentHandler.getVersion().contains("1.")) {
                context[0] = getOrm1_0Project();
                if (validateSchema) {
                    context[1] = getOrm1_0Schema();
                }
            } else if (contentHandler.getVersion().contains("2.0")) {
                context[0] = getOrm2_0Project();
                if (validateSchema) {
                    context[1] = getOrm2_0Schema();
                }
            } else if (contentHandler.getVersion().contains("2.1")) {
                context[0] = getOrm2_1Project();
                if (validateSchema) {
                    context[1] = getOrm2_1Schema();
                }
            } else if (contentHandler.getVersion().contains("2.2")) {
                context[0] = getOrm2_2Project();
                if (validateSchema) {
                    context[1] = getOrm2_2Schema();
                }
            } else {
                context[0] = getOrm3_0Project();
                if (validateSchema) {
                    context[1] = getOrm3_0Schema();
                }
            }
        }

        return context;
    }

    /**
     * @return the Eclipselink orm project.
     */
    public static XMLContext getEclipseLinkOrmProject() {
        if (m_eclipseLinkOrmProject == null) {
            m_eclipseLinkOrmProject = new XMLContext(new XMLEntityMappingsMappingProject(ECLIPSELINK_ORM_NAMESPACE, ECLIPSELINK_ORM_XSD));
        }

        return m_eclipseLinkOrmProject;
    }

    /**
     * @return the Eclipselink orm schema.
     */
    public static Schema getEclipseLinkOrmSchema() throws IOException, SAXException {
        if (m_eclipseLinkOrmSchema == null) {
            m_eclipseLinkOrmSchema = loadLocalSchema(ECLIPSELINK_ORM_XSD);
        }

        return m_eclipseLinkOrmSchema;
    }

    /**
     * Gets a reader from given URL.
     */
    private static InputStreamReader getInputStreamReader(URL url) throws IOException {
        java.net.URLConnection cnx1 = url.openConnection();
        //set to false to prevent locking of jar files on Windows. EclipseLink issue 249664
        cnx1.setUseCaches(false);
        return new InputStreamReader(cnx1.getInputStream(), "UTF-8");
    }

    /**
     * @return the JPA 1.0 orm project.
     */
    public static XMLContext getOrm1_0Project() {
        if (m_orm1_0Project == null) {
            m_orm1_0Project = new XMLContext(new XMLEntityMappingsMappingProject(ORM_1_0_NAMESPACE, ORM_1_0_XSD));
        }

        return m_orm1_0Project;
    }

    /**
     * @return the JPA 1.0 orm schema.
     */
    public static Schema getOrm1_0Schema() throws IOException, SAXException {
        if (m_orm1_0Schema == null) {
            m_orm1_0Schema = loadLocalSchema(ORM_1_0_XSD);
        }

        return m_orm1_0Schema;
    }

    /**
     * @return the JPA 2.0 orm project.
     */
    public static XMLContext getOrm2_0Project() {
        if (m_orm2_0Project == null) {
            m_orm2_0Project = new XMLContext(new XMLEntityMappingsMappingProject(ORM_2_0_NAMESPACE, ORM_2_0_XSD));
        }

        return m_orm2_0Project;
    }

    /**
     * @return the JPA 2.0 orm schema.
     */
    public static Schema getOrm2_0Schema() throws IOException, SAXException {
        if (m_orm2_0Schema == null) {
            m_orm2_0Schema = loadLocalSchema(ORM_2_0_XSD);
        }

        return m_orm2_0Schema;
    }

    /**
     * @return the JPA 2.1 orm project.
     */
    public static XMLContext getOrm2_1Project() {
        if (m_orm2_1Project == null) {
            m_orm2_1Project = new XMLContext(new XMLEntityMappingsMappingProject(ORM_2_1_NAMESPACE, ORM_2_1_XSD));
        }

        return m_orm2_1Project;
    }

    /**
     * @return the JPA 2.1 orm schema.
     */
    public static Schema getOrm2_1Schema() throws IOException, SAXException {
        if (m_orm2_1Schema == null) {
            m_orm2_1Schema = loadLocalSchema(ORM_2_1_XSD);
        }

        return m_orm2_1Schema;
    }
    
    /**
     * @return the JPA 2.2 orm project.
     */
    public static XMLContext getOrm2_2Project() {
        if (m_orm2_2Project == null) {
            m_orm2_2Project = new XMLContext(new XMLEntityMappingsMappingProject(ORM_2_2_NAMESPACE, ORM_2_2_XSD));
        }

        return m_orm2_2Project;
    }

    /**
     * @return the JPA 2.2 orm schema.
     */
    public static Schema getOrm2_2Schema() throws IOException, SAXException {
        if (m_orm2_2Schema == null) {
            m_orm2_2Schema = loadLocalSchema(ORM_2_2_XSD);
        }

        return m_orm2_2Schema;
    }

    /**
     * @return the JPA 3.0 orm project.
     */
    public static XMLContext getOrm3_0Project() {
        if (m_orm3_0Project == null) {
            m_orm3_0Project = new XMLContext(new XMLEntityMappingsMappingProject(ORM_3_0_NAMESPACE, ORM_3_0_XSD));
        }

        return m_orm3_0Project;
    }

    /**
     * @return the JPA 3.0 orm schema.
     */
    public static Schema getOrm3_0Schema() throws IOException, SAXException {
        if (m_orm3_0Schema == null) {
            m_orm3_0Schema = loadLocalSchema(ORM_3_0_XSD);
        }

        return m_orm3_0Schema;
    }

    /**
     * Free the project and schema objects to avoid holding onto the memory.
     * This can be done post-deployment to conserve memory.
     */
    public static void clear() {
        m_orm1_0Project = null;
        m_orm2_0Project = null;
        m_orm2_1Project = null;
        m_orm2_2Project = null;
        m_orm3_0Project = null;
        m_eclipseLinkOrmProject = null;

        m_orm1_0Schema = null;
        m_orm2_0Schema = null;
        m_orm2_1Schema = null;
        m_orm2_2Schema = null;
        m_orm3_0Schema = null;
        m_eclipseLinkOrmSchema = null;
    }

    /**
     * INTERNAL:
     * Return whether the schema validation flag in the Persistence Unit
     * eclipselink.orm.validate.schema is set to true or false.<br>
     * The default value is false.
     * @param properties - PersistenceUnitInfo properties on the project
     */
    private static boolean isORMSchemaValidationPerformed(Map properties) {
        // Get property from persistence.xml (we are not yet parsing sessions.xml)
        String value = EntityManagerFactoryProvider.getConfigPropertyAsString(PersistenceUnitProperties.ORM_SCHEMA_VALIDATION, properties, "false");
        // A true validation property value will override the default of false or NONVALIDATING
        return (value != null && value.equalsIgnoreCase("true"));
    }

    /**
     * Load the XML schema from the jar resource.
     */
    protected static Schema loadLocalSchema(String schemaName) throws IOException, SAXException {
        URL url = XMLEntityMappingsReader.class.getClassLoader().getResource(schemaName);
        InputStream schemaStream = url.openStream();

        try {
            StreamSource source = new StreamSource(url.openStream());
            SchemaFactory schemaFactory = XMLHelper.createSchemaFactory(XMLConstants.SCHEMA_URL, false);
            Schema schema = schemaFactory.newSchema(source);
            return schema;
        } finally {
            schemaStream.close();
        }
    }

    /**
     * INTERNAL:
     */
    public static XMLEntityMappings read(String sourceName, Reader reader, ClassLoader classLoader, Map properties){
        return read(sourceName, null, reader, classLoader, properties);
    }

    /**
     * INTERNAL:
     */
    protected static XMLEntityMappings read(String mappingFile, Reader reader1, Reader reader2, ClassLoader classLoader, Map properties) {
        // Get the schema validation flag if present in the persistence unit properties
        boolean validateORMSchema = isORMSchemaValidationPerformed(properties);

        // Unmarshall JPA format.
        XMLEntityMappings xmlEntityMappings;

        try {
            // First need to determine which context/schema to use, JPA 1.0, 2.0 or EclipseLink orm (only latest supported)
            Object[] context = determineXMLContextAndSchema(mappingFile, reader1, validateORMSchema);
            XMLUnmarshaller unmarshaller = ((XMLContext)context[0]).createUnmarshaller();

            if (validateORMSchema) {
                useLocalSchemaForUnmarshaller(unmarshaller, ((Schema)context[1]));
            }

            xmlEntityMappings = (XMLEntityMappings) unmarshaller.unmarshal(reader2);
        } catch (Exception exception) {
            throw ValidationException.errorParsingMappingFile(mappingFile, exception);
        }

        if (xmlEntityMappings != null) {
            xmlEntityMappings.setMappingFile(mappingFile);
        }

        return xmlEntityMappings;
    }

    /**
     * INTERNAL:
     * @param properties - PersistenceUnitInfo properties on the project
     */
    public static XMLEntityMappings read(URL url, ClassLoader classLoader, Properties properties) throws IOException {
        InputStreamReader reader1 = null;
        InputStreamReader reader2 = null;

        try {
            try {
                //Get separate readers as the read method below is coded to seek through both of them
                reader1 = getInputStreamReader(url);
                reader2 = getInputStreamReader(url);
                return read(url.toString(), reader1, reader2, classLoader, properties);
            } catch (UnsupportedEncodingException exception) {
                throw ValidationException.fatalErrorOccurred(exception);
            }
        } finally {
            try {
                if (reader1 != null) {
                    reader1.close();
                }

                if (reader2 != null) {
                    reader2.close();
                }
            } catch (IOException exception) {
                throw ValidationException.fileError(exception);
            }
        }
    }

    /**
     * This method allows you to set an XML schema on a given unmarshaller. It
     * will get the schema from the same classloader that loaded this class and
     * hence works for the case where the schema is shipped as part of EclipseLink
     *
     */
    private static void useLocalSchemaForUnmarshaller(XMLUnmarshaller unmarshaller, Schema schema) {
        try {

            unmarshaller.setErrorHandler(new ErrorHandler() {
                @Override
                public void error(SAXParseException exception) throws SAXException {
                    throw exception;
                }

                @Override
                public void fatalError(SAXParseException exception) throws SAXException {
                    throw exception;
                }

                @Override
                public void warning(SAXParseException exception) throws SAXException {
                    if (exception.getException() instanceof EclipseLinkException) {
                        throw (EclipseLinkException) exception.getCause();
                    }
                }
            });

            unmarshaller.setSchema(schema);
        } catch (UnsupportedOperationException ex) {
            // Some parsers do not support setSchema.  In that case, setup validation another way.
            unmarshaller.setValidationMode(XMLUnmarshaller.SCHEMA_VALIDATION);
        }
    }
}
