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

org.datanucleus.PersistenceNucleusContextImpl Maven / Gradle / Ivy

Go to download

DataNucleus Core provides the primary components of a heterogenous Java persistence solution. It supports persistence API's being layered on top of the core functionality.

There is a newer version: 6.0.9
Show newest version
/**********************************************************************
Copyright (c) 2010 Andy Jefferson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. 

Contributors:
    ...
**********************************************************************/
package org.datanucleus;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeSet;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.validation.Validation;

import org.datanucleus.cache.JavaxCacheLevel2Cache;
import org.datanucleus.cache.Level2Cache;
import org.datanucleus.cache.NullLevel2Cache;
import org.datanucleus.cache.SoftLevel2Cache;
import org.datanucleus.cache.WeakLevel2Cache;
import org.datanucleus.enhancer.ImplementationCreator;
import org.datanucleus.enhancer.ImplementationCreatorImpl;
import org.datanucleus.exceptions.ClassNotResolvedException;
import org.datanucleus.exceptions.NucleusException;
import org.datanucleus.exceptions.NucleusUserException;
import org.datanucleus.identity.DatastoreUniqueLongId;
import org.datanucleus.identity.IdentityManager;
import org.datanucleus.identity.IdentityManagerImpl;
import org.datanucleus.identity.IdentityUtils;
import org.datanucleus.identity.SCOID;
import org.datanucleus.management.FactoryStatistics;
import org.datanucleus.management.ManagementManager;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.metadata.FileMetaData;
import org.datanucleus.metadata.IdentityType;
import org.datanucleus.metadata.MetaDataListener;
import org.datanucleus.metadata.MetaDataManager;
import org.datanucleus.metadata.QueryLanguage;
import org.datanucleus.metadata.QueryMetaData;
import org.datanucleus.metadata.TransactionType;
import org.datanucleus.plugin.PluginManager;
import org.datanucleus.properties.CorePropertyValidator;
import org.datanucleus.properties.StringPropertyValidator;
import org.datanucleus.state.StateManagerFactory;
import org.datanucleus.state.StateManagerFactoryImpl;
import org.datanucleus.store.StoreManager;
import org.datanucleus.store.StoreManagerHelper;
import org.datanucleus.store.autostart.AutoStartMechanism;
import org.datanucleus.store.autostart.AutoStartMechanismUtils;
import org.datanucleus.store.federation.FederatedStoreManager;
import org.datanucleus.store.schema.CurrentUserProvider;
import org.datanucleus.store.schema.MultiTenancyProvider;
import org.datanucleus.store.schema.SchemaAwareStoreManager;
import org.datanucleus.store.schema.SchemaScriptAwareStoreManager;
import org.datanucleus.store.schema.SchemaTool;
import org.datanucleus.store.schema.SchemaTool.Mode;
import org.datanucleus.transaction.NucleusTransactionException;
import org.datanucleus.transaction.ResourcedTransactionManager;
import org.datanucleus.transaction.TransactionUtils;
import org.datanucleus.transaction.jta.JTASyncRegistry;
import org.datanucleus.transaction.jta.JTASyncRegistryUnavailableException;
import org.datanucleus.transaction.jta.TransactionManagerFinder;
import org.datanucleus.util.Localiser;
import org.datanucleus.util.NucleusLogger;
import org.datanucleus.util.StringUtils;

