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

org.sqlproc.engine.SqlProcessorLoader Maven / Gradle / Ivy

There is a newer version: 3.6.1
Show newest version
package org.sqlproc.engine;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sqlproc.engine.annotation.Beta;
import org.sqlproc.engine.config.SqlEngineConfiguration;
import org.sqlproc.engine.impl.SqlDefaultFeatures;
import org.sqlproc.engine.impl.SqlMappingRule;
import org.sqlproc.engine.impl.SqlMetaStatement;
import org.sqlproc.engine.impl.SqlProcessResult;
import org.sqlproc.engine.impl.SqlProcessor;
import org.sqlproc.engine.plugin.SqlPluginFactory;
import org.sqlproc.engine.type.SqlComposedTypeFactory;
import org.sqlproc.engine.type.SqlInternalType;
import org.sqlproc.engine.type.SqlTypeFactory;
import org.sqlproc.engine.validation.SqlValidatorFactory;

/**
 * The helper class for the META SQL statements and mapping rules parsing. These statements and rules are taken from the
 * file repository based on the provided ANTLR grammar.
* * The purpose of this class is to load and analyze (=parse) the SQL Processor artifacts: *
    *
  • the META SQL statements
  • *
  • the mapping rules
  • *
  • the optional features
  • *
* *

* This is rather a low level helper class. For more simple approach please see {@link SqlDefaultFactory} * *

* All the statements with the name name(QRY) are parsed as the META SQL queries using the ANTLR based * grammar.
* All the statements with the name name(CRUD) are parsed as the META SQL CRUD statements using the ANTLR * based grammar.
* All the statements with the name name(CALL) are parsed as the META SQL CALL statements using the ANTLR * based grammar. These are used to call the stored procedures.
* All the statements with the name name(OUT) are parsed as the mapping rules using the ANTLR based * grammar.
* A pair of the META SQL statement and the (optional) mapping rule forms one named SQL Engine instance.
* All the statements with the name name(OPT) are taken as the optional features used in the process of the * SQL query/statement generation and execution.
*

* In the process of ANTLR based parsing different kinds of incorrect stuff can cause the {@link SqlEngineException} to * be raised. * *

* In the process of the META SQL statements and mapping rules parsing the input/output values META types have to be * established. For this purpose a factory class responsible for these META types construction has to be supplied.
* *

* To initialize the SqlProcessorLoader, Spring DI configuration can be utilized, like the next one:
* *

 * <beans ...>
 *   ...
 *     <bean id="sqlFactory" class="org.sqlproc.engine.jdbc.JdbcEngineFactory" init-method="init">
 *         <property name="metaFilesNames">
 *             <list>
 *                 <value>statements.qry</value>
 *             </list>
 *         </property>
 *     </bean>
 * </beans>
 * 
* * and use the next code to obtain an instance of the SQL Query engine * *
 * SqlEngineFactory sqlFactory = context.getBean("sqlFactory", SqlEngineFactory.class);
 * SqlQueryEngine sqlEngine = sqlFactory.getQueryEngine("ALL");
 * 
* * or the next code to obtain an instance of the SQL CRUD engine * *
 * SqlEngineFactory sqlFactory = context.getBean("sqlFactory", SqlEngineFactory.class);
 * SqlCrudEngine sqlEngine = sqlFactory.getCrudEngine("ALL");
 * 
*

* Another possibility is to utilize {@link SqlFilesLoader}. * *

 * SqlFilesLoader loader = new SqlFilesLoader("statements.qry", this.getClass());
 * SqlProcessorLoader sqlLoader = new SqlProcessorLoader(loader.getStatements(), JdbcTypeFactory.getInstance());
 * SqlQueryEngine sqlEngine = sqlLoader.getQueryEngine("ALL");
 * 
* *

* For more info please see the Tutorials. * * @author Vladimir Hudec */ public class SqlProcessorLoader { /** * The SQL Engine types */ public enum EngineType { Query, Crud, Procedure } /** * The SQL Processor initialized engines */ static class Engine { ConcurrentHashMap sqls = new ConcurrentHashMap<>(); ConcurrentHashMap cruds = new ConcurrentHashMap<>(); ConcurrentHashMap calls = new ConcurrentHashMap<>(); ConcurrentHashMap get(EngineType type) { if (type == EngineType.Query) return sqls; if (type == EngineType.Crud) return cruds; return calls; } } /** * The SQL Processor processing cache */ static class Cache { ConcurrentHashMap> sqls = new ConcurrentHashMap<>(); ConcurrentHashMap> cruds = new ConcurrentHashMap<>(); ConcurrentHashMap> calls = new ConcurrentHashMap<>(); ConcurrentHashMap> get(EngineType type) { if (type == EngineType.Query) return sqls; if (type == EngineType.Crud) return cruds; return calls; } } /** * The internal slf4j logger. */ protected final Logger logger = LoggerFactory.getLogger(getClass()); /** * The combined factory for the META types construction. */ private SqlTypeFactory composedTypeFactory; /** * The factory for the SQL Processor plugins. This is the basic facility to alter the SQL Processor processing. */ private SqlPluginFactory pluginFactory; /** * The monitor factory used in the process of the SQL Monitor instances creation */ private SqlMonitorFactory monitorFactory; /** * The validator factory used in the process of the SQL Monitor instances creation */ private SqlValidatorFactory validatorFactory; /** * The collection of named SQL Engines (the primary SQL Processor class) instances. */ private Engine engines = new Engine(); /** * The collection of named dynamic SQL Engines (the primary SQL Processor class) instances. */ private Engine dynamicEngines = new Engine(); /** * The collection of named META SQL queries. */ private Map sqls; /** * The collection of named META SQL CRUD statements. */ private Map cruds; /** * The collection of named META SQL CALLABLE statements. */ private Map calls; /** * The collection of named explicitly defined mapping rules. */ private Map outs; /** * The collection of the SQL Processor optional features. */ private Map features; /** * The collection of the SQL Processor optional features in the statement context. */ private Map> statementsFeatures; /** * The collection of the SQL Processor optional features to be cleared in the statement context. */ private Map> statementsFeaturesUnset; /** * The overall configuration, which can be persisted. */ private SqlEngineConfiguration configuration; /** * The processing cache used for {@link SqlProcessResult} instances. */ private Cache processingCache = new Cache(); /** * Creates a new instance of the SqlProcessorLoader from the String content repository (which is in fact a * collection of the META SQL statements, mapping rules and optional features. During the instance construction all * the statements are parsed and the collection of named SQL Engine instances is established. Later these instances * are used for the SQL queries/statements execution. For the purpose of the META types construction (located inside * the META SQL statements and mapping rules) a factory instance has to be supplied. * * @param sbStatements * the String representation of the META SQL queries/statements/output mappings * @param typeFactory * the factory for the META types construction * @param pluginFactory * the factory for the SQL Processor plugins * @throws SqlEngineException * mainly in the case the provided statements or rules are not compliant with the ANTLR based grammar */ public SqlProcessorLoader(StringBuilder sbStatements, SqlTypeFactory typeFactory, SqlPluginFactory pluginFactory) throws SqlEngineException { this(sbStatements, typeFactory, pluginFactory, null, null, null, (String[]) null); } /** * Creates a new instance of the SqlProcessorLoader from the String content repository (which is in fact a * collection of the META SQL statements, mapping rules and optional features. During the instance construction all * the statements are parsed and the collection of named SQL Engine instances is established. Later these instances * are used for the SQL queries/statements execution. For the purpose of the META types construction (located inside * the META SQL statements and mapping rules) a factory instance has to be supplied. * * @param sbStatements * the String representation of the META SQL queries/statements/output mappings * @param typeFactory * the factory for the META types construction * @param pluginFactory * the factory for the SQL Processor plugins * @param filter * the properties name prefix to filter the META SQL statements, mapping rules and optional features * @throws SqlEngineException * mainly in the case the provided statements or rules are not compliant with the ANTLR based grammar */ public SqlProcessorLoader(StringBuilder sbStatements, SqlTypeFactory typeFactory, SqlPluginFactory pluginFactory, String filter) throws SqlEngineException { this(sbStatements, typeFactory, pluginFactory, filter, null, null, (String[]) null); } /** * Creates a new instance of the SqlProcessorLoader from the String content repository (which is in fact a * collection of the META SQL statements, mapping rules and optional features. During the instance construction all * the statements are parsed and the collection of named SQL Engine instances is established. Later these instances * are used for the SQL queries/statements execution. For the purpose of the META types construction (located inside * the META SQL statements and mapping rules) a factory instance has to be supplied. Every instance of the SQL * Engine is accompanied with the SQL Monitor for the runtime statistics gathering. For the creation of these * monitors the SQL Monitor Factory can be used. * * @param sbStatements * the String representation of the META SQL queries/statements/output mappings * @param typeFactory * the factory for the META types construction * @param pluginFactory * the factory for the SQL Processor plugins * @param filter * the properties name prefix to filter the META SQL statements, mapping rules and optional features * @param monitorFactory * the monitor factory used in the process of the SQL Monitor instances creation * @throws SqlEngineException * mainly in the case the provided statements or rules are not compliant with the ANTLR based grammar */ public SqlProcessorLoader(StringBuilder sbStatements, SqlTypeFactory typeFactory, SqlPluginFactory pluginFactory, String filter, SqlMonitorFactory monitorFactory) throws SqlEngineException { this(sbStatements, typeFactory, pluginFactory, filter, monitorFactory, null, (String[]) null); } /** * Creates a new instance of the SqlProcessorLoader from the String content repository (which is in fact a * collection of the META SQL statements, mapping rules and optional features. During the instance construction all * the statements are parsed and the collection of named SQL Engine instances is established. Later these instances * are used for the SQL queries/statements execution. For the purpose of the META types construction (located inside * the META SQL statements and mapping rules) a factory instance has to be supplied. Every instance of the SQL * Engine is accompanied with the SQL Monitor for the runtime statistics gathering. For the creation of these * monitors the SQL Monitor Factory can be used. * * @param sbStatements * the String representation of the META SQL queries/statements/output mappings * @param typeFactory * the factory for the META types construction * @param pluginFactory * the factory for the SQL Processor plugins * @param filter * the properties name prefix to filter the META SQL statements, mapping rules and optional features * @param monitorFactory * the monitor factory used in the process of the SQL Monitor instances creation * @param onlyStatements * only statements and rules with the names in this container are picked up from the properties * repository * @throws SqlEngineException * mainly in the case the provided statements or rules are not compliant with the ANTLR based grammar */ public SqlProcessorLoader(StringBuilder sbStatements, SqlTypeFactory typeFactory, SqlPluginFactory pluginFactory, String filter, SqlMonitorFactory monitorFactory, String... onlyStatements) { this(sbStatements, typeFactory, pluginFactory, filter, monitorFactory, null, onlyStatements); } /** * Creates a new instance of the SqlProcessorLoader from the String content repository (which is in fact a * collection of the META SQL statements, mapping rules and optional features. During the instance construction all * the statements are parsed and the collection of named SQL Engine instances is established. Later these instances * are used for the SQL queries/statements execution. For the purpose of the META types construction (located inside * the META SQL statements and mapping rules) a factory instance has to be supplied. Every instance of the SQL * Engine is accompanied with the SQL Monitor for the runtime statistics gathering. For the creation of these * monitors the SQL Monitor Factory can be used. * * @param sbStatements * the String representation of the META SQL queries/statements/output mappings * @param typeFactory * the factory for the META types construction * @param pluginFactory * the factory for the SQL Processor plugins * @param filter * the properties name prefix to filter the META SQL statements, mapping rules and optional features * @param monitorFactory * the monitor factory used in the process of the SQL Monitor instances creation * @param customTypes * the custom META types * @param onlyStatements * only statements and rules with the names in this container are picked up from the properties * repository * @throws SqlEngineException * mainly in the case the provided statements or rules are not compliant with the ANTLR based grammar */ public SqlProcessorLoader(StringBuilder sbStatements, SqlTypeFactory typeFactory, SqlPluginFactory pluginFactory, String filter, SqlMonitorFactory monitorFactory, List customTypes, String... onlyStatements) throws SqlEngineException { this(sbStatements, typeFactory, pluginFactory, filter, monitorFactory, null, customTypes, onlyStatements); } /** * Creates a new instance of the SqlProcessorLoader from the String content repository (which is in fact a * collection of the META SQL statements, mapping rules and optional features. During the instance construction all * the statements are parsed and the collection of named SQL Engine instances is established. Later these instances * are used for the SQL queries/statements execution. For the purpose of the META types construction (located inside * the META SQL statements and mapping rules) a factory instance has to be supplied. Every instance of the SQL * Engine is accompanied with the SQL Monitor for the runtime statistics gathering. For the creation of these * monitors the SQL Monitor Factory can be used. * * @param sbStatements * the String representation of the META SQL queries/statements/output mappings * @param typeFactory * the factory for the META types construction * @param pluginFactory * the factory for the SQL Processor plugins * @param filter * the properties name prefix to filter the META SQL statements, mapping rules and optional features * @param monitorFactory * the monitor factory used in the process of the SQL Monitor instances creation * @param validatorFactory * the validator factory used in the process of the SQL Monitor instances creation * @param customTypes * the custom META types * @param onlyStatements * only statements and rules with the names in this container are picked up from the properties * repository * @throws SqlEngineException * mainly in the case the provided statements or rules are not compliant with the ANTLR based grammar */ public SqlProcessorLoader(StringBuilder sbStatements, SqlTypeFactory typeFactory, SqlPluginFactory pluginFactory, String filter, SqlMonitorFactory monitorFactory, SqlValidatorFactory validatorFactory, List customTypes, String... onlyStatements) throws SqlEngineException { this(sbStatements, typeFactory, pluginFactory, filter, monitorFactory, validatorFactory, customTypes, null, onlyStatements); } /** * Creates a new instance of the SqlProcessorLoader from the String content repository (which is in fact a * collection of the META SQL statements, mapping rules and optional features. During the instance construction all * the statements are parsed and the collection of named SQL Engine instances is established. Later these instances * are used for the SQL queries/statements execution. For the purpose of the META types construction (located inside * the META SQL statements and mapping rules) a factory instance has to be supplied. Every instance of the SQL * Engine is accompanied with the SQL Monitor for the runtime statistics gathering. For the creation of these * monitors the SQL Monitor Factory can be used. * * @param sbStatements * the String representation of the META SQL queries/statements/output mappings * @param typeFactory * the factory for the META types construction * @param pluginFactory * the factory for the SQL Processor plugins * @param filter * the properties name prefix to filter the META SQL statements, mapping rules and optional features * @param monitorFactory * the monitor factory used in the process of the SQL Monitor instances creation * @param validatorFactory * the validator factory used in the process of the SQL Monitor instances creation * @param customTypes * the custom META types * @param configuration * the overall configuration, which can be persisted * @param onlyStatements * only statements and rules with the names in this container are picked up from the properties * repository * @throws SqlEngineException * mainly in the case the provided statements or rules are not compliant with the ANTLR based grammar */ public SqlProcessorLoader(StringBuilder sbStatements, SqlTypeFactory typeFactory, SqlPluginFactory pluginFactory, String filter, SqlMonitorFactory monitorFactory, SqlValidatorFactory validatorFactory, List customTypes, SqlEngineConfiguration configuration, String... onlyStatements) throws SqlEngineException { logger.trace( ">> SqlProcessorLoader, sbStatements={}, typeFactory={}, pluginFactory={}, monitorFactory={}, validatorFactory={}, filter={}, customTypes={}, configuration={}, onlyStatements={}", sbStatements, typeFactory, pluginFactory, monitorFactory, validatorFactory, filter, customTypes, configuration, onlyStatements); long start = System.currentTimeMillis(); if (sbStatements == null) throw new SqlEngineException("Missing SQL META queries/statements/output mappings"); if (typeFactory == null) throw new SqlEngineException("Missing the META types factory"); this.composedTypeFactory = new SqlComposedTypeFactory(typeFactory, customTypes); this.pluginFactory = pluginFactory; this.validatorFactory = validatorFactory; this.monitorFactory = monitorFactory; this.configuration = configuration; try { Set setSelectQueries = (onlyStatements != null && onlyStatements.length > 0) ? new HashSet(Arrays.asList(onlyStatements)) : null; filter = (filter != null) ? filter.toUpperCase() : null; Map defaultFeatures = SqlDefaultFeatures.getFilteredFeatures(filter); StringBuilder errors = new StringBuilder(); SqlProcessor processor = null; try { processor = (isLazyInit()) ? SqlProcessor.getLazyInstance(sbStatements, composedTypeFactory, defaultFeatures, setSelectQueries, filter) : SqlProcessor.getInstance(sbStatements, composedTypeFactory, defaultFeatures, setSelectQueries, filter); } catch (SqlEngineException see) { errors.append(see.getMessage()); } if (errors.length() > 0) throw new SqlEngineException(errors.toString()); if (!processor.getWarnings().isEmpty()) { logger.warn("== SqlProcessorLoader, there're warnings in the process of statements parsing: {}", processor.getWarnings()); } sqls = processor.getMetaStatements(SqlProcessor.StatementType.QRY); cruds = processor.getMetaStatements(SqlProcessor.StatementType.CRUD); calls = processor.getMetaStatements(SqlProcessor.StatementType.CALL); outs = processor.getMappingRules(SqlProcessor.MappingType.OUT); features = processor.getFeatures(); statementsFeatures = processor.getStatementsFeatures(); statementsFeaturesUnset = processor.getStatementsFeaturesUnset(); for (String name : outs.keySet()) { if (!sqls.containsKey(name) && !calls.containsKey(name) && !cruds.containsKey(name)) errors.append("For the OUT/FIELDS there's no QRY: ").append(name).append("\n"); } if (errors.length() > 0) throw new SqlEngineException(errors.toString()); } finally { if (logger.isDebugEnabled()) { long end = System.currentTimeMillis(); logger.debug("== SqlProcessorLoader, lazyInit={}, duration in ms={}", isLazyInit(), (end - start)); } logger.trace("<< SqlProcessorLoader, engines={}, sqls={}, cruds={}, fields={}, features={}", engines, sqls, cruds, outs, features); } } /** * Initializes all SQL Processor engines. It can be done synchronously or asynchronously. For every engine, for * which there's error in the initialization process there a error message. * * @param executor * The asynchronous executor. In the case it is null, the initialization is provided in synchronous mode. * @param sqlsToInit * The SQL engine names to initialize. * @param crudsToInit * The CRUD engine names to initialize. * @param callsToInit * The Procedure engine names to initialize. */ public void init(Executor executor, Set sqlsToInit, Set crudsToInit, Set callsToInit) { if (executor != null) logger.warn(">> init, executor {}", executor); else logger.trace(">> init"); long start = System.currentTimeMillis(); try { if (executor != null) { Set names = (sqlsToInit != null) ? sqlsToInit : sqls.keySet(); for (String name : names) { AsyncEngineInit aei = new AsyncEngineInit(name, EngineType.Query, enginesInitErrors); executor.execute(aei); } names = (crudsToInit != null) ? crudsToInit : cruds.keySet(); for (String name : names) { AsyncEngineInit aei = new AsyncEngineInit(name, EngineType.Crud, enginesInitErrors); executor.execute(aei); } names = (callsToInit != null) ? callsToInit : calls.keySet(); for (String name : names) { AsyncEngineInit aei = new AsyncEngineInit(name, EngineType.Procedure, enginesInitErrors); executor.execute(aei); } } else { Set names = (sqlsToInit != null) ? sqlsToInit : sqls.keySet(); for (String name : names) { try { logger.info("== sync init, name={}, type={} in {}", name, EngineType.Query, Thread.currentThread().getName()); getEngine(name, EngineType.Query); } catch (SqlEngineException ex) { String msg = ex.getMessage(); enginesInitErrors.put(EngineType.Query.name() + ":" + name, msg); logger.warn("!! init, name={}, error={}", name, msg); } } names = (crudsToInit != null) ? crudsToInit : cruds.keySet(); for (String name : names) { try { logger.info("== sync init, name={}, type={} in {}", name, EngineType.Crud, Thread.currentThread().getName()); getEngine(name, EngineType.Crud); } catch (SqlEngineException ex) { String msg = ex.getMessage(); enginesInitErrors.put(EngineType.Crud.name() + ":" + name, msg); logger.warn("!! init, name={}, error={}", name, msg); } } names = (callsToInit != null) ? callsToInit : calls.keySet(); for (String name : names) { try { logger.info("== sync init, name={}, type={} in {}", name, EngineType.Procedure, Thread.currentThread().getName()); getEngine(name, EngineType.Procedure); } catch (SqlEngineException ex) { String msg = ex.getMessage(); enginesInitErrors.put(EngineType.Procedure.name() + ":" + name, msg); logger.warn("!! init, name={}, error={}", name, msg); } } } } finally { if (logger.isDebugEnabled()) { long end = System.currentTimeMillis(); logger.debug("== init, duration in ms=" + (end - start)); } if (logger.isTraceEnabled()) { logger.trace("<< init"); } } } /** * The result of initialization. For every engine, for which there's error in the initialization process there a * error message. */ private ConcurrentHashMap enginesInitErrors = new ConcurrentHashMap(); /** * Returns the result of engines initialization process. For every engine, for which there's error in the * initialization process there a error message. In the case there's no error, the result message is null. * * @return the result of engines initialization process */ public ConcurrentHashMap getEnginesInitErrors() { return enginesInitErrors; } /** * Returns the result of engines initialization process. For every engine, for which there's error in the * initialization process there a error message. In the case there's no error, the result message is null. * * @return the result of engines initialization process */ public String getEnginesInitErrorsMsg() { StringBuilder sb = new StringBuilder(); boolean isError = false; for (Entry e : enginesInitErrors.entrySet()) { if (e.getValue() != null) { if (isError) sb.append("\n"); sb.append(e.getKey() + ": " + e.getValue()); isError = true; } } if (isError) return sb.toString(); return null; } @Beta private class AsyncEngineInit implements Runnable { private String name; private EngineType engineType; private ConcurrentHashMap enginesInitErrors; public AsyncEngineInit(String name, EngineType engineType, ConcurrentHashMap enginesInitErrors) { this.name = name; this.engineType = engineType; this.enginesInitErrors = enginesInitErrors; } @Override public void run() { logger.info("== async init, name={}, type={} in {}", name, engineType, Thread.currentThread().getName()); try { getEngine(name, engineType); } catch (SqlEngineException ex) { String msg = ex.getMessage(); enginesInitErrors.put(engineType.name() + ":" + name, msg); logger.warn("!! init, name={}, error={}", name, msg); } } } /** * Some filters can be the optional features in the statement context. * * @param name * the name of the META SQL statement */ private void loadStatementFeatures(String name, SqlEngine sqlEngine) { Map statementFeatures = statementsFeatures.get(name); if (statementFeatures != null) { for (Map.Entry entry : statementFeatures.entrySet()) { sqlEngine.setFeature(entry.getKey(), entry.getValue()); } } Set statementFeaturesUnset = statementsFeaturesUnset.get(name); if (statementFeaturesUnset != null) { sqlEngine.unsetFeatures(statementFeaturesUnset); } } /** * Returns all static engines of the required type * * @param engineType * the required SQL Engine type * @return a container of initialized engines */ public Map getEngines(EngineType engineType) { return engines.get(engineType); } /** * Returns all dynamic engines of the required type * * @param engineType * the required SQL Engine type * @return a container of initialized engines */ public Map getDynamicEngines(EngineType engineType) { return dynamicEngines.get(engineType); } /** * Creates a new instance of the SQL Engine instance (the primary SQL Processor class). * * @param name * the name of the required SQL Procedure Engine instance * @param engineType * the required SQL Engine type * @param stmt * the new SQL META statement instance for the case of static SQL Engine instance * @param sqlStatement * the new SQL statement for the case of dynamic SQL Engine instance * @return the new SQL Engine instance * @throws SqlEngineException * in the case the instance can't be created */ private SqlEngine createEngine(String name, EngineType engineType, SqlMetaStatement stmt, String sqlStatement) { SqlMetaStatement stmt2 = null; if (sqlStatement != null) stmt2 = SqlMetaStatement.getInstance(name, sqlStatement, composedTypeFactory); else if (isLazyInit()) stmt2 = SqlMetaStatement.getInstance(name, stmt.getRaw(), composedTypeFactory); else stmt2 = stmt; if (engineType == EngineType.Query && !stmt2.isHasOutputMapping() && !outs.containsKey(name)) throw new SqlEngineException("For the QRY there's no OUT: " + name); SqlMappingRule mapping = null; if (outs.containsKey(name)) { mapping = outs.get(name); if (isLazyInit()) mapping = SqlMappingRule.getInstance(name, mapping.getRaw(), composedTypeFactory); } else { mapping = new SqlMappingRule(); } SqlMonitor monitor = (monitorFactory != null) ? monitorFactory.getSqlMonitor(name, features) : null; SqlEngine sqlEngine; if (engineType == EngineType.Query) sqlEngine = new SqlQueryEngine(name, stmt2, mapping, monitor, features, this.composedTypeFactory, this.pluginFactory, this.configuration); else if (engineType == EngineType.Crud) sqlEngine = new SqlCrudEngine(name, stmt2, mapping, monitor, features, this.composedTypeFactory, this.pluginFactory, this.configuration); else sqlEngine = new SqlProcedureEngine(name, stmt2, mapping, monitor, features, this.composedTypeFactory, this.pluginFactory, this.configuration); sqlEngine.setValidator((validatorFactory != null) ? validatorFactory.getSqlValidator() : null); loadStatementFeatures(name, sqlEngine); return sqlEngine; } /** * Returns the named static SQL Engine instance (the primary SQL Processor class). * * @param name * the name of the required SQL Procedure Engine instance * @param engineType * the required SQL Engine type * @return the SQL Engine instance * @throws SqlEngineException * in the case the instance can't be created */ public SqlEngine getStaticEngine(String name, EngineType engineType) { dynamicEngines.get(engineType).remove(name); SqlEngine sqlEngine = engines.get(engineType).get(name); if (sqlEngine == null) { SqlMetaStatement stmt = getStatements(engineType).get(name); if (stmt != null) { sqlEngine = createEngine(name, engineType, stmt, null); SqlEngine sqlEnginePrev = engines.get(engineType).putIfAbsent(name, sqlEngine); if (sqlEnginePrev != null) { sqlEngine = sqlEnginePrev; } else { ConcurrentHashMap _processingCache; processingCache.get(engineType).put(name, _processingCache = new ConcurrentHashMap()); sqlEngine.setProcessingCache(_processingCache); } } } return sqlEngine; } /** * Returns the named dynamic SQL Engine instance (the primary SQL Processor class). * * @param name * the name of the required SQL Procedure Engine instance * @param engineType * the required SQL Engine type * @param sqlStatement * the new SQL statement * @return the SQL Engine instance * @throws SqlEngineException * in the case the instance can't be created */ public SqlEngine getDynamicEngine(String name, EngineType engineType, String sqlStatement) { Map stmts = getStatements(engineType); if (!stmts.containsKey(name)) throw new SqlEngineException("Missing SQL Engine " + name); if (sqlStatement == null) throw new SqlEngineException("SQL statement for SQL Engine " + name + " is null"); SqlEngine sqlEngine = createEngine(name, engineType, null, sqlStatement); dynamicEngines.get(engineType).put(name, sqlEngine); processingCache.get(engineType).put(name, new ConcurrentHashMap()); sqlEngine.setProcessingCache(processingCache.get(engineType).get(name)); return sqlEngine; } /** * Returns the named static or dynamic SQL Engine instance (the primary SQL Processor class). * * @param name * the name of the required SQL Procedure Engine instance * @param engineType * the required SQL Engine type * @return the SQL Engine instance * @throws SqlEngineException * in the case the instance can't be created */ public SqlEngine getEngine(String name, EngineType engineType) { SqlEngine sqlEngine = dynamicEngines.get(engineType).get(name); if (sqlEngine != null) return sqlEngine; return getStaticEngine(name, engineType); } /** * Returns the static statements container based on required SQL Engine type * * @param engineType * the required SQL Engine type * @return the static statements container */ private Map getStatements(EngineType engineType) { if (engineType == EngineType.Query) return sqls; else if (engineType == EngineType.Crud) return cruds; else return calls; } /** * Sets the overall dynamic configuration * * @param configuration * the overall dynamic configuration */ public void setConfiguration(SqlEngineConfiguration configuration) { this.configuration = configuration; } /** * Returns a flag which indicates the lazy initialization mode. * * @return a flag which indicates the lazy initialization mode. */ public boolean isLazyInit() { return configuration != null && configuration.getLazyInit() != null && configuration.getLazyInit(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy