All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 2024 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
//     06/16/2009-2.0 Guy Pelletier
//       - 277039: JPA 2.0 Cache Usage Settings
package org.eclipse.persistence.internal.jpa.deployment;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

import javax.sql.DataSource;

import jakarta.persistence.PersistenceConfiguration;
import jakarta.persistence.PersistenceUnitTransactionType;
import jakarta.persistence.SharedCacheMode;
import jakarta.persistence.ValidationMode;
import jakarta.persistence.spi.ClassTransformer;
import jakarta.persistence.spi.PersistenceUnitInfo;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.internal.jpa.jdbc.DataSourceImpl;

/**
 * Internal implementation of the PersistenceUnitInfo detailed in the EJB 3.0 specification
 * Used by our Java SE implementation so common method calls can be used in setting
 * of Container and non-Container EntityManagerFactories.
 */
public class SEPersistenceUnitInfo implements jakarta.persistence.spi.PersistenceUnitInfo {

    private String schemaVersion;
    // What about 2.0 in 1.0 container here ...
    protected SharedCacheMode cacheMode;
    protected ValidationMode validationMode;
    protected String persistenceUnitName;
    protected String persistenceProviderClassName;
    protected DataSource jtaDataSource;
    protected DataSource nonJtaDataSource;
    protected PersistenceUnitTransactionType persistenceUnitTransactionType;
    protected List mappingFiles;
    private List qualifierAnnNames;
    private String scopeAnnName;

    // names of jars specified in persistence.xml. they are later on used
    // to build jar-file URL.
    private final Collection jarFiles = new ArrayList<>();
    protected List jarFileUrls;
    protected List managedClassNames;
    // persistence.xml root URL
    protected URL persistenceUnitRootUrl;
    // PersistenceConfiguration hash of programmatically defined PU, value is null for PU defined in persistence.xml
    private String configHash;

    protected boolean excludeUnlistedClasses = true;

    // Persistence.xml loaded from the canonical model processor will
    // populate the properties into this collection.
    protected List persistenceUnitProperties = new ArrayList<>();
    // Persistence.xml loaded from the metadata processor will populate the
    // properties into this properties map.
    protected Properties properties;

    protected ClassLoader tempClassLoader;
    protected ClassLoader realClassLoader;

    public SEPersistenceUnitInfo(){
        mappingFiles = new ArrayList<>();
        managedClassNames = new ArrayList<>();
        properties = new Properties();
        persistenceUnitTransactionType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
        // DISABLE_SELECTIVE is our default (same as if UNSPECIFIED),
        // see also MetadataProject.isSharedCacheModeDisableSelective()
        cacheMode = SharedCacheMode.DISABLE_SELECTIVE;
        // Default per spec
        validationMode = ValidationMode.AUTO;
        qualifierAnnNames = new ArrayList<>();
        // don't initialize jarFileUrls as it is lazily initialized
    }

    /**
     * Creates internal implementation of the {@link PersistenceUnitInfo}
     * from {@link PersistenceConfiguration} content.
     *
     * @param configuration configuration of a persistence unit
     * @param rootURL root {@link URL} of the persistence unit
     */
    public SEPersistenceUnitInfo(PersistenceConfiguration configuration, URL rootURL) {
        persistenceUnitName = configuration.name();
        persistenceProviderClassName = configuration.provider();
        if (configuration.jtaDataSource() != null && !configuration.jtaDataSource().isEmpty()) {
            jtaDataSource = new DataSourceImpl(configuration.jtaDataSource(), null, null, null);
        }
        if (configuration.nonJtaDataSource() != null && !configuration.nonJtaDataSource().isEmpty()) {
            nonJtaDataSource = new DataSourceImpl(configuration.nonJtaDataSource(), null, null, null);
        }
        cacheMode = configuration.sharedCacheMode();
        validationMode = configuration.validationMode();
        persistenceUnitTransactionType = configuration.transactionType();
        mappingFiles = configuration.mappingFiles();
        managedClassNames = configuration.managedClasses()
                .stream()
                .map(Class::getName)
                .toList();
        properties = new Properties();
        properties.putAll(configuration.properties());
        if (properties.contains(PersistenceUnitProperties.CLASSLOADER)) {
            realClassLoader = (ClassLoader) properties.get(PersistenceUnitProperties.CLASSLOADER);
        } else {
            realClassLoader = Thread.currentThread().getContextClassLoader();
        }
        persistenceUnitRootUrl = rootURL;
        configHash = Integer.toString(persistenceConfigurationHashCode(configuration));
    }

