From 4470052c3b6bdeb18e45987f8aa293d1e93d0552 Mon Sep 17 00:00:00 2001
From: Ludc <2870569285@qq.com>
Date: 星期二, 18 十一月 2025 11:59:12 +0800
Subject: [PATCH] 所有文件上传接口增加文件安全校验逻辑。
---
Source/BladeX-Tool/blade-starter-flowable/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java | 1647 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1,647 insertions(+), 0 deletions(-)
diff --git a/Source/BladeX-Tool/blade-starter-flowable/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java b/Source/BladeX-Tool/blade-starter-flowable/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java
new file mode 100644
index 0000000..21ad6d3
--- /dev/null
+++ b/Source/BladeX-Tool/blade-starter-flowable/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java
@@ -0,0 +1,1647 @@
+/* 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.
+ */
+package org.flowable.common.engine.impl;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.builder.xml.XMLConfigBuilder;
+import org.apache.ibatis.builder.xml.XMLMapperBuilder;
+import org.apache.ibatis.datasource.pooled.PooledDataSource;
+import org.apache.ibatis.mapping.Environment;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
+import org.apache.ibatis.transaction.TransactionFactory;
+import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
+import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
+import org.flowable.common.engine.api.FlowableException;
+import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
+import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
+import org.flowable.common.engine.impl.cfg.CommandExecutorImpl;
+import org.flowable.common.engine.impl.cfg.IdGenerator;
+import org.flowable.common.engine.impl.cfg.TransactionContextFactory;
+import org.flowable.common.engine.impl.cfg.standalone.StandaloneMybatisTransactionContextFactory;
+import org.flowable.common.engine.impl.db.*;
+import org.flowable.common.engine.impl.event.EventDispatchAction;
+import org.flowable.common.engine.impl.interceptor.*;
+import org.flowable.common.engine.impl.persistence.GenericManagerFactory;
+import org.flowable.common.engine.impl.persistence.StrongUuidGenerator;
+import org.flowable.common.engine.impl.persistence.cache.EntityCache;
+import org.flowable.common.engine.impl.persistence.cache.EntityCacheImpl;
+import org.flowable.common.engine.impl.persistence.entity.Entity;
+import org.flowable.common.engine.impl.runtime.Clock;
+import org.flowable.common.engine.impl.service.CommonEngineServiceImpl;
+import org.flowable.common.engine.impl.util.DefaultClockImpl;
+import org.flowable.common.engine.impl.util.IoUtil;
+import org.flowable.common.engine.impl.util.ReflectUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.sql.*;
+import java.util.*;
+
+public abstract class AbstractEngineConfiguration {
+
+ protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+ /** The tenant id indicating 'no tenant' */
+ public static final String NO_TENANT_ID = "";
+
+ /**
+ * Checks the version of the DB schema against the library when the form engine is being created and throws an exception if the versions don't match.
+ */
+ public static final String DB_SCHEMA_UPDATE_FALSE = "false";
+ public static final String DB_SCHEMA_UPDATE_CREATE = "create";
+ public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";
+
+ /**
+ * Creates the schema when the form engine is being created and drops the schema when the form engine is being closed.
+ */
+ public static final String DB_SCHEMA_UPDATE_DROP_CREATE = "drop-create";
+
+ /**
+ * Upon building of the process engine, a check is performed and an update of the schema is performed if it is necessary.
+ */
+ public static final String DB_SCHEMA_UPDATE_TRUE = "true";
+
+ protected boolean forceCloseMybatisConnectionPool = true;
+
+ protected String databaseType;
+ protected String jdbcDriver = "org.h2.Driver";
+ protected String jdbcUrl = "jdbc:h2:tcp://localhost/~/flowable";
+ protected String jdbcUsername = "sa";
+ protected String jdbcPassword = "";
+ protected String dataSourceJndiName;
+ protected int jdbcMaxActiveConnections;
+ protected int jdbcMaxIdleConnections;
+ protected int jdbcMaxCheckoutTime;
+ protected int jdbcMaxWaitTime;
+ protected boolean jdbcPingEnabled;
+ protected String jdbcPingQuery;
+ protected int jdbcPingConnectionNotUsedFor;
+ protected int jdbcDefaultTransactionIsolationLevel;
+ protected DataSource dataSource;
+ protected SchemaManager commonSchemaManager;
+ protected SchemaManager schemaManager;
+ protected Command<Void> schemaManagementCmd;
+
+ protected String databaseSchemaUpdate = DB_SCHEMA_UPDATE_FALSE;
+
+ protected String xmlEncoding = "UTF-8";
+
+ // COMMAND EXECUTORS ///////////////////////////////////////////////
+
+ protected CommandExecutor commandExecutor;
+ protected Collection<? extends CommandInterceptor> defaultCommandInterceptors;
+ protected CommandConfig defaultCommandConfig;
+ protected CommandConfig schemaCommandConfig;
+ protected CommandContextFactory commandContextFactory;
+ protected CommandInterceptor commandInvoker;
+
+ protected List<CommandInterceptor> customPreCommandInterceptors;
+ protected List<CommandInterceptor> customPostCommandInterceptors;
+ protected List<CommandInterceptor> commandInterceptors;
+
+ protected Map<String, AbstractEngineConfiguration> engineConfigurations = new HashMap<>();
+ protected Map<String, AbstractServiceConfiguration> serviceConfigurations = new HashMap<>();
+
+ protected ClassLoader classLoader;
+ /**
+ * Either use Class.forName or ClassLoader.loadClass for class loading. See http://forums.activiti.org/content/reflectutilloadclass-and-custom- classloader
+ */
+ protected boolean useClassForNameClassLoading = true;
+
+ // MYBATIS SQL SESSION FACTORY /////////////////////////////////////
+
+ protected boolean isDbHistoryUsed = true;
+ protected DbSqlSessionFactory dbSqlSessionFactory;
+ protected SqlSessionFactory sqlSessionFactory;
+ protected TransactionFactory transactionFactory;
+ protected TransactionContextFactory transactionContextFactory;
+
+ /**
+ * If set to true, enables bulk insert (grouping sql inserts together). Default true.
+ * For some databases (eg DB2+z/OS) needs to be set to false.
+ */
+ protected boolean isBulkInsertEnabled = true;
+
+ /**
+ * Some databases have a limit of how many parameters one sql insert can have (eg SQL Server, 2000 params (!= insert statements) ). Tweak this parameter in case of exceptions indicating too much
+ * is being put into one bulk insert, or make it higher if your database can cope with it and there are inserts with a huge amount of data.
+ * <p>
+ * By default: 100 (75 for mssql server as it has a hard limit of 2000 parameters in a statement)
+ */
+ protected int maxNrOfStatementsInBulkInsert = 100;
+
+ public int DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER = 60; // currently Execution has most params (31). 2000 / 31 = 64.
+
+ protected Set<Class<?>> customMybatisMappers;
+ protected Set<String> customMybatisXMLMappers;
+ protected List<Interceptor> customMybatisInterceptors;
+
+
+ protected Set<String> dependentEngineMyBatisXmlMappers;
+ protected List<MybatisTypeAliasConfigurator> dependentEngineMybatisTypeAliasConfigs;
+ protected List<MybatisTypeHandlerConfigurator> dependentEngineMybatisTypeHandlerConfigs;
+
+ // SESSION FACTORIES ///////////////////////////////////////////////
+ protected List<SessionFactory> customSessionFactories;
+ protected Map<Class<?>, SessionFactory> sessionFactories;
+
+ protected boolean enableEventDispatcher = true;
+ protected FlowableEventDispatcher eventDispatcher;
+ protected List<FlowableEventListener> eventListeners;
+ protected Map<String, List<FlowableEventListener>> typedEventListeners;
+ protected List<EventDispatchAction> additionalEventDispatchActions;
+
+ protected boolean transactionsExternallyManaged;
+
+ /**
+ * Flag that can be set to configure or not a relational database is used. This is useful for custom implementations that do not use relational databases at all.
+ *
+ * If true (default), the {@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()} value will be used to determine what needs to happen wrt the database schema.
+ *
+ * If false, no validation or schema creation will be done. That means that the database schema must have been created 'manually' before but the engine does not validate whether the schema is
+ * correct. The {@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()} value will not be used.
+ */
+ protected boolean usingRelationalDatabase = true;
+
+ /**
+ * Flag that can be set to configure whether or not a schema is used. This is usefil for custom implementations that do not use relational databases at all.
+ * Setting {@link #usingRelationalDatabase} to true will automotically imply using a schema.
+ */
+ protected boolean usingSchemaMgmt = true;
+
+ /**
+ * Allows configuring a database table prefix which is used for all runtime operations of the process engine. For example, if you specify a prefix named 'PRE1.', Flowable will query for executions
+ * in a table named 'PRE1.ACT_RU_EXECUTION_'.
+ *
+ * <p />
+ * <strong>NOTE: the prefix is not respected by automatic database schema management. If you use {@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_CREATE_DROP} or
+ * {@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_TRUE}, Flowable will create the database tables using the default names, regardless of the prefix configured here.</strong>
+ */
+ protected String databaseTablePrefix = "";
+
+ /**
+ * Escape character for doing wildcard searches.
+ *
+ * This will be added at then end of queries that include for example a LIKE clause. For example: SELECT * FROM table WHERE column LIKE '%\%%' ESCAPE '\';
+ */
+ protected String databaseWildcardEscapeCharacter;
+
+ /**
+ * database catalog to use
+ */
+ protected String databaseCatalog = "";
+
+ /**
+ * In some situations you want to set the schema to use for table checks / generation if the database metadata doesn't return that correctly, see https://jira.codehaus.org/browse/ACT-1220,
+ * https://jira.codehaus.org/browse/ACT-1062
+ */
+ protected String databaseSchema;
+
+ /**
+ * Set to true in case the defined databaseTablePrefix is a schema-name, instead of an actual table name prefix. This is relevant for checking if Flowable-tables exist, the databaseTablePrefix
+ * will not be used here - since the schema is taken into account already, adding a prefix for the table-check will result in wrong table-names.
+ */
+ protected boolean tablePrefixIsSchema;
+
+ /**
+ * Set to true if the latest version of a definition should be retrieved, ignoring a possible parent deployment id value
+ */
+ protected boolean alwaysLookupLatestDefinitionVersion;
+
+ /**
+ * Set to true if by default lookups should fallback to the default tenant (an empty string by default or a defined tenant value)
+ */
+ protected boolean fallbackToDefaultTenant;
+
+ /**
+ * Default tenant provider that is executed when looking up definitions, in case the global or local fallback to default tenant value is true
+ */
+ protected DefaultTenantProvider defaultTenantProvider = (tenantId, scope, scopeKey) -> NO_TENANT_ID;
+
+ /**
+ * Enables the MyBatis plugin that logs the execution time of sql statements.
+ */
+ protected boolean enableLogSqlExecutionTime;
+
+ protected Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();
+
+ protected List<EngineDeployer> customPreDeployers;
+ protected List<EngineDeployer> customPostDeployers;
+ protected List<EngineDeployer> deployers;
+
+ // CONFIGURATORS ////////////////////////////////////////////////////////////
+
+ protected boolean enableConfiguratorServiceLoader = true; // Enabled by default. In certain environments this should be set to false (eg osgi)
+ protected List<EngineConfigurator> configurators; // The injected configurators
+ protected List<EngineConfigurator> allConfigurators; // Including auto-discovered configurators
+ protected EngineConfigurator idmEngineConfigurator;
+
+ public static final String PRODUCT_NAME_POSTGRES = "PostgreSQL";
+ public static final String PRODUCT_NAME_CRDB = "CockroachDB";
+
+ public static final String DATABASE_TYPE_H2 = "h2";
+ public static final String DATABASE_TYPE_HSQL = "hsql";
+ public static final String DATABASE_TYPE_MYSQL = "mysql";
+ public static final String DATABASE_TYPE_ORACLE = "oracle";
+ public static final String DATABASE_TYPE_POSTGRES = "postgres";
+ public static final String DATABASE_TYPE_MSSQL = "mssql";
+ public static final String DATABASE_TYPE_DB2 = "db2";
+ public static final String DATABASE_TYPE_COCKROACHDB = "cockroachdb";
+ public static final String DATABASE_TYPE_DM = "oracle";
+
+ public static Properties getDefaultDatabaseTypeMappings() {
+ Properties databaseTypeMappings = new Properties();
+ databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
+ databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL);
+ databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
+ databaseTypeMappings.setProperty("MariaDB", DATABASE_TYPE_MYSQL);
+ databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
+ databaseTypeMappings.setProperty(PRODUCT_NAME_POSTGRES, DATABASE_TYPE_POSTGRES);
+ databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
+ databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/LINUXPPC64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
+ databaseTypeMappings.setProperty("DM DBMS", DATABASE_TYPE_DM);
+ databaseTypeMappings.setProperty(PRODUCT_NAME_CRDB, DATABASE_TYPE_COCKROACHDB);
+ return databaseTypeMappings;
+ }
+
+ protected Map<Object, Object> beans;
+
+ protected IdGenerator idGenerator;
+ protected boolean usePrefixId;
+
+ protected Clock clock;
+
+ // Variables
+
+ public static final int DEFAULT_GENERIC_MAX_LENGTH_STRING = 4000;
+ public static final int DEFAULT_ORACLE_MAX_LENGTH_STRING = 2000;
+
+ /**
+ * Define a max length for storing String variable types in the database. Mainly used for the Oracle NVARCHAR2 limit of 2000 characters
+ */
+ protected int maxLengthStringVariableType = -1;
+
+ protected void initEngineConfigurations() {
+ engineConfigurations.put(getEngineCfgKey(), this);
+ }
+
+ // DataSource
+ // ///////////////////////////////////////////////////////////////
+
+ protected void initDataSource() {
+ if (dataSource == null) {
+ if (dataSourceJndiName != null) {
+ try {
+ dataSource = (DataSource) new InitialContext().lookup(dataSourceJndiName);
+ } catch (Exception e) {
+ throw new FlowableException("couldn't lookup datasource from " + dataSourceJndiName + ": " + e.getMessage(), e);
+ }
+
+ } else if (jdbcUrl != null) {
+ if ((jdbcDriver == null) || (jdbcUsername == null)) {
+ throw new FlowableException("DataSource or JDBC properties have to be specified in a process engine configuration");
+ }
+
+ logger.debug("initializing datasource to db: {}", jdbcUrl);
+
+ if (logger.isInfoEnabled()) {
+ logger.info("Configuring Datasource with following properties (omitted password for security)");
+ logger.info("datasource driver : {}", jdbcDriver);
+ logger.info("datasource url : {}", jdbcUrl);
+ logger.info("datasource user name : {}", jdbcUsername);
+ }
+
+ PooledDataSource pooledDataSource = new PooledDataSource(this.getClass().getClassLoader(), jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword);
+
+ if (jdbcMaxActiveConnections > 0) {
+ pooledDataSource.setPoolMaximumActiveConnections(jdbcMaxActiveConnections);
+ }
+ if (jdbcMaxIdleConnections > 0) {
+ pooledDataSource.setPoolMaximumIdleConnections(jdbcMaxIdleConnections);
+ }
+ if (jdbcMaxCheckoutTime > 0) {
+ pooledDataSource.setPoolMaximumCheckoutTime(jdbcMaxCheckoutTime);
+ }
+ if (jdbcMaxWaitTime > 0) {
+ pooledDataSource.setPoolTimeToWait(jdbcMaxWaitTime);
+ }
+ if (jdbcPingEnabled) {
+ pooledDataSource.setPoolPingEnabled(true);
+ if (jdbcPingQuery != null) {
+ pooledDataSource.setPoolPingQuery(jdbcPingQuery);
+ }
+ pooledDataSource.setPoolPingConnectionsNotUsedFor(jdbcPingConnectionNotUsedFor);
+ }
+ if (jdbcDefaultTransactionIsolationLevel > 0) {
+ pooledDataSource.setDefaultTransactionIsolationLevel(jdbcDefaultTransactionIsolationLevel);
+ }
+ dataSource = pooledDataSource;
+ }
+ }
+
+ if (databaseType == null) {
+ initDatabaseType();
+ }
+ }
+
+ public void initDatabaseType() {
+ Connection connection = null;
+ try {
+ connection = dataSource.getConnection();
+ DatabaseMetaData databaseMetaData = connection.getMetaData();
+ String databaseProductName = databaseMetaData.getDatabaseProductName();
+ logger.debug("database product name: '{}'", databaseProductName);
+
+ // CRDB does not expose the version through the jdbc driver, so we need to fetch it through version().
+ if (PRODUCT_NAME_POSTGRES.equalsIgnoreCase(databaseProductName)) {
+ PreparedStatement preparedStatement = connection.prepareStatement("select version() as version;");
+ ResultSet resultSet = preparedStatement.executeQuery();
+ String version = null;
+ if (resultSet.next()) {
+ version = resultSet.getString("version");
+ }
+ resultSet.close();
+
+ if (StringUtils.isNotEmpty(version) && version.toLowerCase().startsWith(PRODUCT_NAME_CRDB.toLowerCase())) {
+ databaseProductName = PRODUCT_NAME_CRDB;
+ logger.info("CockroachDB version '{}' detected", version);
+ }
+ }
+
+ databaseType = databaseTypeMappings.getProperty(databaseProductName);
+ if (databaseType == null) {
+ throw new FlowableException("couldn't deduct database type from database product name '" + databaseProductName + "'");
+ }
+ logger.debug("using database type: {}", databaseType);
+
+ } catch (SQLException e) {
+ logger.error("Exception while initializing Database connection", e);
+ } finally {
+ try {
+ if (connection != null) {
+ connection.close();
+ }
+ } catch (SQLException e) {
+ logger.error("Exception while closing the Database connection", e);
+ }
+ }
+
+ // Special care for MSSQL, as it has a hard limit of 2000 params per statement (incl bulk statement).
+ // Especially with executions, with 100 as default, this limit is passed.
+ if (DATABASE_TYPE_MSSQL.equals(databaseType)) {
+ maxNrOfStatementsInBulkInsert = DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER;
+ }
+ }
+
+ public void initSchemaManager() {
+ if (this.commonSchemaManager == null) {
+ this.commonSchemaManager = new CommonDbSchemaManager();
+ }
+ }
+
+ // session factories ////////////////////////////////////////////////////////
+
+ public void addSessionFactory(SessionFactory sessionFactory) {
+ sessionFactories.put(sessionFactory.getSessionType(), sessionFactory);
+ }
+
+ public void initCommandContextFactory() {
+ if (commandContextFactory == null) {
+ commandContextFactory = new CommandContextFactory();
+ }
+ }
+
+ public void initTransactionContextFactory() {
+ if (transactionContextFactory == null) {
+ transactionContextFactory = new StandaloneMybatisTransactionContextFactory();
+ }
+ }
+
+ public void initCommandExecutors() {
+ initDefaultCommandConfig();
+ initSchemaCommandConfig();
+ initCommandInvoker();
+ initCommandInterceptors();
+ initCommandExecutor();
+ }
+
+
+ public void initDefaultCommandConfig() {
+ if (defaultCommandConfig == null) {
+ defaultCommandConfig = new CommandConfig();
+ }
+ }
+
+ public void initSchemaCommandConfig() {
+ if (schemaCommandConfig == null) {
+ schemaCommandConfig = new CommandConfig();
+ }
+ }
+
+ public void initCommandInvoker() {
+ if (commandInvoker == null) {
+ commandInvoker = new DefaultCommandInvoker();
+ }
+ }
+
+ public void initCommandInterceptors() {
+ if (commandInterceptors == null) {
+ commandInterceptors = new ArrayList<>();
+ if (customPreCommandInterceptors != null) {
+ commandInterceptors.addAll(customPreCommandInterceptors);
+ }
+ commandInterceptors.addAll(getDefaultCommandInterceptors());
+ if (customPostCommandInterceptors != null) {
+ commandInterceptors.addAll(customPostCommandInterceptors);
+ }
+ commandInterceptors.add(commandInvoker);
+ }
+ }
+
+ public Collection<? extends CommandInterceptor> getDefaultCommandInterceptors() {
+ if (defaultCommandInterceptors == null) {
+ List<CommandInterceptor> interceptors = new ArrayList<>();
+ interceptors.add(new LogInterceptor());
+
+ if (DATABASE_TYPE_COCKROACHDB.equals(databaseType)) {
+ interceptors.add(new CrDbRetryInterceptor());
+ }
+
+ CommandInterceptor transactionInterceptor = createTransactionInterceptor();
+ if (transactionInterceptor != null) {
+ interceptors.add(transactionInterceptor);
+ }
+
+ if (commandContextFactory != null) {
+ String engineCfgKey = getEngineCfgKey();
+ CommandContextInterceptor commandContextInterceptor = new CommandContextInterceptor(commandContextFactory);
+ engineConfigurations.put(engineCfgKey, this);
+ commandContextInterceptor.setEngineConfigurations(engineConfigurations);
+ commandContextInterceptor.setServiceConfigurations(serviceConfigurations);
+ commandContextInterceptor.setCurrentEngineConfigurationKey(engineCfgKey);
+ interceptors.add(commandContextInterceptor);
+ }
+
+ if (transactionContextFactory != null) {
+ interceptors.add(new TransactionContextInterceptor(transactionContextFactory));
+ }
+
+ List<CommandInterceptor> additionalCommandInterceptors = getAdditionalDefaultCommandInterceptors();
+ if (additionalCommandInterceptors != null) {
+ interceptors.addAll(additionalCommandInterceptors);
+ }
+
+ defaultCommandInterceptors = interceptors;
+ }
+ return defaultCommandInterceptors;
+ }
+
+ public abstract String getEngineCfgKey();
+
+ public List<CommandInterceptor> getAdditionalDefaultCommandInterceptors() {
+ return null;
+ }
+
+ public void initCommandExecutor() {
+ if (commandExecutor == null) {
+ CommandInterceptor first = initInterceptorChain(commandInterceptors);
+ commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
+ }
+ }
+
+ public CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) {
+ if (chain == null || chain.isEmpty()) {
+ throw new FlowableException("invalid command interceptor chain configuration: " + chain);
+ }
+ for (int i = 0; i < chain.size() - 1; i++) {
+ chain.get(i).setNext(chain.get(i + 1));
+ }
+ return chain.get(0);
+ }
+
+ public abstract CommandInterceptor createTransactionInterceptor();
+
+
+ public void initBeans() {
+ if (beans == null) {
+ beans = new HashMap<>();
+ }
+ }
+
+ // id generator
+ // /////////////////////////////////////////////////////////////
+
+ public void initIdGenerator() {
+ if (idGenerator == null) {
+ idGenerator = new StrongUuidGenerator();
+ }
+ }
+
+ public void initClock() {
+ if (clock == null) {
+ clock = new DefaultClockImpl();
+ }
+ }
+
+ // services
+ // /////////////////////////////////////////////////////////////////
+
+ protected void initService(Object service) {
+ if (service instanceof CommonEngineServiceImpl) {
+ ((CommonEngineServiceImpl) service).setCommandExecutor(commandExecutor);
+ }
+ }
+
+ // myBatis SqlSessionFactory
+ // ////////////////////////////////////////////////
+
+ public void initSessionFactories() {
+ if (sessionFactories == null) {
+ sessionFactories = new HashMap<>();
+
+ if (usingRelationalDatabase) {
+ initDbSqlSessionFactory();
+ }
+
+ addSessionFactory(new GenericManagerFactory(EntityCache.class, EntityCacheImpl.class));
+ commandContextFactory.setSessionFactories(sessionFactories);
+ }
+
+ if (customSessionFactories != null) {
+ for (SessionFactory sessionFactory : customSessionFactories) {
+ addSessionFactory(sessionFactory);
+ }
+ }
+ }
+
+ public void initDbSqlSessionFactory() {
+ if (dbSqlSessionFactory == null) {
+ dbSqlSessionFactory = createDbSqlSessionFactory();
+ }
+ dbSqlSessionFactory.setDatabaseType(databaseType);
+ dbSqlSessionFactory.setSqlSessionFactory(sqlSessionFactory);
+ dbSqlSessionFactory.setDbHistoryUsed(isDbHistoryUsed);
+ dbSqlSessionFactory.setDatabaseTablePrefix(databaseTablePrefix);
+ dbSqlSessionFactory.setTablePrefixIsSchema(tablePrefixIsSchema);
+ dbSqlSessionFactory.setDatabaseCatalog(databaseCatalog);
+ dbSqlSessionFactory.setDatabaseSchema(databaseSchema);
+ dbSqlSessionFactory.setMaxNrOfStatementsInBulkInsert(maxNrOfStatementsInBulkInsert);
+
+ initDbSqlSessionFactoryEntitySettings();
+
+ addSessionFactory(dbSqlSessionFactory);
+ }
+
+ public DbSqlSessionFactory createDbSqlSessionFactory() {
+ return new DbSqlSessionFactory(usePrefixId);
+ }
+
+ protected abstract void initDbSqlSessionFactoryEntitySettings();
+
+ protected void defaultInitDbSqlSessionFactoryEntitySettings(List<Class<? extends Entity>> insertOrder, List<Class<? extends Entity>> deleteOrder) {
+ if (insertOrder != null) {
+ for (Class<? extends Entity> clazz : insertOrder) {
+ dbSqlSessionFactory.getInsertionOrder().add(clazz);
+
+ if (isBulkInsertEnabled) {
+ dbSqlSessionFactory.getBulkInserteableEntityClasses().add(clazz);
+ }
+ }
+ }
+
+ if (deleteOrder != null) {
+ for (Class<? extends Entity> clazz : deleteOrder) {
+ dbSqlSessionFactory.getDeletionOrder().add(clazz);
+ }
+ }
+ }
+
+ public void initTransactionFactory() {
+ if (transactionFactory == null) {
+ if (transactionsExternallyManaged) {
+ transactionFactory = new ManagedTransactionFactory();
+ Properties properties = new Properties();
+ properties.put("closeConnection", "false");
+ this.transactionFactory.setProperties(properties);
+ } else {
+ transactionFactory = new JdbcTransactionFactory();
+ }
+ }
+ }
+
+ public void initSqlSessionFactory() {
+ if (sqlSessionFactory == null) {
+ InputStream inputStream = null;
+ try {
+ inputStream = getMyBatisXmlConfigurationStream();
+
+ Environment environment = new Environment("default", transactionFactory, dataSource);
+ Reader reader = new InputStreamReader(inputStream);
+ Properties properties = new Properties();
+ properties.put("prefix", databaseTablePrefix);
+
+ String wildcardEscapeClause = "";
+ if ((databaseWildcardEscapeCharacter != null) && (databaseWildcardEscapeCharacter.length() != 0)) {
+ wildcardEscapeClause = " escape '" + databaseWildcardEscapeCharacter + "'";
+ }
+ properties.put("wildcardEscapeClause", wildcardEscapeClause);
+
+ // set default properties
+ properties.put("limitBefore", "");
+ properties.put("limitAfter", "");
+ properties.put("limitBetween", "");
+ properties.put("limitOuterJoinBetween", "");
+ properties.put("limitBeforeNativeQuery", "");
+ properties.put("blobType", "BLOB");
+ properties.put("boolValue", "TRUE");
+
+ if (databaseType != null) {
+ properties.load(getResourceAsStream(pathToEngineDbProperties()));
+ }
+
+ Configuration configuration = initMybatisConfiguration(environment, reader, properties);
+ sqlSessionFactory = new DefaultSqlSessionFactory(configuration);
+
+ } catch (Exception e) {
+ throw new FlowableException("Error while building ibatis SqlSessionFactory: " + e.getMessage(), e);
+ } finally {
+ IoUtil.closeSilently(inputStream);
+ }
+ }
+ }
+
+ public String pathToEngineDbProperties() {
+ return "org/flowable/common/db/properties/" + databaseType + ".properties";
+ }
+
+ public Configuration initMybatisConfiguration(Environment environment, Reader reader, Properties properties) {
+ XMLConfigBuilder parser = new XMLConfigBuilder(reader, "", properties);
+ Configuration configuration = parser.getConfiguration();
+
+ if (databaseType != null) {
+ configuration.setDatabaseId(databaseType);
+ }
+
+ configuration.setEnvironment(environment);
+
+ initCustomMybatisMappers(configuration);
+ initMybatisTypeHandlers(configuration);
+ initCustomMybatisInterceptors(configuration);
+ if (isEnableLogSqlExecutionTime()) {
+ initMyBatisLogSqlExecutionTimePlugin(configuration);
+ }
+
+ configuration = parseMybatisConfiguration(parser);
+ return configuration;
+ }
+
+ public void initCustomMybatisMappers(Configuration configuration) {
+ if (getCustomMybatisMappers() != null) {
+ for (Class<?> clazz : getCustomMybatisMappers()) {
+ configuration.addMapper(clazz);
+ }
+ }
+ }
+
+ public void initMybatisTypeHandlers(Configuration configuration) {
+ // To be extended
+ }
+
+ public void initCustomMybatisInterceptors(Configuration configuration) {
+ if (customMybatisInterceptors!=null){
+ for (Interceptor interceptor :customMybatisInterceptors){
+ configuration.addInterceptor(interceptor);
+ }
+ }
+ }
+
+ public void initMyBatisLogSqlExecutionTimePlugin(Configuration configuration) {
+ configuration.addInterceptor(new LogSqlExecutionTimePlugin());
+ }
+
+ public Configuration parseMybatisConfiguration(XMLConfigBuilder parser) {
+ Configuration configuration = parser.parse();
+
+ if (dependentEngineMybatisTypeAliasConfigs != null) {
+ for (MybatisTypeAliasConfigurator typeAliasConfig : dependentEngineMybatisTypeAliasConfigs) {
+ typeAliasConfig.configure(configuration.getTypeAliasRegistry());
+ }
+ }
+ if (dependentEngineMybatisTypeHandlerConfigs != null) {
+ for (MybatisTypeHandlerConfigurator typeHandlerConfig : dependentEngineMybatisTypeHandlerConfigs) {
+ typeHandlerConfig.configure(configuration.getTypeHandlerRegistry());
+ }
+ }
+
+ parseDependentEngineMybatisXMLMappers(configuration);
+ parseCustomMybatisXMLMappers(configuration);
+ return configuration;
+ }
+
+ public void parseCustomMybatisXMLMappers(Configuration configuration) {
+ if (getCustomMybatisXMLMappers() != null) {
+ for (String resource : getCustomMybatisXMLMappers()) {
+ parseMybatisXmlMapping(configuration, resource);
+ }
+ }
+ }
+
+ public void parseDependentEngineMybatisXMLMappers(Configuration configuration) {
+ if (getDependentEngineMyBatisXmlMappers() != null) {
+ for (String resource : getDependentEngineMyBatisXmlMappers()) {
+ parseMybatisXmlMapping(configuration, resource);
+ }
+ }
+ }
+
+ protected void parseMybatisXmlMapping(Configuration configuration, String resource) {
+ // see XMLConfigBuilder.mapperElement()
+ XMLMapperBuilder mapperParser = new XMLMapperBuilder(getResourceAsStream(resource), configuration, resource, configuration.getSqlFragments());
+ mapperParser.parse();
+ }
+
+ protected InputStream getResourceAsStream(String resource) {
+ ClassLoader classLoader = getClassLoader();
+ if (classLoader != null) {
+ return getClassLoader().getResourceAsStream(resource);
+ } else {
+ return this.getClass().getClassLoader().getResourceAsStream(resource);
+ }
+ }
+
+ public abstract InputStream getMyBatisXmlConfigurationStream();
+
+ public void initConfigurators() {
+
+ allConfigurators = new ArrayList<>();
+ allConfigurators.addAll(getEngineSpecificEngineConfigurators());
+
+ // Configurators that are explicitly added to the config
+ if (configurators != null) {
+ allConfigurators.addAll(configurators);
+ }
+
+ // Auto discovery through ServiceLoader
+ if (enableConfiguratorServiceLoader) {
+ ClassLoader classLoader = getClassLoader();
+ if (classLoader == null) {
+ classLoader = ReflectUtil.getClassLoader();
+ }
+
+ ServiceLoader<EngineConfigurator> configuratorServiceLoader = ServiceLoader.load(EngineConfigurator.class, classLoader);
+ int nrOfServiceLoadedConfigurators = 0;
+ for (EngineConfigurator configurator : configuratorServiceLoader) {
+ allConfigurators.add(configurator);
+ nrOfServiceLoadedConfigurators++;
+ }
+
+ if (nrOfServiceLoadedConfigurators > 0) {
+ logger.info("Found {} auto-discoverable Process Engine Configurator{}", nrOfServiceLoadedConfigurators, nrOfServiceLoadedConfigurators > 1 ? "s" : "");
+ }
+
+ if (!allConfigurators.isEmpty()) {
+
+ // Order them according to the priorities (useful for dependent
+ // configurator)
+ Collections.sort(allConfigurators, new Comparator<EngineConfigurator>() {
+ @Override
+ public int compare(EngineConfigurator configurator1, EngineConfigurator configurator2) {
+ int priority1 = configurator1.getPriority();
+ int priority2 = configurator2.getPriority();
+
+ if (priority1 < priority2) {
+ return -1;
+ } else if (priority1 > priority2) {
+ return 1;
+ }
+ return 0;
+ }
+ });
+
+ // Execute the configurators
+ logger.info("Found {} Engine Configurators in total:", allConfigurators.size());
+ for (EngineConfigurator configurator : allConfigurators) {
+ logger.info("{} (priority:{})", configurator.getClass(), configurator.getPriority());
+ }
+
+ }
+
+ }
+ }
+
+ public void close() {
+ if (forceCloseMybatisConnectionPool && dataSource instanceof PooledDataSource) {
+ /*
+ * When the datasource is created by a Flowable engine (i.e. it's an instance of PooledDataSource),
+ * the connection pool needs to be closed when closing the engine.
+ * Note that calling forceCloseAll() multiple times (as is the case when running with multiple engine) is ok.
+ */
+ ((PooledDataSource) dataSource).forceCloseAll();
+ }
+ }
+
+ protected List<EngineConfigurator> getEngineSpecificEngineConfigurators() {
+ // meant to be overridden if needed
+ return Collections.emptyList();
+ }
+
+ public void configuratorsBeforeInit() {
+ for (EngineConfigurator configurator : allConfigurators) {
+ logger.info("Executing beforeInit() of {} (priority:{})", configurator.getClass(), configurator.getPriority());
+ configurator.beforeInit(this);
+ }
+ }
+
+ public void configuratorsAfterInit() {
+ for (EngineConfigurator configurator : allConfigurators) {
+ logger.info("Executing configure() of {} (priority:{})", configurator.getClass(), configurator.getPriority());
+ configurator.configure(this);
+ }
+ }
+
+ // getters and setters
+ // //////////////////////////////////////////////////////
+
+ public abstract String getEngineName();
+
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ public AbstractEngineConfiguration setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ return this;
+ }
+
+ public boolean isUseClassForNameClassLoading() {
+ return useClassForNameClassLoading;
+ }
+
+ public AbstractEngineConfiguration setUseClassForNameClassLoading(boolean useClassForNameClassLoading) {
+ this.useClassForNameClassLoading = useClassForNameClassLoading;
+ return this;
+ }
+
+ public String getDatabaseType() {
+ return databaseType;
+ }
+
+ public AbstractEngineConfiguration setDatabaseType(String databaseType) {
+ this.databaseType = databaseType;
+ return this;
+ }
+
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ public AbstractEngineConfiguration setDataSource(DataSource dataSource) {
+ this.dataSource = dataSource;
+ return this;
+ }
+
+ public SchemaManager getSchemaManager() {
+ return schemaManager;
+ }
+
+ public AbstractEngineConfiguration setSchemaManager(SchemaManager schemaManager) {
+ this.schemaManager = schemaManager;
+ return this;
+ }
+
+ public SchemaManager getCommonSchemaManager() {
+ return commonSchemaManager;
+ }
+
+ public AbstractEngineConfiguration setCommonSchemaManager(SchemaManager commonSchemaManager) {
+ this.commonSchemaManager = commonSchemaManager;
+ return this;
+ }
+
+ public Command<Void> getSchemaManagementCmd() {
+ return schemaManagementCmd;
+ }
+
+ public AbstractEngineConfiguration setSchemaManagementCmd(Command<Void> schemaManagementCmd) {
+ this.schemaManagementCmd = schemaManagementCmd;
+ return this;
+ }
+
+ public String getJdbcDriver() {
+ return jdbcDriver;
+ }
+
+ public AbstractEngineConfiguration setJdbcDriver(String jdbcDriver) {
+ this.jdbcDriver = jdbcDriver;
+ return this;
+ }
+
+ public String getJdbcUrl() {
+ return jdbcUrl;
+ }
+
+ public AbstractEngineConfiguration setJdbcUrl(String jdbcUrl) {
+ this.jdbcUrl = jdbcUrl;
+ return this;
+ }
+
+ public String getJdbcUsername() {
+ return jdbcUsername;
+ }
+
+ public AbstractEngineConfiguration setJdbcUsername(String jdbcUsername) {
+ this.jdbcUsername = jdbcUsername;
+ return this;
+ }
+
+ public String getJdbcPassword() {
+ return jdbcPassword;
+ }
+
+ public AbstractEngineConfiguration setJdbcPassword(String jdbcPassword) {
+ this.jdbcPassword = jdbcPassword;
+ return this;
+ }
+
+ public int getJdbcMaxActiveConnections() {
+ return jdbcMaxActiveConnections;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxActiveConnections(int jdbcMaxActiveConnections) {
+ this.jdbcMaxActiveConnections = jdbcMaxActiveConnections;
+ return this;
+ }
+
+ public int getJdbcMaxIdleConnections() {
+ return jdbcMaxIdleConnections;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxIdleConnections(int jdbcMaxIdleConnections) {
+ this.jdbcMaxIdleConnections = jdbcMaxIdleConnections;
+ return this;
+ }
+
+ public int getJdbcMaxCheckoutTime() {
+ return jdbcMaxCheckoutTime;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxCheckoutTime(int jdbcMaxCheckoutTime) {
+ this.jdbcMaxCheckoutTime = jdbcMaxCheckoutTime;
+ return this;
+ }
+
+ public int getJdbcMaxWaitTime() {
+ return jdbcMaxWaitTime;
+ }
+
+ public AbstractEngineConfiguration setJdbcMaxWaitTime(int jdbcMaxWaitTime) {
+ this.jdbcMaxWaitTime = jdbcMaxWaitTime;
+ return this;
+ }
+
+ public boolean isJdbcPingEnabled() {
+ return jdbcPingEnabled;
+ }
+
+ public AbstractEngineConfiguration setJdbcPingEnabled(boolean jdbcPingEnabled) {
+ this.jdbcPingEnabled = jdbcPingEnabled;
+ return this;
+ }
+
+ public int getJdbcPingConnectionNotUsedFor() {
+ return jdbcPingConnectionNotUsedFor;
+ }
+
+ public AbstractEngineConfiguration setJdbcPingConnectionNotUsedFor(int jdbcPingConnectionNotUsedFor) {
+ this.jdbcPingConnectionNotUsedFor = jdbcPingConnectionNotUsedFor;
+ return this;
+ }
+
+ public int getJdbcDefaultTransactionIsolationLevel() {
+ return jdbcDefaultTransactionIsolationLevel;
+ }
+
+ public AbstractEngineConfiguration setJdbcDefaultTransactionIsolationLevel(int jdbcDefaultTransactionIsolationLevel) {
+ this.jdbcDefaultTransactionIsolationLevel = jdbcDefaultTransactionIsolationLevel;
+ return this;
+ }
+
+ public String getJdbcPingQuery() {
+ return jdbcPingQuery;
+ }
+
+ public AbstractEngineConfiguration setJdbcPingQuery(String jdbcPingQuery) {
+ this.jdbcPingQuery = jdbcPingQuery;
+ return this;
+ }
+
+ public String getDataSourceJndiName() {
+ return dataSourceJndiName;
+ }
+
+ public AbstractEngineConfiguration setDataSourceJndiName(String dataSourceJndiName) {
+ this.dataSourceJndiName = dataSourceJndiName;
+ return this;
+ }
+
+ public CommandConfig getSchemaCommandConfig() {
+ return schemaCommandConfig;
+ }
+
+ public AbstractEngineConfiguration setSchemaCommandConfig(CommandConfig schemaCommandConfig) {
+ this.schemaCommandConfig = schemaCommandConfig;
+ return this;
+ }
+
+ public boolean isTransactionsExternallyManaged() {
+ return transactionsExternallyManaged;
+ }
+
+ public AbstractEngineConfiguration setTransactionsExternallyManaged(boolean transactionsExternallyManaged) {
+ this.transactionsExternallyManaged = transactionsExternallyManaged;
+ return this;
+ }
+
+ public Map<Object, Object> getBeans() {
+ return beans;
+ }
+
+ public AbstractEngineConfiguration setBeans(Map<Object, Object> beans) {
+ this.beans = beans;
+ return this;
+ }
+
+ public IdGenerator getIdGenerator() {
+ return idGenerator;
+ }
+
+ public AbstractEngineConfiguration setIdGenerator(IdGenerator idGenerator) {
+ this.idGenerator = idGenerator;
+ return this;
+ }
+
+ public boolean isUsePrefixId() {
+ return usePrefixId;
+ }
+
+ public AbstractEngineConfiguration setUsePrefixId(boolean usePrefixId) {
+ this.usePrefixId = usePrefixId;
+ return this;
+ }
+
+ public String getXmlEncoding() {
+ return xmlEncoding;
+ }
+
+ public AbstractEngineConfiguration setXmlEncoding(String xmlEncoding) {
+ this.xmlEncoding = xmlEncoding;
+ return this;
+ }
+
+ public CommandConfig getDefaultCommandConfig() {
+ return defaultCommandConfig;
+ }
+
+ public AbstractEngineConfiguration setDefaultCommandConfig(CommandConfig defaultCommandConfig) {
+ this.defaultCommandConfig = defaultCommandConfig;
+ return this;
+ }
+
+ public CommandExecutor getCommandExecutor() {
+ return commandExecutor;
+ }
+
+ public AbstractEngineConfiguration setCommandExecutor(CommandExecutor commandExecutor) {
+ this.commandExecutor = commandExecutor;
+ return this;
+ }
+
+ public CommandContextFactory getCommandContextFactory() {
+ return commandContextFactory;
+ }
+
+ public AbstractEngineConfiguration setCommandContextFactory(CommandContextFactory commandContextFactory) {
+ this.commandContextFactory = commandContextFactory;
+ return this;
+ }
+
+ public CommandInterceptor getCommandInvoker() {
+ return commandInvoker;
+ }
+
+ public AbstractEngineConfiguration setCommandInvoker(CommandInterceptor commandInvoker) {
+ this.commandInvoker = commandInvoker;
+ return this;
+ }
+
+ public List<CommandInterceptor> getCustomPreCommandInterceptors() {
+ return customPreCommandInterceptors;
+ }
+
+ public AbstractEngineConfiguration setCustomPreCommandInterceptors(List<CommandInterceptor> customPreCommandInterceptors) {
+ this.customPreCommandInterceptors = customPreCommandInterceptors;
+ return this;
+ }
+
+ public List<CommandInterceptor> getCustomPostCommandInterceptors() {
+ return customPostCommandInterceptors;
+ }
+
+ public AbstractEngineConfiguration setCustomPostCommandInterceptors(List<CommandInterceptor> customPostCommandInterceptors) {
+ this.customPostCommandInterceptors = customPostCommandInterceptors;
+ return this;
+ }
+
+ public List<CommandInterceptor> getCommandInterceptors() {
+ return commandInterceptors;
+ }
+
+ public AbstractEngineConfiguration setCommandInterceptors(List<CommandInterceptor> commandInterceptors) {
+ this.commandInterceptors = commandInterceptors;
+ return this;
+ }
+
+ public Map<String, AbstractEngineConfiguration> getEngineConfigurations() {
+ return engineConfigurations;
+ }
+
+ public AbstractEngineConfiguration setEngineConfigurations(Map<String, AbstractEngineConfiguration> engineConfigurations) {
+ this.engineConfigurations = engineConfigurations;
+ return this;
+ }
+
+ public void addEngineConfiguration(String key, AbstractEngineConfiguration engineConfiguration) {
+ if (engineConfigurations == null) {
+ engineConfigurations = new HashMap<>();
+ }
+ engineConfigurations.put(key, engineConfiguration);
+ }
+
+ public Map<String, AbstractServiceConfiguration> getServiceConfigurations() {
+ return serviceConfigurations;
+ }
+
+ public AbstractEngineConfiguration setServiceConfigurations(Map<String, AbstractServiceConfiguration> serviceConfigurations) {
+ this.serviceConfigurations = serviceConfigurations;
+ return this;
+ }
+
+ public void addServiceConfiguration(String key, AbstractServiceConfiguration serviceConfiguration) {
+ if (serviceConfigurations == null) {
+ serviceConfigurations = new HashMap<>();
+ }
+ serviceConfigurations.put(key, serviceConfiguration);
+ }
+
+ public void setDefaultCommandInterceptors(Collection<? extends CommandInterceptor> defaultCommandInterceptors) {
+ this.defaultCommandInterceptors = defaultCommandInterceptors;
+ }
+
+ public SqlSessionFactory getSqlSessionFactory() {
+ return sqlSessionFactory;
+ }
+
+ public AbstractEngineConfiguration setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
+ this.sqlSessionFactory = sqlSessionFactory;
+ return this;
+ }
+
+ public boolean isDbHistoryUsed() {
+ return isDbHistoryUsed;
+ }
+
+ public AbstractEngineConfiguration setDbHistoryUsed(boolean isDbHistoryUsed) {
+ this.isDbHistoryUsed = isDbHistoryUsed;
+ return this;
+ }
+
+ public DbSqlSessionFactory getDbSqlSessionFactory() {
+ return dbSqlSessionFactory;
+ }
+
+ public AbstractEngineConfiguration setDbSqlSessionFactory(DbSqlSessionFactory dbSqlSessionFactory) {
+ this.dbSqlSessionFactory = dbSqlSessionFactory;
+ return this;
+ }
+
+ public TransactionFactory getTransactionFactory() {
+ return transactionFactory;
+ }
+
+ public AbstractEngineConfiguration setTransactionFactory(TransactionFactory transactionFactory) {
+ this.transactionFactory = transactionFactory;
+ return this;
+ }
+
+ public TransactionContextFactory getTransactionContextFactory() {
+ return transactionContextFactory;
+ }
+
+ public AbstractEngineConfiguration setTransactionContextFactory(TransactionContextFactory transactionContextFactory) {
+ this.transactionContextFactory = transactionContextFactory;
+ return this;
+ }
+
+ public int getMaxNrOfStatementsInBulkInsert() {
+ return maxNrOfStatementsInBulkInsert;
+ }
+
+ public AbstractEngineConfiguration setMaxNrOfStatementsInBulkInsert(int maxNrOfStatementsInBulkInsert) {
+ this.maxNrOfStatementsInBulkInsert = maxNrOfStatementsInBulkInsert;
+ return this;
+ }
+
+ public boolean isBulkInsertEnabled() {
+ return isBulkInsertEnabled;
+ }
+
+ public AbstractEngineConfiguration setBulkInsertEnabled(boolean isBulkInsertEnabled) {
+ this.isBulkInsertEnabled = isBulkInsertEnabled;
+ return this;
+ }
+
+ public Set<Class<?>> getCustomMybatisMappers() {
+ return customMybatisMappers;
+ }
+
+ public AbstractEngineConfiguration setCustomMybatisMappers(Set<Class<?>> customMybatisMappers) {
+ this.customMybatisMappers = customMybatisMappers;
+ return this;
+ }
+
+ public Set<String> getCustomMybatisXMLMappers() {
+ return customMybatisXMLMappers;
+ }
+
+ public AbstractEngineConfiguration setCustomMybatisXMLMappers(Set<String> customMybatisXMLMappers) {
+ this.customMybatisXMLMappers = customMybatisXMLMappers;
+ return this;
+ }
+
+ public Set<String> getDependentEngineMyBatisXmlMappers() {
+ return dependentEngineMyBatisXmlMappers;
+ }
+
+ public AbstractEngineConfiguration setCustomMybatisInterceptors(List<Interceptor> customMybatisInterceptors) {
+ this.customMybatisInterceptors = customMybatisInterceptors;
+ return this;
+ }
+
+ public List<Interceptor> getCustomMybatisInterceptors() {
+ return customMybatisInterceptors;
+ }
+
+ public AbstractEngineConfiguration setDependentEngineMyBatisXmlMappers(Set<String> dependentEngineMyBatisXmlMappers) {
+ this.dependentEngineMyBatisXmlMappers = dependentEngineMyBatisXmlMappers;
+ return this;
+ }
+
+ public List<MybatisTypeAliasConfigurator> getDependentEngineMybatisTypeAliasConfigs() {
+ return dependentEngineMybatisTypeAliasConfigs;
+ }
+
+ public AbstractEngineConfiguration setDependentEngineMybatisTypeAliasConfigs(List<MybatisTypeAliasConfigurator> dependentEngineMybatisTypeAliasConfigs) {
+ this.dependentEngineMybatisTypeAliasConfigs = dependentEngineMybatisTypeAliasConfigs;
+ return this;
+ }
+
+ public List<MybatisTypeHandlerConfigurator> getDependentEngineMybatisTypeHandlerConfigs() {
+ return dependentEngineMybatisTypeHandlerConfigs;
+ }
+
+ public AbstractEngineConfiguration setDependentEngineMybatisTypeHandlerConfigs(List<MybatisTypeHandlerConfigurator> dependentEngineMybatisTypeHandlerConfigs) {
+ this.dependentEngineMybatisTypeHandlerConfigs = dependentEngineMybatisTypeHandlerConfigs;
+ return this;
+ }
+
+ public List<SessionFactory> getCustomSessionFactories() {
+ return customSessionFactories;
+ }
+
+ public AbstractEngineConfiguration addCustomSessionFactory(SessionFactory sessionFactory) {
+ if (customSessionFactories == null) {
+ customSessionFactories = new ArrayList<>();
+ }
+ customSessionFactories.add(sessionFactory);
+ return this;
+ }
+
+ public AbstractEngineConfiguration setCustomSessionFactories(List<SessionFactory> customSessionFactories) {
+ this.customSessionFactories = customSessionFactories;
+ return this;
+ }
+
+ public boolean isUsingRelationalDatabase() {
+ return usingRelationalDatabase;
+ }
+
+ public AbstractEngineConfiguration setUsingRelationalDatabase(boolean usingRelationalDatabase) {
+ this.usingRelationalDatabase = usingRelationalDatabase;
+ return this;
+ }
+
+ public boolean isUsingSchemaMgmt() {
+ return usingSchemaMgmt;
+ }
+
+ public AbstractEngineConfiguration setUsingSchemaMgmt(boolean usingSchema) {
+ this.usingSchemaMgmt = usingSchema;
+ return this;
+ }
+
+ public String getDatabaseTablePrefix() {
+ return databaseTablePrefix;
+ }
+
+ public AbstractEngineConfiguration setDatabaseTablePrefix(String databaseTablePrefix) {
+ this.databaseTablePrefix = databaseTablePrefix;
+ return this;
+ }
+
+ public String getDatabaseWildcardEscapeCharacter() {
+ return databaseWildcardEscapeCharacter;
+ }
+
+ public AbstractEngineConfiguration setDatabaseWildcardEscapeCharacter(String databaseWildcardEscapeCharacter) {
+ this.databaseWildcardEscapeCharacter = databaseWildcardEscapeCharacter;
+ return this;
+ }
+
+ public String getDatabaseCatalog() {
+ return databaseCatalog;
+ }
+
+ public AbstractEngineConfiguration setDatabaseCatalog(String databaseCatalog) {
+ this.databaseCatalog = databaseCatalog;
+ return this;
+ }
+
+ public String getDatabaseSchema() {
+ return databaseSchema;
+ }
+
+ public AbstractEngineConfiguration setDatabaseSchema(String databaseSchema) {
+ this.databaseSchema = databaseSchema;
+ return this;
+ }
+
+ public boolean isTablePrefixIsSchema() {
+ return tablePrefixIsSchema;
+ }
+
+ public AbstractEngineConfiguration setTablePrefixIsSchema(boolean tablePrefixIsSchema) {
+ this.tablePrefixIsSchema = tablePrefixIsSchema;
+ return this;
+ }
+
+ public boolean isAlwaysLookupLatestDefinitionVersion() {
+ return alwaysLookupLatestDefinitionVersion;
+ }
+
+ public AbstractEngineConfiguration setAlwaysLookupLatestDefinitionVersion(boolean alwaysLookupLatestDefinitionVersion) {
+ this.alwaysLookupLatestDefinitionVersion = alwaysLookupLatestDefinitionVersion;
+ return this;
+ }
+
+ public boolean isFallbackToDefaultTenant() {
+ return fallbackToDefaultTenant;
+ }
+
+ public AbstractEngineConfiguration setFallbackToDefaultTenant(boolean fallbackToDefaultTenant) {
+ this.fallbackToDefaultTenant = fallbackToDefaultTenant;
+ return this;
+ }
+
+ /**
+ * @return name of the default tenant
+ * @deprecated use {@link AbstractEngineConfiguration#getDefaultTenantProvider()} instead
+ */
+ @Deprecated
+ public String getDefaultTenantValue() {
+ return getDefaultTenantProvider().getDefaultTenant(null, null, null);
+ }
+
+ public AbstractEngineConfiguration setDefaultTenantValue(String defaultTenantValue) {
+ this.defaultTenantProvider = (tenantId, scope, scopeKey) -> defaultTenantValue;
+ return this;
+ }
+
+ public DefaultTenantProvider getDefaultTenantProvider() {
+ return defaultTenantProvider;
+ }
+
+ public AbstractEngineConfiguration setDefaultTenantProvider(DefaultTenantProvider defaultTenantProvider) {
+ this.defaultTenantProvider = defaultTenantProvider;
+ return this;
+ }
+
+ public boolean isEnableLogSqlExecutionTime() {
+ return enableLogSqlExecutionTime;
+ }
+
+ public void setEnableLogSqlExecutionTime(boolean enableLogSqlExecutionTime) {
+ this.enableLogSqlExecutionTime = enableLogSqlExecutionTime;
+ }
+
+ public Map<Class<?>, SessionFactory> getSessionFactories() {
+ return sessionFactories;
+ }
+
+ public AbstractEngineConfiguration setSessionFactories(Map<Class<?>, SessionFactory> sessionFactories) {
+ this.sessionFactories = sessionFactories;
+ return this;
+ }
+
+ public String getDatabaseSchemaUpdate() {
+ return databaseSchemaUpdate;
+ }
+
+ public AbstractEngineConfiguration setDatabaseSchemaUpdate(String databaseSchemaUpdate) {
+ this.databaseSchemaUpdate = databaseSchemaUpdate;
+ return this;
+ }
+
+ public boolean isEnableEventDispatcher() {
+ return enableEventDispatcher;
+ }
+
+ public AbstractEngineConfiguration setEnableEventDispatcher(boolean enableEventDispatcher) {
+ this.enableEventDispatcher = enableEventDispatcher;
+ return this;
+ }
+
+ public FlowableEventDispatcher getEventDispatcher() {
+ return eventDispatcher;
+ }
+
+ public AbstractEngineConfiguration setEventDispatcher(FlowableEventDispatcher eventDispatcher) {
+ this.eventDispatcher = eventDispatcher;
+ return this;
+ }
+
+ public List<FlowableEventListener> getEventListeners() {
+ return eventListeners;
+ }
+
+ public AbstractEngineConfiguration setEventListeners(List<FlowableEventListener> eventListeners) {
+ this.eventListeners = eventListeners;
+ return this;
+ }
+
+ public Map<String, List<FlowableEventListener>> getTypedEventListeners() {
+ return typedEventListeners;
+ }
+
+ public AbstractEngineConfiguration setTypedEventListeners(Map<String, List<FlowableEventListener>> typedEventListeners) {
+ this.typedEventListeners = typedEventListeners;
+ return this;
+ }
+
+ public List<EventDispatchAction> getAdditionalEventDispatchActions() {
+ return additionalEventDispatchActions;
+ }
+
+ public AbstractEngineConfiguration setAdditionalEventDispatchActions(List<EventDispatchAction> additionalEventDispatchActions) {
+ this.additionalEventDispatchActions = additionalEventDispatchActions;
+ return this;
+ }
+
+ public Clock getClock() {
+ return clock;
+ }
+
+ public AbstractEngineConfiguration setClock(Clock clock) {
+ this.clock = clock;
+ return this;
+ }
+
+ public int getMaxLengthString() {
+ if (maxLengthStringVariableType == -1) {
+ if ("oracle".equalsIgnoreCase(databaseType)) {
+ return DEFAULT_ORACLE_MAX_LENGTH_STRING;
+ } else {
+ return DEFAULT_GENERIC_MAX_LENGTH_STRING;
+ }
+ } else {
+ return maxLengthStringVariableType;
+ }
+ }
+
+ public int getMaxLengthStringVariableType() {
+ return maxLengthStringVariableType;
+ }
+
+ public AbstractEngineConfiguration setMaxLengthStringVariableType(int maxLengthStringVariableType) {
+ this.maxLengthStringVariableType = maxLengthStringVariableType;
+ return this;
+ }
+
+ public List<EngineDeployer> getDeployers() {
+ return deployers;
+ }
+
+ public AbstractEngineConfiguration setDeployers(List<EngineDeployer> deployers) {
+ this.deployers = deployers;
+ return this;
+ }
+
+ public List<EngineDeployer> getCustomPreDeployers() {
+ return customPreDeployers;
+ }
+
+ public AbstractEngineConfiguration setCustomPreDeployers(List<EngineDeployer> customPreDeployers) {
+ this.customPreDeployers = customPreDeployers;
+ return this;
+ }
+
+ public List<EngineDeployer> getCustomPostDeployers() {
+ return customPostDeployers;
+ }
+
+ public AbstractEngineConfiguration setCustomPostDeployers(List<EngineDeployer> customPostDeployers) {
+ this.customPostDeployers = customPostDeployers;
+ return this;
+ }
+
+ public boolean isEnableConfiguratorServiceLoader() {
+ return enableConfiguratorServiceLoader;
+ }
+
+ public AbstractEngineConfiguration setEnableConfiguratorServiceLoader(boolean enableConfiguratorServiceLoader) {
+ this.enableConfiguratorServiceLoader = enableConfiguratorServiceLoader;
+ return this;
+ }
+
+ public List<EngineConfigurator> getConfigurators() {
+ return configurators;
+ }
+
+ public AbstractEngineConfiguration addConfigurator(EngineConfigurator configurator) {
+ if (configurators == null) {
+ configurators = new ArrayList<>();
+ }
+ configurators.add(configurator);
+ return this;
+ }
+
+ public AbstractEngineConfiguration setConfigurators(List<EngineConfigurator> configurators) {
+ this.configurators = configurators;
+ return this;
+ }
+
+ public EngineConfigurator getIdmEngineConfigurator() {
+ return idmEngineConfigurator;
+ }
+
+ public AbstractEngineConfiguration setIdmEngineConfigurator(EngineConfigurator idmEngineConfigurator) {
+ this.idmEngineConfigurator = idmEngineConfigurator;
+ return this;
+ }
+
+ public AbstractEngineConfiguration setForceCloseMybatisConnectionPool(boolean forceCloseMybatisConnectionPool) {
+ this.forceCloseMybatisConnectionPool = forceCloseMybatisConnectionPool;
+ return this;
+ }
+
+ public boolean isForceCloseMybatisConnectionPool() {
+ return forceCloseMybatisConnectionPool;
+ }
+}
--
Gitblit v1.9.3