/*
 * 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:
//     08/10/2009-2.0 Guy Pelletier
//       - 267391: JPA 2.0 implement/extend/use an APT tooling library for MetaModel API canonical classes
//     11/20/2009-2.0 Guy Pelletier/Mitesh Meswani
//       - 295376: Improve usability of MetaModel generator
//     04/29/2010-2.0.3 Guy Pelletier
//       - 311020: Canonical model generator should not throw an exception when no persistence.xml is found
//     06/01/2010-2.1 Guy Pelletier
//       - 315195: Add new property to avoid reading XML during the canonical model generation
//     03/06/2013-2.5 Guy Pelletier
//       - 267391: JPA 2.1 Functionality for Java EE 7 (JSR-338)
package org.eclipse.persistence.internal.jpa.modelgen.objects;

import static org.eclipse.persistence.config.PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML;
import static org.eclipse.persistence.config.PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML_DEFAULT;
import static org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProperties.CANONICAL_MODEL_LOAD_XML;
import static org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProperties.CANONICAL_MODEL_LOAD_XML_DEFAULT;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.StringTokenizer;

import javax.annotation.processing.ProcessingEnvironment;
import javax.tools.FileObject;
import javax.tools.StandardLocation;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.internal.jpa.metadata.MetadataLogger;
import org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProperties;
import org.eclipse.persistence.internal.jpa.modelgen.MetadataMirrorFactory;
import org.eclipse.persistence.logging.SessionLog;

/**
 * Used to read persistence units through the java annotation processing API.
 *
 * @author Guy Pelletier, Peter Krogh
 * @since EclipseLink 1.2
 */
public class PersistenceUnitReader {

    /** Current logger. */
    protected final MetadataLogger logger;
    /** Annotation model processing environment. */
    protected final ProcessingEnvironment processingEnv;

    /**
     * INTERNAL:
     */
    public PersistenceUnitReader(final MetadataLogger logger, final ProcessingEnvironment processingEnv) throws IOException {
        this.logger = logger;
        this.processingEnv = processingEnv;
    }

    /**
     * INTERAL:
     * Close the given input stream.
     */
    protected void closeInputStream(InputStream inputStream) {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException exception) {
                throw ValidationException.fileError(exception);
            }
        }
    }

    /**
     * INTERNAL:
     */
    protected FileObject getFileObject(String filename, ProcessingEnvironment processingEnv) throws IOException {
        return processingEnv.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", filename);
    }

    /**
     * INTERNAL:
     * Return an input stream for the given filename.
     */
    protected InputStream getInputStream(String filename, boolean loadingPersistenceXML) {
        InputStream inputStream = null;

        try {
            FileObject fileObject = getFileObject(filename, processingEnv);
            inputStream = fileObject.openInputStream();
        } catch (Exception ioe) {
            // If we can't find the persistence.xml from the class output
            // we'll try from the current directory using regular IO.
            try {
                inputStream = new FileInputStream(filename);
            } catch (IOException e) {
                if (loadingPersistenceXML) {
                    // If loading the persistence.xml, log a BIG warning message.
                    logger.getSession().getSessionLog().log(SessionLog.WARNING, SessionLog.PROCESSOR,
                            "The persistence xml file [{0}] was not found. NO GENERATION will occur!!"
                            + " Please ensure a persistence xml file is available either from the CLASS_OUTPUT directory"
                            + " [META-INF/persistence.xml] or using the eclipselink.persistencexml property"
                            + " to specify its location.",
                            new Object[] {filename}, false);
                } else {
                    // For any other mapping file log a message.
                    logger.getSession().getSessionLog().log(SessionLog.INFO, SessionLog.PROCESSOR,
                            "Optional file was not found: {0} continuing with generation.",
                            new Object[] {filename}, false);
                }
            }
        }

        return inputStream;
    }

    /**
     * INTERNAL:
     * This method will look for an process the -A eclipselink.persistenceunits
     * option. This list is treated as an include/filter list and if it is not
     * specified all persistence units are processed.
     */
    protected HashSet<String> getPersistenceUnitList(ProcessingEnvironment processingEnv ) {
        String persistenceUnits = processingEnv.getOptions().get(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_UNITS);
        HashSet<String> persistenceUnitList = null;

        if (persistenceUnits != null) {
            persistenceUnitList = new HashSet<String>();
            StringTokenizer st = new StringTokenizer(persistenceUnits, ",");

            while (st.hasMoreTokens()) {
                persistenceUnitList.add(st.nextToken().trim());
            }
        }

        return persistenceUnitList;
    }

    /**
     * INTERNAL:
     */
    public void initPersistenceUnits(final MetadataMirrorFactory factory) {
        // As a performance enhancement to avoid reloading and merging XML metadata for every compile round,
        // the user may choose to turn off the XML loading by setting the load XML flag to false.
        if (Boolean.valueOf(CanonicalModelProperties.getOption(CANONICAL_MODEL_LOAD_XML, CANONICAL_MODEL_LOAD_XML_DEFAULT, processingEnv.getOptions()))) {
            final String filename = CanonicalModelProperties.getOption(ECLIPSELINK_PERSISTENCE_XML, ECLIPSELINK_PERSISTENCE_XML_DEFAULT, processingEnv.getOptions());
            HashSet<String> persistenceUnitList = getPersistenceUnitList(processingEnv);

            InputStream in = null;
            InputStream inStream1 = null;
            InputStream inStream2 = null;

            try {
                in = getInputStream(filename, true);

                // If the persistence.xml was not found, then there is nothing to do.
                if (in != null) {
                    PersistenceXML persistenceXML;
                    try {
                        // Try a 3.0 context first.
                        persistenceXML = (PersistenceXML) PersistenceXMLMappings.createXML3_0Context().createUnmarshaller().unmarshal(in);
                    } catch (Throwable t) {
                        try {
                            // Then 2.1 context with a new input stream.
                            inStream1 = getInputStream(filename, true);
                            persistenceXML = (PersistenceXML) PersistenceXMLMappings.createXML2_1Context().createUnmarshaller().unmarshal(inStream1);
                        } catch (Exception e) {
                            // Catch all exceptions and try a 2.0 context with a new input stream the last
                            inStream2 = getInputStream(filename, true);
                            persistenceXML = (PersistenceXML) PersistenceXMLMappings.createXML2_0Context().createUnmarshaller().unmarshal(inStream2);
                        }

                    }
                    for (SEPersistenceUnitInfo puInfo : persistenceXML.getPersistenceUnitInfos()) {
                        // If no persistence unit list has been specified or one
                        // has been specified and this persistence unit info's
                        // name
                        // appears in that list then add it.
                        if (persistenceUnitList == null || persistenceUnitList.contains(puInfo.getPersistenceUnitName())) {
                            factory.addPersistenceUnit(puInfo, new PersistenceUnit(puInfo, factory, this));
                        }
                    }
                }
            } finally {
                closeInputStream(in);
                closeInputStream(inStream1);
                closeInputStream(inStream2);
            }
        }
    }

}