    // TODO: Remove when fixed by implementing hashCode in jakarta.persistence API
    private static int persistenceConfigurationHashCode(PersistenceConfiguration configuration) {
        return Objects.hash(configuration.name(),
                                configuration.provider(),
                                configuration.jtaDataSource(),
                                configuration.nonJtaDataSource(),
                                configuration.sharedCacheMode(),
                                configuration.validationMode(),
                                configuration.transactionType(),
                                configuration.managedClasses(),
                                configuration.mappingFiles(),
                                configuration.properties());
    }

    /**
    * @return The name of the persistence unit.
    * Corresponds to the <name> element in the persistence.xml file.
    */
    @Override
    public String getPersistenceUnitName(){
        return persistenceUnitName;
    }

    public void setPersistenceUnitName(String persistenceUnitName){
        this.persistenceUnitName = persistenceUnitName;
    }

    /**
     * Used with the OX mapping file for the Canonical model processor.
     */
    public List getPersistenceUnitProperties() {
       return persistenceUnitProperties;
    }

    /**
     * Used with the OX mapping file for the Canonical model processor.
     */
    public void setPersistenceUnitProperties(List persistenceUnitProperties) {
       this.persistenceUnitProperties = persistenceUnitProperties;
    }

    /**
    * @return The fully qualified name of the persistence provider
    * implementation class.
    * Corresponds to the <provider> element in the persistence.xml
    * file.
    */
    @Override
    public String getPersistenceProviderClassName(){
        return persistenceProviderClassName;
    }

    public void setScopeAnnotationName(String scopeAnnName) {
        this.scopeAnnName = scopeAnnName;
    }

    @Override
    public String getScopeAnnotationName() {
        return scopeAnnName;
    }

    public void setQualifierAnnotationNames(List qualifierAnnNames) {
        this.qualifierAnnNames = qualifierAnnNames;
    }

    @Override
    public List getQualifierAnnotationNames() {
        return qualifierAnnNames;
    }

    public void setPersistenceProviderClassName(String persistenceProviderClassName){
        this.persistenceProviderClassName = persistenceProviderClassName;
    }

    /**
     * Get the transaction type of the persistence unit.
     * The transaction type corresponds to the transaction-type attribute
     * in the {@code persistence.xml} file.
     *
     * @return The transaction type of the entity managers created
     *         by the EntityManagerFactory.
     * @deprecated Use {@link PersistenceUnitTransactionType}
     *             instead of {@link jakarta.persistence.spi.PersistenceUnitTransactionType}
     */
    @Override
    @Deprecated
    @SuppressWarnings("removal")
    public jakarta.persistence.spi.PersistenceUnitTransactionType getTransactionType() {
        return switch (persistenceUnitTransactionType) {
            case JTA -> jakarta.persistence.spi.PersistenceUnitTransactionType.JTA;
            case RESOURCE_LOCAL -> jakarta.persistence.spi.PersistenceUnitTransactionType.RESOURCE_LOCAL;
        };
    }

    /**
     * Specify the transaction type of the persistence unit.
     *
     * @param transactionType the transaction type of the entity managers
     *                        created by the EntityManagerFactory.
     * @deprecated Use {@link PersistenceUnitTransactionType}
     *             instead of {@link jakarta.persistence.spi.PersistenceUnitTransactionType}
     */
    @Deprecated
    @SuppressWarnings("removal")
    public void setTransactionType(jakarta.persistence.spi.PersistenceUnitTransactionType transactionType) {
        persistenceUnitTransactionType = switch (transactionType) {
            case JTA -> PersistenceUnitTransactionType.JTA;
            case RESOURCE_LOCAL -> PersistenceUnitTransactionType.RESOURCE_LOCAL;
        };
    }