/**
 * Extends the basic DataNucleus context, adding on services for
 * 
    *
  • creating ExecutionContext objects to handle persistence. Uses a pool of ExecutionContext objects, reusing them as required.
  • *
  • providing a cache across ExecutionContext objects (the "Level 2" cache).
  • *
  • provides a factory for creating StateManagers. This factory makes use of pooling, allowing reuse.
  • *
  • provides access to the datastore via a StoreManager
  • *
*/ public class PersistenceNucleusContextImpl extends AbstractNucleusContext implements Serializable, PersistenceNucleusContext { private static final long serialVersionUID = 7166558862250068749L; /** Manager for the datastore used by this PMF/EMF. */ private transient StoreManager storeMgr = null; private boolean federated = false; /** Auto-Start Mechanism for loading classes into the StoreManager (if enabled). */ private transient AutoStartMechanism starter = null; /** Flag defining if this is running within the JDO JCA adaptor. */ private boolean jca = false; /** Level 2 Cache, caching across ExecutionContexts. */ private Level2Cache cache; /** ResourcedTransaction Manager. */ private transient ResourcedTransactionManager txManager = null; /** JTA Transaction Manager (if using JTA). */ private transient javax.transaction.TransactionManager jtaTxManager = null; /** JTA Synchronization Registry (if using JTA 1.1 and supported). */ private transient JTASyncRegistry jtaSyncRegistry = null; /** Manager for JMX features. */ private transient ManagementManager jmxManager = null; /** Statistics gathering object. */ private transient FactoryStatistics statistics = null; /** Manager for object identities. */ private IdentityManager identityManager; /** ImplementationCreator for any persistent interfaces. */ private ImplementationCreator implCreator; private List executionContextListeners = new ArrayList(); /** Manager for dynamic fetch groups defined on the PMF/EMF. */ private transient FetchGroupManager fetchGrpMgr; /** Factory for validation. */ private transient Object validatorFactory = null; /** Flag for whether we have initialised the ValidatorFactory. */ private transient boolean validatorFactoryInit = false; private transient CDIHandler cdiHandler = null; /** Flag for whether we have initialised the CDIHandler. */ private transient boolean cdiHandlerInit = false; /** Pool for ExecutionContexts. */ private ExecutionContextPool ecPool = null; /** Factory for StateManagers for managing persistable objects. */ private StateManagerFactory smFactory = null; private MultiTenancyProvider multiTenancyProvider = null; private CurrentUserProvider currentUserProvider = null; /** * Constructor for the context. * @param apiName Name of the API that we need a context for (JDO, JPA, etc) * @param startupProps Any properties that could define behaviour of this context (plugin registry, class loading etc) */ public PersistenceNucleusContextImpl(String apiName, Map startupProps) { this(apiName, startupProps, null); } /** * Constructor for the context. * @param apiName Name of the API that we need a context for (JDO, JPA, etc) * @param startupProps Any properties that could define behaviour of this context (plugin registry, class loading etc) * @param pluginMgr Plugin Manager (or null if wanting it to be created) */ public PersistenceNucleusContextImpl(String apiName, Map startupProps, PluginManager pluginMgr) { super(apiName, startupProps, pluginMgr); } @Override public void applyDefaultProperties(Configuration conf) { super.applyDefaultProperties(conf); // PersistenceContext level features conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_IGNORE_CACHE, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_OPTIMISTIC, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_MULTITHREADED, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_RETAIN_VALUES, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_RESTORE_VALUES, null, false, false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_JMX_TYPE, null, null, null, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_ENABLE_STATISTICS, null, false, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_PMF_NAME, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_PERSISTENCE_UNIT_NAME, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_PERSISTENCE_XML_FILENAME, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_SERVER_TIMEZONE_ID, null, null, CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_PROPERTIES_FILE, null, null, null, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_PERSISTENCE_UNIT_LOAD_CLASSES, null, false, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_EXECUTION_CONTEXT_REAPER_THREAD, null, false, false, false); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_EXECUTION_CONTEXT_MAX_IDLE, null, 20, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_EXECUTION_CONTEXT_CLOSE_ACTIVE_TX_ACTION, null, "exception", CorePropertyValidator.class.getName(), false, false); // conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_STATE_MANAGER_REAPER_THREAD, null, false, false, false); // conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_STATE_MANAGER_MAX_IDLE, null, 0, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_STATE_MANAGER_CLASS_NAME, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_DATASTORE_IDENTITY_TYPE, null, "datanucleus", null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_IDENTITY_STRING_TRANSLATOR_TYPE, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_IDENTITY_KEY_TRANSLATOR_TYPE, null, null, null, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_USE_IMPLEMENTATION_CREATOR, null, true, false, false); // Transactions conf.addDefaultProperty(PropertyNames.PROPERTY_TRANSACTION_TYPE, null, null, CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_TRANSACTION_ISOLATION, null, "read-committed", CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_TRANSACTION_JTA_LOCATOR, null, "autodetect", null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_TRANSACTION_JTA_JNDI_LOCATION, null, null, null, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_TRANSACTION_NONTX_READ, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_TRANSACTION_NONTX_WRITE, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_TRANSACTION_NONTX_ATOMIC, null, true, false, true); // Flush process conf.addDefaultProperty(PropertyNames.PROPERTY_FLUSH_MODE, null, null, CorePropertyValidator.class.getName(), false, true); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_FLUSH_AUTO_OBJECT_LIMIT, null, 1, false, false); // Value Generation conf.addDefaultProperty(PropertyNames.PROPERTY_VALUEGEN_TXN_ISOLATION, null, "read-committed", CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_VALUEGEN_TXN_ATTRIBUTE, null, "NEW", CorePropertyValidator.class.getName(), false, false); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_VALUEGEN_SEQUENCE_ALLOCSIZE, null, 10, false, false); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_VALUEGEN_INCREMENT_ALLOCSIZE, null, 10, false, false); // Bean Validation conf.addDefaultProperty(PropertyNames.PROPERTY_VALIDATION_MODE, null, "auto", CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_VALIDATION_GROUP_PREPERSIST, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_VALIDATION_GROUP_PREUPDATE, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_VALIDATION_GROUP_PREREMOVE, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_VALIDATION_FACTORY, null, null, null, false, false); // Store Definition conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_DATASTORE_READONLY, null, false, false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_DATASTORE_READONLY_ACTION, null, "EXCEPTION", CorePropertyValidator.class.getName(), false, true); // Schema Generation conf.addDefaultProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_DATABASE_MODE, null, "none", CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_SCRIPTS_MODE, null, "none", CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_DATABASE_CREATE_ORDER, null, null, CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_SCRIPTS_CREATE, null, "datanucleus-schema-create.ddl", null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_DATABASE_CREATE_SCRIPT, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_DATABASE_DROP_ORDER, null, null, CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_SCRIPTS_DROP, null, "datanucleus-schema-drop.ddl", null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_DATABASE_DROP_SCRIPT, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_SCHEMA_LOAD_SCRIPT, null, null, null, false, false); // Cache conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_COLLECTIONS, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_COLLECTIONS_LAZY, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_L1_TYPE, null, "soft", null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_L2_TYPE, null, "soft", null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_L2_MODE, null, "UNSPECIFIED", CorePropertyValidator.class.getName(), false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_L2_NAME, null, "datanucleus", null, false, false); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_CACHE_L2_MAXSIZE, null, -1, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_LOADFIELDS, null, true, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_CLEARATCLOSE, null, true, false, false); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_CACHE_L2_EXPIRY_MILLIS, null, -1, false, false); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_CACHE_L2_BATCHSIZE, null, 100, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_CACHE_EMBEDDED, null, true, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_READ_THROUGH, null, true, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_WRITE_THROUGH, null, true, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_STATISTICS_ENABLED, null, false, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_STORE_BY_VALUE, null, true, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_L2_RETRIEVE_MODE, null, "use", CorePropertyValidator.class.getName(), false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_L2_STORE_MODE, null, "use", CorePropertyValidator.class.getName(), false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_L2_UPDATE_MODE, null, "commit-and-datastore-read", CorePropertyValidator.class.getName(), false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_QUERYCOMPILE_TYPE, null, "soft", null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_QUERYCOMPILEDATASTORE_TYPE, null, "soft", null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_QUERYRESULTS_TYPE, null, "soft", null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CACHE_QUERYRESULTS_NAME, null, "datanucleus-query", null, false, false); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_CACHE_QUERYRESULTS_MAXSIZE, null, -1, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CACHE_QUERYRESULTS_CLEARATCLOSE, null, true, false, false); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_CACHE_QUERYRESULTS_EXPIRY_MILLIS, null, -1, false, false); // Queries conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_SQL_ALLOWALL, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_JDOQL_ALLOWALL, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_JPQL_ALLOW_RANGE, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_SQL_SYNTAXCHECKS, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_FLUSH_BEFORE_EXECUTE, null, false, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_USE_FETCHPLAN, null, true, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_CHECK_UNUSED_PARAMS, null, true, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_COMPILE_OPTIMISE_VAR_THIS, null, false, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_LOAD_RESULTS_AT_COMMIT, null, true, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_COMPILATION_CACHED, null, true, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_RESULTS_CACHED, null, false, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_EVALUATE_IN_MEMORY, null, false, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_RESULTCACHE_VALIDATEOBJECTS, null, true, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_QUERY_RESULT_SIZE_METHOD, null, "last", null, false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_QUERY_COMPILE_NAMED_QUERIES_AT_STARTUP, null, false, false, false); // Other properties conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_PERSISTENCE_BY_REACHABILITY_AT_COMMIT, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_MANAGE_RELATIONSHIPS, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_MANAGE_RELATIONSHIPS_CHECKS, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SERIALIZE_READ, null, false, false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_DELETION_POLICY, null, "JDO2", CorePropertyValidator.class.getName(), false, true); // TODO Would be nice to set the default here to "false" but JDO TCK "instanceCallbacks" fails conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_FIND_OBJECT_VALIDATE_WHEN_CACHED, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_FIND_OBJECT_TYPE_CONVERSION, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_ALLOW_CALLBACKS, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_DETACH_ALL_ON_COMMIT, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_DETACH_ALL_ON_ROLLBACK, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_DETACH_ON_CLOSE, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_COPY_ON_ATTACH, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_ATTACH_SAME_DATASTORE, null, true, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_ALLOW_ATTACH_OF_TRANSIENT, null, false, false, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_DETACH_AS_WRAPPED, null, false, false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_DETACH_DETACHMENT_FIELDS, null, "load-fields", CorePropertyValidator.class.getName(), false, false); // TODO Change last arg to true conf.addDefaultProperty(PropertyNames.PROPERTY_DETACH_DETACHED_STATE, null, "fetch-groups", CorePropertyValidator.class.getName(), false, false); // TODO Change last arg to true conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_MAX_FETCH_DEPTH, null, 1, false, true); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_VERSION_NUMBER_INITIAL_VALUE, null, 1, false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_RELATION_IDENTITY_STORAGE_MODE, null, StoreManager.RELATION_IDENTITY_STORAGE_PERSISTABLE_IDENTITY, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_TYPE_WRAPPER_BASIS, null, "instantiated", CorePropertyValidator.class.getName(), false, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_TYPE_TREAT_JAVA_UTIL_DATE_AS_MUTABLE, null, true, false, false); // ========================= Generally all properties below here are specified at the StoreManager level ============================= conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL, null, false, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_DATABASE, null, false, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_TABLES, null, false, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_COLUMNS, null, false, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_CONSTRAINTS, null, false, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_WARNONERROR, null, false, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_VALIDATE_ALL, null, false, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_VALIDATE_TABLES, null, false, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_VALIDATE_COLUMNS, null, false, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_SCHEMA_VALIDATE_CONSTRAINTS, null, false, true, false); // Schema identifier naming conf.addDefaultProperty(PropertyNames.PROPERTY_IDENTIFIER_NAMING_FACTORY, null, "datanucleus2", null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_IDENTIFIER_CASE, null, null, CorePropertyValidator.class.getName(), true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_IDENTIFIER_TABLE_PREFIX, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_IDENTIFIER_TABLE_SUFFIX, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_IDENTIFIER_WORD_SEPARATOR, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_IDENTIFIER_FACTORY, null, "datanucleus2", null, true, false); // TODO Migrate RDBMS to use NamingFactory and drop this // Datastore conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_DATASTORE_READ_TIMEOUT, null, null, true, true); conf.addDefaultIntegerProperty(PropertyNames.PROPERTY_DATASTORE_WRITE_TIMEOUT, null, null, true, true); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_STORE_ALLOW_REFS_WITHOUT_IMPLS, null, false, false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_MAPPING, null, null, StringPropertyValidator.class.getName(), true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_MAPPING_CATALOG, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_MAPPING_SCHEMA, null, null, null, true, false); // Multitenancy conf.addDefaultProperty(PropertyNames.PROPERTY_MAPPING_TENANT_ID, null, null, null, false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_MAPPING_TENANT_READ_IDS, null, null, null, false, false); conf.addDefaultProperty(PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER, null, null, null, false, false); // Current user conf.addDefaultProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER, null, null, null, false, true); conf.addDefaultProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER, null, null, null, false, false); // Auto-Start Mechanism conf.addDefaultProperty(PropertyNames.PROPERTY_AUTOSTART_MECHANISM, null, "None", null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_AUTOSTART_MODE, null, "Quiet", CorePropertyValidator.class.getName(), true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_AUTOSTART_CLASSNAMES, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_AUTOSTART_METADATAFILES, null, null, null, true, false); // Connection conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_URL, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_DRIVER_NAME, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_USER_NAME, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_PASSWORD, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_PASSWORD_DECRYPTER, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_FACTORY_NAME, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_FACTORY2_NAME, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_FACTORY, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_FACTORY2, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_RESOURCETYPE, null, null, CorePropertyValidator.class.getName(), true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_RESOURCETYPE2, null, null, CorePropertyValidator.class.getName(), true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_POOLINGTYPE, null, null, null, true, false); conf.addDefaultProperty(PropertyNames.PROPERTY_CONNECTION_POOLINGTYPE2, null, null, null, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CONNECTION_NONTX_RELEASE_AFTER_USE, null, true, true, false); conf.addDefaultBooleanProperty(PropertyNames.PROPERTY_CONNECTION_SINGLE_CONNECTION, null, false, true, false); } @Override public synchronized void initialise() { final ClassLoaderResolver clr = getClassLoaderResolver(null); clr.registerUserClassLoader((ClassLoader)config.getProperty(PropertyNames.PROPERTY_CLASSLOADER_PRIMARY)); boolean generateSchema = false; boolean generateScripts = false; String generateModeStr = config.getStringProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_DATABASE_MODE); if (generateModeStr == null || generateModeStr.equalsIgnoreCase("none")) { // Try scripts instead of database since that wasn't set generateModeStr = config.getStringProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_SCRIPTS_MODE); generateScripts = true; } if (generateModeStr != null && !generateModeStr.equalsIgnoreCase("none")) { generateSchema = true; } // Create the StoreManager try { Set propNamesWithDatastore = config.getPropertyNamesWithPrefix("datanucleus.datastore."); if (propNamesWithDatastore == null) { // Find the StoreManager using the persistence property if specified NucleusLogger.DATASTORE.debug("Creating StoreManager for datastore"); Map datastoreProps = config.getDatastoreProperties(); this.storeMgr = StoreManagerHelper.createStoreManagerForProperties(config.getPersistenceProperties(), datastoreProps, clr, this); // Make sure the isolation level is valid for this StoreManager and correct if necessary String transactionIsolation = config.getStringProperty(PropertyNames.PROPERTY_TRANSACTION_ISOLATION); if (transactionIsolation != null) { String reqdIsolation = TransactionUtils.getTransactionIsolationForStoreManager(storeMgr, transactionIsolation); if (!transactionIsolation.equalsIgnoreCase(reqdIsolation)) { config.setProperty(PropertyNames.PROPERTY_TRANSACTION_ISOLATION, reqdIsolation); } } } else { NucleusLogger.DATASTORE.debug("Creating FederatedStoreManager to handle federation of primary StoreManager and " + propNamesWithDatastore.size() + " secondary datastores"); this.storeMgr = new FederatedStoreManager(clr, this); this.federated = true; } } catch (NucleusException ne) { NucleusLogger.DATASTORE.error("Exception thrown creating StoreManager : " + StringUtils.getMessageFromRootCauseOfThrowable(ne)); throw ne; } NucleusLogger.DATASTORE.debug("StoreManager now created"); // Make sure MetaDataManager is initialised MetaDataManager mmgr = getMetaDataManager(); final Level2Cache cache = getLevel2Cache(); if (cache != null) { // Add listener for metadata loading so we can pin any classes in the L2 cache that are marked for that mmgr.registerListener(new MetaDataListener() { @Override public void loaded(AbstractClassMetaData cmd) { if (cmd.hasExtension("cache-pin") && cmd.getValueForExtension("cache-pin").equalsIgnoreCase("true")) { // Register as auto-pinned in the L2 cache Class cls = clr.classForName(cmd.getFullClassName()); cache.pinAll(cls, false); } } }); } // ========== Initialise the StoreManager contents ========== // A). Load any classes specified by auto-start String autoStartMechanism = config.getStringProperty(PropertyNames.PROPERTY_AUTOSTART_MECHANISM); if (autoStartMechanism != null && !autoStartMechanism.equals("None")) { String mode = config.getStringProperty(PropertyNames.PROPERTY_AUTOSTART_MODE); starter = AutoStartMechanismUtils.createAutoStartMechanism(this, clr, autoStartMechanism, mode); } // B). Schema Generation if (generateSchema) { initialiseSchema(generateModeStr, generateScripts); } // C). Load up internal representations of all persistence-unit classes if (config.getStringProperty(PropertyNames.PROPERTY_PERSISTENCE_UNIT_NAME) != null && config.getBooleanProperty(PropertyNames.PROPERTY_PERSISTENCE_UNIT_LOAD_CLASSES)) { // User is using a persistence-unit, so load up its persistence-unit classes into StoreManager Collection loadedClasses = getMetaDataManager().getClassesWithMetaData(); this.storeMgr.manageClasses(clr, loadedClasses.toArray(new String[loadedClasses.size()])); } // ========================================================== if (config.getBooleanProperty(PropertyNames.PROPERTY_QUERY_COMPILE_NAMED_QUERIES_AT_STARTUP)) { initialiseNamedQueries(clr); } if (ecPool == null) { ecPool = new ExecutionContextPool(this); } if (smFactory == null) { smFactory = new StateManagerFactoryImpl(this); } if (config.hasProperty(PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER)) { try { multiTenancyProvider = (MultiTenancyProvider)config.getProperty(PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER); } catch (Throwable thr) { NucleusLogger.PERSISTENCE.warn("Error accessing property " + PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER + "; should be an instance of MultiTenancyProvider but isnt! Ignored"); } } if (config.hasProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER)) { try { currentUserProvider = (CurrentUserProvider)config.getProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER); } catch (Throwable thr) { NucleusLogger.PERSISTENCE.warn("Error accessing property " + PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER + "; should be an instance of CurrentUserProvider but isnt! Ignored"); } } super.initialise(); } @Override public synchronized void close() { if (cdiHandler != null) { cdiHandler.close(); } if (smFactory != null) { smFactory.close(); smFactory = null; } if (ecPool != null) { ecPool.cleanUp(); ecPool = null; } if (fetchGrpMgr != null) { fetchGrpMgr.clearFetchGroups(); } if (storeMgr != null) { storeMgr.close(); storeMgr = null; } if (metaDataManager != null) { metaDataManager.close(); metaDataManager = null; } if (statistics != null) { statistics.close(); statistics = null; } if (jmxManager != null) { jmxManager.close(); jmxManager = null; } if (cache != null) { // Close the L2 Cache cache.close(); cache = null; NucleusLogger.CACHE.debug(Localiser.msg("004009")); } if (classLoaderResolverMap != null) { classLoaderResolverMap.clear(); classLoaderResolverMap = null; } if (typeManager != null) { typeManager = null; } identityManager = null; super.close(); } @Override protected void logConfigurationDetails() { String timeZoneID = config.getStringProperty(PropertyNames.PROPERTY_SERVER_TIMEZONE_ID); if (timeZoneID == null) { timeZoneID = TimeZone.getDefault().getID(); } NucleusLogger.PERSISTENCE.debug("Persistence : " + (config.getBooleanProperty(PropertyNames.PROPERTY_MULTITHREADED) ? "pm-multithreaded" : "pm-singlethreaded") + (config.getBooleanProperty(PropertyNames.PROPERTY_RETAIN_VALUES) ? ", retain-values" : "") + (config.getBooleanProperty(PropertyNames.PROPERTY_RESTORE_VALUES) ? ", restore-values" : "") + (config.getBooleanProperty(PropertyNames.PROPERTY_TRANSACTION_NONTX_READ) ? ", nontransactional-read" : "") + (config.getBooleanProperty(PropertyNames.PROPERTY_TRANSACTION_NONTX_WRITE) ? ", nontransactional-write" : "") + (config.getBooleanProperty(PropertyNames.PROPERTY_PERSISTENCE_BY_REACHABILITY_AT_COMMIT) ? ", reachability-at-commit" : "") + (config.getBooleanProperty(PropertyNames.PROPERTY_DETACH_ALL_ON_COMMIT) ? ", detach-all-on-commit" : "") + (config.getBooleanProperty(PropertyNames.PROPERTY_DETACH_ALL_ON_ROLLBACK) ? ", detach-all-on-rollback" : "") + (config.getBooleanProperty(PropertyNames.PROPERTY_DETACH_ON_CLOSE) ? ", detach-on-close" : "") + (config.getBooleanProperty(PropertyNames.PROPERTY_COPY_ON_ATTACH) ? ", copy-on-attach" : "") + (config.getBooleanProperty(PropertyNames.PROPERTY_MANAGE_RELATIONSHIPS) ? (config.getBooleanProperty(PropertyNames.PROPERTY_MANAGE_RELATIONSHIPS_CHECKS) ? ", managed-relations(checked)" : ", managed-relations(unchecked)") : "") + ", deletion-policy=" + config.getStringProperty(PropertyNames.PROPERTY_DELETION_POLICY) + (config.getBooleanProperty(PropertyNames.PROPERTY_IGNORE_CACHE) ? ", ignoreCache" : "") + ", serverTimeZone=" + timeZoneID); String txnType = "RESOURCE_LOCAL"; if (TransactionType.JTA.toString().equalsIgnoreCase(config.getStringProperty(PropertyNames.PROPERTY_TRANSACTION_TYPE))) { if (isJcaMode()) { txnType = "JTA (via JCA adapter)"; } else { txnType = "JTA"; } } String autoStartMechanism = config.getStringProperty(PropertyNames.PROPERTY_AUTOSTART_MECHANISM); if (autoStartMechanism != null && !autoStartMechanism.equals("None")) { String autoStartClassNames = config.getStringProperty(PropertyNames.PROPERTY_AUTOSTART_CLASSNAMES); NucleusLogger.PERSISTENCE.debug("AutoStart : mechanism=" + autoStartMechanism + ", mode=" + config.getStringProperty(PropertyNames.PROPERTY_AUTOSTART_MODE) + ((autoStartClassNames != null) ? (", classes=" + autoStartClassNames) : "")); } NucleusLogger.PERSISTENCE.debug("Transactions : type=" + txnType + ", mode=" + (config.getBooleanProperty(PropertyNames.PROPERTY_OPTIMISTIC) ? "optimistic" : "datastore") + ", isolation=" + config.getStringProperty(PropertyNames.PROPERTY_TRANSACTION_ISOLATION)); NucleusLogger.PERSISTENCE.debug("ValueGeneration :" + " txn-isolation=" + config.getStringProperty(PropertyNames.PROPERTY_VALUEGEN_TXN_ISOLATION) + " connection=" + (config.getStringProperty(PropertyNames.PROPERTY_VALUEGEN_TXN_ATTRIBUTE).equalsIgnoreCase("New") ? "New" : "Existing")); NucleusLogger.PERSISTENCE.debug("Cache : Level1 (" + config.getStringProperty(PropertyNames.PROPERTY_CACHE_L1_TYPE) + ")" + ", Level2 (" + config.getStringProperty(PropertyNames.PROPERTY_CACHE_L2_TYPE) + ", mode=" + config.getStringProperty(PropertyNames.PROPERTY_CACHE_L2_MODE) + ")" + ", QueryResults (" + config.getStringProperty(PropertyNames.PROPERTY_CACHE_QUERYRESULTS_TYPE) + ")" + (config.getBooleanProperty(PropertyNames.PROPERTY_CACHE_COLLECTIONS) ? ", Collections/Maps " : "")); } @Override public boolean isFederated() { return federated; } @Override public AutoStartMechanism getAutoStartMechanism() { return starter; } /** * Method to compile all registered named queries (when the user has initialised using a persistence-unit). * @param clr ClassLoader resolver */ protected void initialiseNamedQueries(ClassLoaderResolver clr) { MetaDataManager mmgr = getMetaDataManager(); Set queryNames = mmgr.getNamedQueryNames(); if (queryNames != null) { // Compile all named queries of JDOQL/JPQL language using dummy ExecutionContext ExecutionContext ec = getExecutionContext(null, null); for (String queryName : queryNames) { QueryMetaData qmd = mmgr.getMetaDataForQuery(null, clr, queryName); if (qmd.getLanguage().equals(QueryLanguage.JPQL.name()) || qmd.getLanguage().equals(QueryLanguage.JDOQL.name())) { if (NucleusLogger.QUERY.isDebugEnabled()) { NucleusLogger.QUERY.debug(Localiser.msg("008017", queryName, qmd.getQuery())); } org.datanucleus.store.query.Query q = storeMgr.newQuery(qmd.getLanguage().toString(), ec, qmd.getQuery()); q.compile(); q.closeAll(); } } ec.close(); } } /** * Method to handle generation (create, drop, drop+create) of a schema at initialisation. * Will generate the schema for all classes that have had their metadata loaded at this point, which * typically means the persistence-unit. * @param generateModeStr Generate "mode" * @param generateScripts Whether to generate */ protected void initialiseSchema(String generateModeStr, boolean generateScripts) { Mode mode = null; if (generateModeStr.equalsIgnoreCase("create")) { mode = Mode.CREATE; } else if (generateModeStr.equalsIgnoreCase("drop")) { mode = Mode.DELETE; } else if (generateModeStr.equalsIgnoreCase("drop-and-create")) { mode = Mode.DELETE_CREATE; } if (NucleusLogger.DATASTORE_SCHEMA.isDebugEnabled()) { if (mode == Mode.CREATE) { NucleusLogger.DATASTORE_SCHEMA.debug(Localiser.msg("014000")); } else if (mode == Mode.DELETE) { NucleusLogger.DATASTORE_SCHEMA.debug(Localiser.msg("014001")); } else if (mode == Mode.DELETE_CREATE) { NucleusLogger.DATASTORE_SCHEMA.debug(Localiser.msg("014045")); } } // Extract the classes that have metadata loaded (e.g persistence-unit) Set schemaClassNames = new TreeSet(); FileMetaData[] filemds = getMetaDataManager().getFileMetaData(); if (filemds == null) { throw new NucleusUserException("No classes to process in generateSchema"); } for (int i=0;i options) { return getExecutionContextPool().checkOut(owner, options); } @Override public IdentityManager getIdentityManager() { if (identityManager == null) { identityManager = new IdentityManagerImpl(this); } return identityManager; } @Override public boolean statisticsEnabled() { return config.getBooleanProperty(PropertyNames.PROPERTY_ENABLE_STATISTICS) || getJMXManager() != null; } @Override public synchronized ManagementManager getJMXManager() { if (jmxManager == null && config.getStringProperty(PropertyNames.PROPERTY_JMX_TYPE) != null) { // User requires managed runtime, and not yet present so create manager jmxManager = new ManagementManager(this); } return jmxManager; } @Override public synchronized FactoryStatistics getStatistics() { if (statistics == null && statisticsEnabled()) { statistics = new FactoryStatistics(jmxManager); } return statistics; } @Override public synchronized ImplementationCreator getImplementationCreator() { if (implCreator == null) { boolean useImplCreator = config.getBooleanProperty(PropertyNames.PROPERTY_USE_IMPLEMENTATION_CREATOR); if (useImplCreator) { implCreator = new ImplementationCreatorImpl(getMetaDataManager()); } } return implCreator; } @Override public synchronized ResourcedTransactionManager getResourcedTransactionManager() { if (txManager == null) { txManager = new ResourcedTransactionManager(); } return txManager; } @Override public synchronized javax.transaction.TransactionManager getJtaTransactionManager() { if (jtaTxManager == null) { // Find the JTA transaction manager - there is no standard way to do this so use the finder process. jtaTxManager = new TransactionManagerFinder(this).getTransactionManager(getClassLoaderResolver((ClassLoader)config.getProperty(PropertyNames.PROPERTY_CLASSLOADER_PRIMARY))); if (jtaTxManager == null) { throw new NucleusTransactionException(Localiser.msg("015030")); } } return jtaTxManager; } @Override public JTASyncRegistry getJtaSyncRegistry() { if (jtaSyncRegistry == null) { try { jtaSyncRegistry = new JTASyncRegistry(); } catch (JTASyncRegistryUnavailableException jsrue) { NucleusLogger.TRANSACTION.debug("JTA TransactionSynchronizationRegistry not found at " + "JNDI java:comp/TransactionSynchronizationRegistry so using Transaction to register synchronisation"); jtaSyncRegistry = null; } } return jtaSyncRegistry; } @Override public StoreManager getStoreManager() { if (storeMgr == null) { initialise(); } return storeMgr; } @Override public boolean supportsORMMetaData() { if (storeMgr != null) { return storeMgr.getSupportedOptions().contains(StoreManager.OPTION_ORM); } return true; } @Override public BeanValidationHandler getBeanValidationHandler(ExecutionContext ec) { String validationMode = config.getStringProperty(PropertyNames.PROPERTY_VALIDATION_MODE); if ("none".equalsIgnoreCase(validationMode)) { validatorFactoryInit = true; return null; } try { if (validatorFactory == null && !validatorFactoryInit) { validatorFactoryInit = true; // Factory not yet set so create it if (config.hasPropertyNotNull(PropertyNames.PROPERTY_VALIDATION_FACTORY)) { // Create from javax.persistence.validation.factory if given validatorFactory = config.getProperty(PropertyNames.PROPERTY_VALIDATION_FACTORY); } else { // Create via BeanValidation API bootstrap if present try { ec.getClassLoaderResolver().classForName("javax.validation.Validation"); validatorFactory = Validation.buildDefaultValidatorFactory(); } catch (ClassNotResolvedException cnre) { NucleusLogger.PERSISTENCE.debug("No BeanValidation API (javax.validation) present so cannot utilise BeanValidation hooks"); } } } return (validatorFactory != null) ? new BeanValidationHandler(ec, validatorFactory) : null; } catch (Throwable ex) //throwable used to catch linkage errors { if ("callback".equalsIgnoreCase(validationMode)) { throw ec.getApiAdapter().getUserExceptionForException(ex.getMessage(), (Exception)ex); } NucleusLogger.GENERAL.warn("Unable to create validator handler", ex); } return null; } @Override public CDIHandler getCDIHandler() { if (cdiHandlerInit) { return cdiHandler; } cdiHandlerInit = true; if (config.hasPropertyNotNull(PropertyNames.PROPERTY_CDI_BEAN_MANAGER)) { Object cdiBeanManager = config.getProperty(PropertyNames.PROPERTY_CDI_BEAN_MANAGER); cdiHandler = new CDIHandler(cdiBeanManager); } else { // Try to find a BeanManager using JNDI lookup (in case we have standalone JNDI and CDI) try { Object cdiBeanManager = new InitialContext().lookup("java:comp/BeanManager"); if (cdiBeanManager != null) { cdiHandler = new CDIHandler(cdiBeanManager); } } catch (NamingException e) { return null; } } return cdiHandler; } @Override public boolean hasLevel2Cache() { getLevel2Cache(); return !(cache instanceof NullLevel2Cache); } @Override public Level2Cache getLevel2Cache() { if (cache == null) { String level2Type = config.getStringProperty(PropertyNames.PROPERTY_CACHE_L2_TYPE); if (NullLevel2Cache.NAME.equals(level2Type)) { cache = new NullLevel2Cache(this); } else if (SoftLevel2Cache.NAME.equals(level2Type)) { cache = new SoftLevel2Cache(this); } else if (WeakLevel2Cache.NAME.equals(level2Type)) { cache = new WeakLevel2Cache(this); } else if (JavaxCacheLevel2Cache.NAME.equals(level2Type)) { cache = new JavaxCacheLevel2Cache(this); } else { // Find the L2 cache class name from its plugin name String level2ClassName = pluginManager.getAttributeValueForExtension("org.datanucleus.cache_level2", "name", level2Type, "class-name"); if (level2ClassName == null) { // Plugin of this name not found throw new NucleusUserException(Localiser.msg("004000", level2Type)).setFatal(); } try { // Create an instance of the L2 Cache cache = (Level2Cache)pluginManager.createExecutableExtension("org.datanucleus.cache_level2", "name", level2Type, "class-name", new Class[]{ClassConstants.NUCLEUS_CONTEXT}, new Object[]{this}); if (NucleusLogger.CACHE.isDebugEnabled()) { NucleusLogger.CACHE.debug(Localiser.msg("004002", level2Type)); } } catch (Exception e) { // Class name for this L2 cache plugin is not found! throw new NucleusUserException(Localiser.msg("004001", level2Type, level2ClassName), e).setFatal(); } } } return cache; } @Override public ExecutionContext.LifecycleListener[] getExecutionContextListeners() { return executionContextListeners.toArray(new ExecutionContext.LifecycleListener[executionContextListeners.size()]); } @Override public void addExecutionContextListener(ExecutionContext.LifecycleListener listener) { executionContextListeners.add(listener); } @Override public void removeExecutionContextListener(ExecutionContext.LifecycleListener listener) { executionContextListeners.remove(listener); } @Override public synchronized void setJcaMode(boolean jca) { this.jca = jca; } @Override public boolean isJcaMode() { return jca; } // --------------------------- Fetch Groups --------------------------------- @Override public synchronized FetchGroupManager getFetchGroupManager() { if (fetchGrpMgr == null) { fetchGrpMgr = new FetchGroupManager(this); } return fetchGrpMgr; } @Override public void addInternalFetchGroup(FetchGroup grp) { getFetchGroupManager().addFetchGroup(grp); } @Override public void removeInternalFetchGroup(FetchGroup grp) { getFetchGroupManager().removeFetchGroup(grp); } @Override public FetchGroup createInternalFetchGroup(Class cls, String name) { if (!cls.isInterface() && !getApiAdapter().isPersistable(cls)) { // Class but not persistable! throw new NucleusUserException("Cannot create FetchGroup for " + cls + " since it is not persistable"); } else if (cls.isInterface() && !getMetaDataManager().isPersistentInterface(cls.getName())) { // Interface but not persistent throw new NucleusUserException("Cannot create FetchGroup for " + cls + " since it is not persistable"); } return getFetchGroupManager().createFetchGroup(cls, name); } @Override public FetchGroup getInternalFetchGroup(Class cls, String name, boolean createIfNotPresent) { if (!cls.isInterface() && !getApiAdapter().isPersistable(cls)) { // Class but not persistable! throw new NucleusUserException("Cannot create FetchGroup for " + cls + " since it is not persistable"); } // Make sure metadata for this class is loaded getMetaDataManager().getMetaDataForClass(cls, getClassLoaderResolver(cls.getClassLoader())); if (cls.isInterface() && !getMetaDataManager().isPersistentInterface(cls.getName())) { // Interface but not persistent throw new NucleusUserException("Cannot create FetchGroup for " + cls + " since it is not persistable"); } return getFetchGroupManager().getFetchGroup(cls, name, createIfNotPresent); } @Override public Set getFetchGroupsWithName(String name) { return getFetchGroupManager().getFetchGroupsWithName(name); } @Override public boolean isClassWithIdentityCacheable(Object id) { if (id == null) { return false; } if (id instanceof SCOID) { return false; } else if (id instanceof DatastoreUniqueLongId) { // This doesn't have the class name so can't get metadata return false; } AbstractClassMetaData cmd = null; String className = IdentityUtils.getTargetClassNameForIdentity(id); if (className != null) { // "Identity" defines the class name cmd = getMetaDataManager().getMetaDataForClass(className, getClassLoaderResolver(id.getClass().getClassLoader())); } else { // Application identity with user PK class, so find all using this PK and take first one Collection cmds = getMetaDataManager().getClassMetaDataWithApplicationId(id.getClass().getName()); if (cmds != null && !cmds.isEmpty()) { cmd = cmds.iterator().next(); } } return isClassCacheable(cmd); } @Override public boolean isClassCacheable(AbstractClassMetaData cmd) { if (cmd != null && cmd.getIdentityType() == IdentityType.NONDURABLE) { return false; } String cacheMode = config.getStringProperty(PropertyNames.PROPERTY_CACHE_L2_MODE).toUpperCase(); if (cacheMode.equals("ALL")) { // Everything is cached return true; } else if (cacheMode.equals("NONE")) { // Nothing is cached return false; } else if (cacheMode.equals("ENABLE_SELECTIVE")) { // Default to not cached unless set otherwise if (cmd == null) { return true; } if (cmd.isCacheable() != null && cmd.isCacheable()) { // Explicitly set as cached return true; } return false; } else if (cacheMode.equals("DISABLE_SELECTIVE")) { // Default to cached unless set otherwise if (cmd == null) { return true; } if (cmd.isCacheable() != null && !cmd.isCacheable()) { // Explicitly set as not cached return false; } return true; } else { // Default to cacheable unless set otherwise if (cmd == null) { return true; } Boolean cacheableFlag = cmd.isCacheable(); if (cacheableFlag == null) { return true; } return cacheableFlag; } } @Override public String getTenantId(ExecutionContext ec) { if (multiTenancyProvider != null) { return multiTenancyProvider.getTenantId(ec); } return ec.getStringProperty(PropertyNames.PROPERTY_MAPPING_TENANT_ID); } @Override public String[] getTenantReadIds(ExecutionContext ec) { if (multiTenancyProvider != null) { String[] tenantReadIds = multiTenancyProvider.getTenantReadIds(ec); return (tenantReadIds != null) ? tenantReadIds : new String[] {multiTenancyProvider.getTenantId(ec)}; } // Check for tenantReadIds property (either overridden in EC, or from config) String readIds = null; if (ec != null) { readIds = ec.getStringProperty(PropertyNames.PROPERTY_MAPPING_TENANT_READ_IDS); } if (readIds == null) { readIds = config.getStringProperty(PropertyNames.PROPERTY_MAPPING_TENANT_READ_IDS); } if (readIds != null) { return readIds.split(","); } // Fallback to current tenant id (either overridden in EC, or from config) String tenantId = null; if (ec != null) { // Overridden in EC tenantId = ec.getStringProperty(PropertyNames.PROPERTY_MAPPING_TENANT_ID); } if (tenantId == null) { tenantId = config.getStringProperty(PropertyNames.PROPERTY_MAPPING_TENANT_ID); } return new String[] {tenantId}; } @Override public String getCurrentUser(ExecutionContext ec) { if (currentUserProvider != null) { return currentUserProvider.currentUser(); } return ec.getStringProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy