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

org.eclipse.persistence.internal.sessions.PropertiesHandler Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2024 IBM Corporation 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
//      Gordon Yorke - VM managed entity detachment
//     Eduard Bartsch, SAP - Fix for Bug 351186 - ConcurrentModificationException Exception in PropertiesHandler
//     Rick Curtis - Add support for WebSphere Liberty platform.
//     08/11/2014-2.5 Rick Curtis
//       - 440594: Tolerate invalid NamedQuery at EntityManager creation.
//     09/03/2015 - Will Dazey
//       - 456067 : Added support for defining query timeout units
//     09/28/2015 - Will Dazey
//       - 478331 : Added support for defining local or server as the default locale for obtaining timestamps
//     03/11/2016 - Jody Grassel
//       - 489794 : Add support for WebSphere EJBEmbeddable platform.
//     08/29/2016 Jody Grassel
//       - 500441: Eclipselink core has System.getProperty() calls that are not potentially executed under doPriv()
//     04/11/2018 - Will Dazey
//       - 533148 : Add the eclipselink.jpa.sql-call-deferral property
package org.eclipse.persistence.internal.sessions;

import org.eclipse.persistence.annotations.IdValidation;
import org.eclipse.persistence.config.BatchWriting;
import org.eclipse.persistence.config.CacheType;
import org.eclipse.persistence.config.CommitOrderType;
import org.eclipse.persistence.config.EntityManagerProperties;
import org.eclipse.persistence.config.ExclusiveConnectionMode;
import org.eclipse.persistence.config.FlushClearCache;
import org.eclipse.persistence.config.LoggerType;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.ReferenceMode;
import org.eclipse.persistence.config.TargetDatabase;
import org.eclipse.persistence.config.TargetServer;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetSystemProperty;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

/**
 *
 * The class processes some of EclipseLink properties.
 * The class may be used for any properties, but it only makes sense
 * to use it in the following two cases:
 *      1. There is a set of legal values defined
 *          either requiring translation (like CacheTypeProp);
 *          or not (like LoggingLevelProp).
 *      2. Property is really a prefix from which the property obtained by
 *      appending entity or class name (like DescriptorCustomizerProp -
 *      it corresponds to "eclipselink.descriptor.customizer." prefix that allows to
 *      define properties like "eclipselink.descriptor.customizer.myPackage.MyClass").
 * 

* EclipseLink properties and their values defined in org.eclipse.persistence.config package. *

* To add a new property: * Define a new property in PersistenceUnitProperties; * Add a class containing property's values if required to config package (like CacheType); * Alternatively values may be already defined elsewhere (like in LoggingLevelProp). * Add an inner class to this class extending Prop corresponding to the new property (like CacheTypeProp); * The first constructor parameter is property name; the second is default value; * In constructor * provide 2-dimensional value array in case the values should be translated (like CacheTypeProp); * in case translation is not required provide a single-dimension array (like LoggingLevelProp). * In inner class Prop static initializer addProp an instance of the new prop class (like addProp(new CacheTypeProp())). * * @see PersistenceUnitProperties * @see CacheType * @see TargetDatabase * @see TargetServer * * 05/28/2008-1.0M8 Andrei Ilitchev. * - 224964: Provide support for Proxy Authentication through JPA. * Added support for CONNECTION_EXCLUSIVE. Also added BooleanProp to allow simpler way of creating boolean-valued properties: * instead of defining a new class for each new Boolean property just add a new instance of BooleanProp with property name and default: * addProp(new BooleanProp(PersistenceUnitProperties.CONNECTION_EXCLUSIVE, "false")); * Changed the existing boolean-valued properties to use this approach, also * applied the same approach to LOGGING_LEVEL and CATEGORY_LOGGING_LEVEL_ * Also introduced a new version of getSessionPropertyValue that takes properties: * public static String getSessionPropertyValue(String name, Map m, AbstractSession session) { * it's convenient for use in EntityManagerImpl: first searches the passed properties then (recursively) properties of the session, then System properties. */ public class PropertiesHandler { /** * INTERNAL: * Gets property value from the map, if none found looks in System properties. * Use this to get a value for a non-prefixed property. * Could be used on prefixes (like "org.eclipse.persistence.cache-type.") too, * but will always return null * Throws IllegalArgumentException in case the property value is illegal. */ public static String getPropertyValue(String name, Map m) { return getPropertyValue(name, m, true); } public static String getPropertyValueLogDebug(String name, Map m, AbstractSession session) { return getPropertyValueLogDebug(name, m, session, true); } public static String getPropertyValue(String name, Map m, boolean useSystemAsDefault) { return Prop.getPropertyValueToApply(name, m, null, useSystemAsDefault); } public static String getPropertyValueLogDebug(String name, Map m, AbstractSession session, boolean useSystemAsDefault) { return Prop.getPropertyValueToApply(name, m, session, useSystemAsDefault); } /** * INTERNAL: * Given property name and value verifies and translates the value. * Throws IllegalArgumentException in case the property value is illegal. */ public static String getPropertyValue(String name, String value) { return Prop.getPropertyValueToApply(name, value, null); } public static String getPropertyValueLogDebug(String name, String value, AbstractSession session) { return Prop.getPropertyValueToApply(name, value, session); } /** * INTERNAL: * Gets property value from the map, if none found looks in System properties. * Use this to get a value for a prefixed property: * for "org.eclipse.persistence.cache-type.Employee" * pass "org.eclipse.persistence.cache-type.", "Employee". * Throws IllegalArgumentException in case the property value is illegal. */ public static String getPrefixedPropertyValue(String prefix, String suffix, Map m) { return (String)getPrefixValues(prefix, m).get(suffix); } /** * INTERNAL: * Gets properties' values from the map, if none found looks in System properties. * In the returned map values keyed by suffixes. * Use it with prefixes (like "org.eclipse.persistence.cache-type."). * Could be used on simple properties (not prefixes, too), * but will always return either an empty map or a map containing a single * value keyed by an empty String. * Throws IllegalArgumentException in case the property value is illegal. */ public static Map getPrefixValues(String prefix, Map m) { return Prop.getPrefixValuesToApply(prefix, m, null, true); } public static Map getPrefixValuesLogDebug(String prefix, Map m, AbstractSession session) { return Prop.getPrefixValuesToApply(prefix, m, session, true); } /** * INTERNAL: * Returns the default property value that should be applied. * Throws IllegalArgumentException in case the name doesn't correspond * to any property. */ public static String getDefaultPropertyValue(String name) { return Prop.getDefaultPropertyValueToApply(name, null); } public static String getDefaultPropertyValueLogDebug(String name, AbstractSession session) { return Prop.getDefaultPropertyValueToApply(name, session); } /** * INTERNAL: * Empty String value indicates that the default property value should be used. */ protected static boolean shouldUseDefault(String value) { return value != null && value.isEmpty(); } protected static abstract class Prop { static HashMap mainMap = new HashMap(); Object[] valueArray; HashMap valueMap; String name; String defaultValue; String defaultValueToApply; boolean valueToApplyMayBeNull; boolean shouldReturnOriginalValueIfValueToApplyNotFound; static { addProp(new LoggerTypeProp()); addProp(new LoggingLevelProp(PersistenceUnitProperties.LOGGING_LEVEL, Level.INFO.getName())); addProp(new LoggingLevelProp(PersistenceUnitProperties.CATEGORY_LOGGING_LEVEL_, Level.INFO.getName())); addProp(new TargetDatabaseProp()); addProp(new TargetServerProp()); addProp(new JTACntrlrProp()); addProp(new CacheSizeProp()); addProp(new CacheTypeProp()); addProp(new BooleanProp(PersistenceUnitProperties.CACHE_SHARED_, "false")); addProp(new DescriptorCustomizerProp()); addProp(new BatchWritingProp()); addProp(new FlushClearCacheProp()); addProp(new ReferenceModeProp()); addProp(new FlushModeProp()); addProp(new BooleanProp(PersistenceUnitProperties.PERSISTENCE_CONTEXT_CLOSE_ON_COMMIT, "false")); addProp(new BooleanProp(PersistenceUnitProperties.PERSISTENCE_CONTEXT_PERSIST_ON_COMMIT, "true")); addProp(new BooleanProp(PersistenceUnitProperties.PERSISTENCE_CONTEXT_COMMIT_WITHOUT_PERSIST_RULES, "false")); addProp(new BooleanProp(PersistenceUnitProperties.VALIDATE_EXISTENCE, "false")); addProp(new BooleanProp(PersistenceUnitProperties.ORDER_UPDATES, "true")); addProp(new CommitOrderProp()); addProp(new BooleanProp(PersistenceUnitProperties.JOIN_EXISTING_TRANSACTION, "false")); addProp(new BooleanProp(PersistenceUnitProperties.COMPOSITE_UNIT, "false")); addProp(new BooleanProp(PersistenceUnitProperties.COMPOSITE_UNIT_MEMBER, "false")); addProp(new ExclusiveConnectionModeProp()); addProp(new BooleanProp(PersistenceUnitProperties.EXCLUSIVE_CONNECTION_IS_LAZY, "true")); addProp(new IdValidationProp()); addProp(new ConnectionPoolProp()); addProp(new BooleanProp(PersistenceUnitProperties.JDBC_RESULT_SET_ACCESS_OPTIMIZATION, Boolean.toString(ObjectLevelReadQuery.isResultSetAccessOptimizedQueryDefault))); addProp(new BooleanProp(PersistenceUnitProperties.JPQL_TOLERATE, "false")); addProp(new BooleanProp(PersistenceUnitProperties.MULTITENANT_SHARED_CACHE, "false")); addProp(new BooleanProp(PersistenceUnitProperties.MULTITENANT_SHARED_EMF, "true")); //Enhancement addProp(new QueryTimeoutUnitProp()); addProp(new PessimisticLockTimeoutUnitProp()); addProp(new BooleanProp(PersistenceUnitProperties.USE_LOCAL_TIMESTAMP, "false")); addProp(new BooleanProp(PersistenceUnitProperties.SQL_CALL_DEFERRAL, "true")); addProp(new BooleanProp(PersistenceUnitProperties.NAMING_INTO_INDEXED, "false")); } Prop(String name) { this.name = name; } Prop(String name, String defaultValue) { this(name); this.defaultValue = defaultValue; } static String getPropertyValueFromMap(String name, Map m, boolean useSystemAsDefault) { String value = (String)m.get(name); if (value == null && useSystemAsDefault) { if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { value = AccessController.doPrivileged(new PrivilegedGetSystemProperty(name)); } else { value = System.getProperty(name); } } return value; } // Collect all entries corresponding to the prefix name. // Note that entries from Map m override those from System properties. static Map getPrefixValuesFromMap(String name, Map m, boolean useSystemAsDefault) { Map mapOut = new HashMap(); if(useSystemAsDefault) { Map.Entry[] entries = (Map.Entry[]) AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { return System.getProperties().entrySet().toArray(new Map.Entry[] {}); } } ); for (Map.Entry entry:entries) { String str = (String)entry.getKey(); if(str.startsWith(name)) { String entityName = str.substring(name.length(), str.length()); mapOut.put(entityName, entry.getValue()); } } } Iterator it = m.entrySet().iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String str = (String)entry.getKey(); if(str.startsWith(name)) { String entityName = str.substring(name.length(), str.length()); mapOut.put(entityName, entry.getValue()); } } return mapOut; } static String getPropertyValue(String name, boolean shouldUseDefault, Map m, AbstractSession session, boolean useSystemAsDefault) { Prop prop = (Prop)mainMap.get(name); if(prop == null) { // it's not our property return null; } String value = getPropertyValueFromMap(name, m, useSystemAsDefault); if(value == null) { return null; } return prop.getValueToApply(value, shouldUseDefault, session); } static String getPropertyValueToApply(String name, Map m, AbstractSession session, boolean useSystemAsDefault) { Prop prop = (Prop)mainMap.get(name); if(prop == null) { throw new IllegalArgumentException(name); } String value = getPropertyValueFromMap(name, m, useSystemAsDefault); if(value == null) { return null; } return prop.getValueToApply(value, shouldUseDefault(value), session); } static String getPropertyValueToApply(String name, String value, AbstractSession session) { Prop prop = (Prop)mainMap.get(name); if(prop == null) { throw new IllegalArgumentException(name); } return prop.getValueToApply(value, shouldUseDefault(value), session); } static Map getPrefixValuesToApply(String prefix, Map m, AbstractSession session, boolean useSystemAsDefault) { Prop prop = (Prop)mainMap.get(prefix); // maps suffixes to property values Map mapIn = getPrefixValuesFromMap(prefix, m, useSystemAsDefault); if(mapIn.isEmpty()) { return mapIn; } HashMap mapOut = new HashMap(mapIn.size()); Iterator it = mapIn.entrySet().iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String suffix = (String)entry.getKey(); Object value = entry.getValue(); if ((prop != null) && (value instanceof String)) { value = prop.getValueToApply((String)value, shouldUseDefault((String)value), suffix, session); } mapOut.put(suffix, value); } // maps suffixes to valuesToApply return mapOut; } static String getDefaultPropertyValueToApply(String name, AbstractSession session) { Prop prop = (Prop)mainMap.get(name); if(prop == null) { throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-default-for-unknown-property", new Object[]{name})); } prop.logDefault(session); return prop.defaultValueToApply; } String getValueToApply(String value, boolean shouldUseDefault, AbstractSession session) { return getValueToApply(value, shouldUseDefault, null, session); } // suffix is used only for properties-prefixes (like CacheType) String getValueToApply(String value, boolean shouldUseDefault, String suffix, AbstractSession session) { if(shouldUseDefault) { logDefault(session, suffix); return defaultValueToApply; } String valueToApply = value; if(valueMap != null) { String key = getUpperCaseString(value); valueToApply = (String)valueMap.get(key); if(valueToApply == null) { boolean notFound = true; if(valueToApplyMayBeNull) { notFound = !valueMap.containsKey(key); } if(notFound) { if(shouldReturnOriginalValueIfValueToApplyNotFound) { valueToApply = value; } else { String propertyName = name; if(suffix != null) { propertyName = propertyName + suffix; } throw new IllegalArgumentException(ExceptionLocalization.buildMessage("ejb30-illegal-property-value", new Object[]{propertyName, getPrintValue(value)})); } } } } String logValue = PersistenceUnitProperties.getOverriddenLogStringForProperty(name); if (logValue != null){ log(session, logValue, logValue, suffix); } else { log(session, value, valueToApply, suffix); } return valueToApply; } static String getUpperCaseString(String value) { if(value != null) { return value.toUpperCase(); } else { return null; } } static String getPrintValue(String value) { if(value != null) { return value; } else { return "null"; } } void initialize() { if(valueArray != null) { valueMap = new HashMap(valueArray.length); if(valueArray instanceof Object[][] valueArray2) { for(int i=0; i





© 2015 - 2024 Weber Informatics LLC | Privacy Policy