    /**
     * Specify the transaction type for the persistence unit.
     *
     * @param transactionType the transaction type
     */
    public void setTransactionType(PersistenceUnitTransactionType transactionType){
        persistenceUnitTransactionType = transactionType;
    }

    /**
    * @return the JTA-enabled data source to be used by the
    * persistence provider.
    * The data source corresponds to the <jta-data-source>
    * element in the persistence.xml file or is provided at
    * deployment or by the container.
    */
    @Override
    public DataSource getJtaDataSource(){
        return jtaDataSource;
    }

    public void setJtaDataSource(DataSource jtaDataSource){
        this.jtaDataSource = jtaDataSource;
    }

    /**
    * @return The non-JTA-enabled data source to be used by the
    * persistence provider for accessing data outside a JTA
    * transaction.
    * The data source corresponds to the named <non-jta-data-source>
    * element in the persistence.xml file or provided at
    * deployment or by the container.
    */
    @Override
    public DataSource getNonJtaDataSource(){
        return nonJtaDataSource;
    }

    public void setNonJtaDataSource(DataSource nonJtaDataSource){
        this.nonJtaDataSource = nonJtaDataSource;
    }

    /**
    * @return The list of mapping file names that the persistence
    * provider must load to determine the mappings for the entity
    * classes. The mapping files must be in the standard XML
    * mapping format, be uniquely named and be resource-loadable
    * from the application classpath. This list will not include
    * the orm.xml file if one was specified.
    * Each mapping file name corresponds to a <mapping-file>
    * element in the persistence.xml file.
    */
    @Override
    public List getMappingFileNames(){
        return mappingFiles;
    }

    public void setMappingFileNames(List mappingFiles){
        this.mappingFiles = mappingFiles;
    }
    /**
    * @return The list of JAR file URLs that the persistence
    * provider must examine for managed classes of the persistence
    * unit. Each jar file URL corresponds to a named <jar-file>
    * element in the persistence.xml file.
    */
    @Override
    public List getJarFileUrls(){
        if (jarFileUrls == null) { // lazy initialization
            List jarFileUrls = new ArrayList<>(jarFiles.size());
            for (String jarFile : jarFiles) {
                try {
                    // build a URL relative to the PU Root
                    URL jarFileURL = new URL(persistenceUnitRootUrl, jarFile);
                    jarFileUrls.add(jarFileURL);
                } catch (MalformedURLException e) {
                    throw new RuntimeException(e);
                }
            }
            synchronized(this) {
                this.jarFileUrls = jarFileUrls;
            }
        }
        return Collections.unmodifiableList(jarFileUrls);
    }

    public void setJarFileUrls(List jarFileUrls){
        this.jarFileUrls = jarFileUrls;
    }

    /**
    * @return The URL for the jar file that is the root of the
    * persistence unit. If the persistence unit is rooted in
    * the WEB-INF/classes directory, this will be the URL of
    * that directory.
    */
    @Override
    public URL getPersistenceUnitRootUrl(){
        return persistenceUnitRootUrl;
    }

    public void setPersistenceUnitRootUrl(URL persistenceUnitRootUrl){
        this.persistenceUnitRootUrl = persistenceUnitRootUrl;
    }

    /**
     * Get programmatically defined persistence unit hash.
     *
     * @return persistence unit hash or {@code null} if this unit was not defined programmatically
     */
    String getConfigHash() {
        return configHash;
    }

    /**
    * @return The list of the names of the classes that the
    * persistence provider must add it to its set of managed
    * classes. Each name corresponds to a named <class> element
    * in the persistence.xml file.
    */
    @Override
    public List getManagedClassNames(){
        return managedClassNames;
    }

    public void setManagedClassNames(List managedClassNames){
        this.managedClassNames = managedClassNames;
    }
    /**
    * @return Whether classes in the root of the persistence
    * unit that have not been explicitly listed are to be
    * included in the set of managed classes.
    * This value corresponds to the <exclude-unlisted-classes>
    * element in the persistence.xml file.
    */
    @Override
    public boolean excludeUnlistedClasses(){
        return excludeUnlistedClasses;
    }

    public void setExcludeUnlistedClasses(boolean excludeUnlistedClasses){
        this.excludeUnlistedClasses = excludeUnlistedClasses;
    }
    /**
    * @return Properties object. Each property corresponds
    * to a <property> element in the persistence.xml file
    */
    @Override
    public Properties getProperties(){
        return properties;
    }

    public void setProperties(Properties properties){
        this.properties = properties;
    }
    /**
    * @return ClassLoader that the provider may use to load any
    * classes, resources, or open URLs.
    */
    @Override
    public ClassLoader getClassLoader(){
        return realClassLoader;
    }
    /**
    * Add a transformer supplied by the provider that will be
    * called for every new class definition or class redefinition
    * that gets loaded by the loader returned by the
    * PersistenceUnitInfo.getClassLoader method. The transformer
    * has no effect on the result returned by the
    * PersistenceUnitInfo.getNewTempClassLoader method.
    * Classes are only transformed once within the same classloading
    * scope, regardless of how many persistence units they may be
    * a part of.
    *
    * @param transformer A provider-supplied transformer that the
    * Container invokes at class-(re)definition time
    */
    @Override
    public void addTransformer(ClassTransformer transformer){
        // not required for our Java SE implementation
    }

    /**
    * Return a ClassLoader that the provider may use to temporarily
    * load any classes, resources, or open URLs. The scope and
    * classpath of this loader is exactly the same as that of the
    * loader returned by PersistenceUnitInfo.getClassLoader. None of the
    * classes loaded by this class loader will be visible to
    * application components.
    *
    * @return Temporary ClassLoader with same visibility as current
    * loader
    */
    @Override
    public ClassLoader getNewTempClassLoader(){
        return tempClassLoader;
    }

    public void setNewTempClassLoader(ClassLoader loader){
        this.tempClassLoader = loader;
    }

    /**
     * @see PersistenceUnitInfo#getSharedCacheMode()
     * @since Java Persistence 2.0
     */
    public void setSharedCacheMode(String sharedCacheMode) {
        // If user enters an invalid caching type valueOf will throw an illegal
        // argument exception, e.g.
        // java.lang.IllegalArgumentException: No enum const class jakarta.persistence.SharedCacheMode.ALLBOGUS
        this.cacheMode = SharedCacheMode.valueOf(sharedCacheMode);
    }

    /**
     * @see PersistenceUnitInfo#getValidationMode()
     * @since Java Persistence 2.0
     */
    public void setValidationMode(String validationMode) {
        // If user enters an invalid validation mode valueOf will throw an illegal
        // argument exception, e.g.
        // java.lang.IllegalArgumentException: No enum const class jakarta.persistence.ValidationMode.ALLBOGUS
        this.validationMode = ValidationMode.valueOf(validationMode);
    }

    public void setClassLoader(ClassLoader loader) {
        this.realClassLoader = loader;
    }

    public Collection getJarFiles() {
        return jarFiles;
    }

    /**
     * @see PersistenceUnitInfo#getPersistenceXMLSchemaVersion()
     * @since Java Persistence 2.0
     */
    @Override
    public String getPersistenceXMLSchemaVersion() {
        return schemaVersion;
    }

    public void setPersistenceXMLSchemaVersion(String schemaVersion) {
        this.schemaVersion = schemaVersion;
    }

    /**
     * @see PersistenceUnitInfo#getSharedCacheMode()
     * @since Java Persistence 2.0
     */
    @Override
    public SharedCacheMode getSharedCacheMode() {
        return cacheMode;
    }

    /**
     * @see PersistenceUnitInfo#getValidationMode()
     * @since Java Persistence 2.0
     */
    @Override
    public ValidationMode getValidationMode() {
        return validationMode;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy