|  | @@ -0,0 +1,881 @@
 | 
												
													
														
															|  | 
 |  | +/*
 | 
												
													
														
															|  | 
 |  | + *    Copyright 2009-2014 the original author or authors.
 | 
												
													
														
															|  | 
 |  | + *
 | 
												
													
														
															|  | 
 |  | + *    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.apache.ibatis.session;
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +import java.util.Arrays;
 | 
												
													
														
															|  | 
 |  | +import java.util.Collection;
 | 
												
													
														
															|  | 
 |  | +import java.util.HashMap;
 | 
												
													
														
															|  | 
 |  | +import java.util.HashSet;
 | 
												
													
														
															|  | 
 |  | +import java.util.LinkedList;
 | 
												
													
														
															|  | 
 |  | +import java.util.List;
 | 
												
													
														
															|  | 
 |  | +import java.util.Map;
 | 
												
													
														
															|  | 
 |  | +import java.util.Properties;
 | 
												
													
														
															|  | 
 |  | +import java.util.Set;
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.binding.MapperRegistry;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.builder.CacheRefResolver;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.builder.ResultMapResolver;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.builder.annotation.MethodResolver;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.builder.xml.XMLStatementBuilder;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.cache.Cache;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.cache.decorators.FifoCache;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.cache.decorators.LruCache;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.cache.decorators.SoftCache;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.cache.decorators.WeakCache;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.cache.impl.PerpetualCache;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.datasource.jndi.JndiDataSourceFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.BatchExecutor;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.CachingExecutor;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.Executor;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.ReuseExecutor;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.SimpleExecutor;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.keygen.KeyGenerator;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.loader.ProxyFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.loader.cglib.CglibProxyFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.parameter.ParameterHandler;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.resultset.DefaultResultSetHandler;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.resultset.ResultSetHandler;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.statement.RoutingStatementHandler;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.executor.statement.StatementHandler;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.logging.Log;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.logging.LogFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.logging.log4j.Log4jImpl;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.logging.log4j2.Log4j2Impl;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.logging.nologging.NoLoggingImpl;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.logging.slf4j.Slf4jImpl;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.logging.stdout.StdOutImpl;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.mapping.BoundSql;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.mapping.Environment;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.mapping.MappedStatement;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.mapping.ParameterMap;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.mapping.ResultMap;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.parsing.XNode;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.plugin.Interceptor;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.plugin.InterceptorChain;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.reflection.MetaObject;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.reflection.factory.ObjectFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.scripting.LanguageDriver;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.scripting.LanguageDriverRegistry;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.scripting.defaults.RawLanguageDriver;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.transaction.Transaction;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.type.JdbcType;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.type.TypeAliasRegistry;
 | 
												
													
														
															|  | 
 |  | +import org.apache.ibatis.type.TypeHandlerRegistry;
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +/**
 | 
												
													
														
															|  | 
 |  | + * @author Clinton Begin
 | 
												
													
														
															|  | 
 |  | + * @description 重写put,实现刷新的功能
 | 
												
													
														
															|  | 
 |  | + */
 | 
												
													
														
															|  | 
 |  | +public class Configuration {
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected Environment environment;
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected boolean safeRowBoundsEnabled = false;
 | 
												
													
														
															|  | 
 |  | +	protected boolean safeResultHandlerEnabled = true;
 | 
												
													
														
															|  | 
 |  | +	protected boolean mapUnderscoreToCamelCase = false;
 | 
												
													
														
															|  | 
 |  | +	protected boolean aggressiveLazyLoading = true;
 | 
												
													
														
															|  | 
 |  | +	protected boolean multipleResultSetsEnabled = true;
 | 
												
													
														
															|  | 
 |  | +	protected boolean useGeneratedKeys = false;
 | 
												
													
														
															|  | 
 |  | +	protected boolean useColumnLabel = true;
 | 
												
													
														
															|  | 
 |  | +	protected boolean cacheEnabled = true;
 | 
												
													
														
															|  | 
 |  | +	protected boolean callSettersOnNulls = false;
 | 
												
													
														
															|  | 
 |  | +	protected String logPrefix;
 | 
												
													
														
															|  | 
 |  | +	protected Class<? extends Log> logImpl;
 | 
												
													
														
															|  | 
 |  | +	protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
 | 
												
													
														
															|  | 
 |  | +	protected JdbcType jdbcTypeForNull = JdbcType.OTHER;
 | 
												
													
														
															|  | 
 |  | +	protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(
 | 
												
													
														
															|  | 
 |  | +			Arrays.asList(new String[] { "equals", "clone", "hashCode",
 | 
												
													
														
															|  | 
 |  | +					"toString" }));
 | 
												
													
														
															|  | 
 |  | +	protected Integer defaultStatementTimeout;
 | 
												
													
														
															|  | 
 |  | +	protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
 | 
												
													
														
															|  | 
 |  | +	protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL;
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected Properties variables = new Properties();
 | 
												
													
														
															|  | 
 |  | +	protected ObjectFactory objectFactory = new DefaultObjectFactory();
 | 
												
													
														
															|  | 
 |  | +	protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
 | 
												
													
														
															|  | 
 |  | +	protected MapperRegistry mapperRegistry = new MapperRegistry(this);
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected boolean lazyLoadingEnabled = false;
 | 
												
													
														
															|  | 
 |  | +	protected ProxyFactory proxyFactory;
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected String databaseId;
 | 
												
													
														
															|  | 
 |  | +	/**
 | 
												
													
														
															|  | 
 |  | +	 * Configuration factory class. Used to create Configuration for loading
 | 
												
													
														
															|  | 
 |  | +	 * deserialized unread properties.
 | 
												
													
														
															|  | 
 |  | +	 * 
 | 
												
													
														
															|  | 
 |  | +	 * @see <a
 | 
												
													
														
															|  | 
 |  | +	 *      href='https://code.google.com/p/mybatis/issues/detail?id=300'>Issue
 | 
												
													
														
															|  | 
 |  | +	 *      300</a> (google code)
 | 
												
													
														
															|  | 
 |  | +	 */
 | 
												
													
														
															|  | 
 |  | +	protected Class<?> configurationFactory;
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected final InterceptorChain interceptorChain = new InterceptorChain();
 | 
												
													
														
															|  | 
 |  | +	protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
 | 
												
													
														
															|  | 
 |  | +	protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
 | 
												
													
														
															|  | 
 |  | +	protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry();
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>(
 | 
												
													
														
															|  | 
 |  | +			"Mapped Statements collection");
 | 
												
													
														
															|  | 
 |  | +	protected final Map<String, Cache> caches = new StrictMap<Cache>(
 | 
												
													
														
															|  | 
 |  | +			"Caches collection");
 | 
												
													
														
															|  | 
 |  | +	protected final Map<String, ResultMap> resultMaps = new StrictMap<ResultMap>(
 | 
												
													
														
															|  | 
 |  | +			"Result Maps collection");
 | 
												
													
														
															|  | 
 |  | +	protected final Map<String, ParameterMap> parameterMaps = new StrictMap<ParameterMap>(
 | 
												
													
														
															|  | 
 |  | +			"Parameter Maps collection");
 | 
												
													
														
															|  | 
 |  | +	protected final Map<String, KeyGenerator> keyGenerators = new StrictMap<KeyGenerator>(
 | 
												
													
														
															|  | 
 |  | +			"Key Generators collection");
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected final Set<String> loadedResources = new HashSet<String>();
 | 
												
													
														
															|  | 
 |  | +	protected final Map<String, XNode> sqlFragments = new StrictMap<XNode>(
 | 
												
													
														
															|  | 
 |  | +			"XML fragments parsed from previous mappers");
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected final Collection<XMLStatementBuilder> incompleteStatements = new LinkedList<XMLStatementBuilder>();
 | 
												
													
														
															|  | 
 |  | +	protected final Collection<CacheRefResolver> incompleteCacheRefs = new LinkedList<CacheRefResolver>();
 | 
												
													
														
															|  | 
 |  | +	protected final Collection<ResultMapResolver> incompleteResultMaps = new LinkedList<ResultMapResolver>();
 | 
												
													
														
															|  | 
 |  | +	protected final Collection<MethodResolver> incompleteMethods = new LinkedList<MethodResolver>();
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	/*
 | 
												
													
														
															|  | 
 |  | +	 * A map holds cache-ref relationship. The key is the namespace that
 | 
												
													
														
															|  | 
 |  | +	 * references a cache bound to another namespace and the value is the
 | 
												
													
														
															|  | 
 |  | +	 * namespace which the actual cache is bound to.
 | 
												
													
														
															|  | 
 |  | +	 */
 | 
												
													
														
															|  | 
 |  | +	protected final Map<String, String> cacheRefMap = new HashMap<String, String>();
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Configuration(Environment environment) {
 | 
												
													
														
															|  | 
 |  | +		this();
 | 
												
													
														
															|  | 
 |  | +		this.environment = environment;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Configuration() {
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("MANAGED",
 | 
												
													
														
															|  | 
 |  | +				ManagedTransactionFactory.class);
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry
 | 
												
													
														
															|  | 
 |  | +				.registerAlias("POOLED", PooledDataSourceFactory.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("UNPOOLED",
 | 
												
													
														
															|  | 
 |  | +				UnpooledDataSourceFactory.class);
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("LRU", LruCache.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("WEAK", WeakCache.class);
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("DB_VENDOR",
 | 
												
													
														
															|  | 
 |  | +				VendorDatabaseIdProvider.class);
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("COMMONS_LOGGING",
 | 
												
													
														
															|  | 
 |  | +				JakartaCommonsLoggingImpl.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
 | 
												
													
														
															|  | 
 |  | +		typeAliasRegistry.registerAlias("JAVASSIST",
 | 
												
													
														
															|  | 
 |  | +				JavassistProxyFactory.class);
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
 | 
												
													
														
															|  | 
 |  | +		languageRegistry.register(RawLanguageDriver.class);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public String getLogPrefix() {
 | 
												
													
														
															|  | 
 |  | +		return logPrefix;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setLogPrefix(String logPrefix) {
 | 
												
													
														
															|  | 
 |  | +		this.logPrefix = logPrefix;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Class<? extends Log> getLogImpl() {
 | 
												
													
														
															|  | 
 |  | +		return logImpl;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	@SuppressWarnings("unchecked")
 | 
												
													
														
															|  | 
 |  | +	public void setLogImpl(Class<?> logImpl) {
 | 
												
													
														
															|  | 
 |  | +		if (logImpl != null) {
 | 
												
													
														
															|  | 
 |  | +			this.logImpl = (Class<? extends Log>) logImpl;
 | 
												
													
														
															|  | 
 |  | +			LogFactory.useCustomLogging(this.logImpl);
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isCallSettersOnNulls() {
 | 
												
													
														
															|  | 
 |  | +		return callSettersOnNulls;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setCallSettersOnNulls(boolean callSettersOnNulls) {
 | 
												
													
														
															|  | 
 |  | +		this.callSettersOnNulls = callSettersOnNulls;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public String getDatabaseId() {
 | 
												
													
														
															|  | 
 |  | +		return databaseId;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setDatabaseId(String databaseId) {
 | 
												
													
														
															|  | 
 |  | +		this.databaseId = databaseId;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Class<?> getConfigurationFactory() {
 | 
												
													
														
															|  | 
 |  | +		return configurationFactory;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setConfigurationFactory(Class<?> configurationFactory) {
 | 
												
													
														
															|  | 
 |  | +		this.configurationFactory = configurationFactory;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isSafeResultHandlerEnabled() {
 | 
												
													
														
															|  | 
 |  | +		return safeResultHandlerEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setSafeResultHandlerEnabled(boolean safeResultHandlerEnabled) {
 | 
												
													
														
															|  | 
 |  | +		this.safeResultHandlerEnabled = safeResultHandlerEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isSafeRowBoundsEnabled() {
 | 
												
													
														
															|  | 
 |  | +		return safeRowBoundsEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setSafeRowBoundsEnabled(boolean safeRowBoundsEnabled) {
 | 
												
													
														
															|  | 
 |  | +		this.safeRowBoundsEnabled = safeRowBoundsEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isMapUnderscoreToCamelCase() {
 | 
												
													
														
															|  | 
 |  | +		return mapUnderscoreToCamelCase;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setMapUnderscoreToCamelCase(boolean mapUnderscoreToCamelCase) {
 | 
												
													
														
															|  | 
 |  | +		this.mapUnderscoreToCamelCase = mapUnderscoreToCamelCase;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addLoadedResource(String resource) {
 | 
												
													
														
															|  | 
 |  | +		loadedResources.add(resource);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isResourceLoaded(String resource) {
 | 
												
													
														
															|  | 
 |  | +		return loadedResources.contains(resource);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Environment getEnvironment() {
 | 
												
													
														
															|  | 
 |  | +		return environment;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setEnvironment(Environment environment) {
 | 
												
													
														
															|  | 
 |  | +		this.environment = environment;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public AutoMappingBehavior getAutoMappingBehavior() {
 | 
												
													
														
															|  | 
 |  | +		return autoMappingBehavior;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setAutoMappingBehavior(AutoMappingBehavior autoMappingBehavior) {
 | 
												
													
														
															|  | 
 |  | +		this.autoMappingBehavior = autoMappingBehavior;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isLazyLoadingEnabled() {
 | 
												
													
														
															|  | 
 |  | +		return lazyLoadingEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setLazyLoadingEnabled(boolean lazyLoadingEnabled) {
 | 
												
													
														
															|  | 
 |  | +		this.lazyLoadingEnabled = lazyLoadingEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public ProxyFactory getProxyFactory() {
 | 
												
													
														
															|  | 
 |  | +		if (proxyFactory == null) {
 | 
												
													
														
															|  | 
 |  | +			// makes sure CGLIB is not needed unless explicitly requested
 | 
												
													
														
															|  | 
 |  | +			proxyFactory = new CglibProxyFactory();
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +		return proxyFactory;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setProxyFactory(ProxyFactory proxyFactory) {
 | 
												
													
														
															|  | 
 |  | +		this.proxyFactory = proxyFactory;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isAggressiveLazyLoading() {
 | 
												
													
														
															|  | 
 |  | +		return aggressiveLazyLoading;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setAggressiveLazyLoading(boolean aggressiveLazyLoading) {
 | 
												
													
														
															|  | 
 |  | +		this.aggressiveLazyLoading = aggressiveLazyLoading;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isMultipleResultSetsEnabled() {
 | 
												
													
														
															|  | 
 |  | +		return multipleResultSetsEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setMultipleResultSetsEnabled(boolean multipleResultSetsEnabled) {
 | 
												
													
														
															|  | 
 |  | +		this.multipleResultSetsEnabled = multipleResultSetsEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Set<String> getLazyLoadTriggerMethods() {
 | 
												
													
														
															|  | 
 |  | +		return lazyLoadTriggerMethods;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setLazyLoadTriggerMethods(Set<String> lazyLoadTriggerMethods) {
 | 
												
													
														
															|  | 
 |  | +		this.lazyLoadTriggerMethods = lazyLoadTriggerMethods;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isUseGeneratedKeys() {
 | 
												
													
														
															|  | 
 |  | +		return useGeneratedKeys;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setUseGeneratedKeys(boolean useGeneratedKeys) {
 | 
												
													
														
															|  | 
 |  | +		this.useGeneratedKeys = useGeneratedKeys;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public ExecutorType getDefaultExecutorType() {
 | 
												
													
														
															|  | 
 |  | +		return defaultExecutorType;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setDefaultExecutorType(ExecutorType defaultExecutorType) {
 | 
												
													
														
															|  | 
 |  | +		this.defaultExecutorType = defaultExecutorType;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isCacheEnabled() {
 | 
												
													
														
															|  | 
 |  | +		return cacheEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setCacheEnabled(boolean cacheEnabled) {
 | 
												
													
														
															|  | 
 |  | +		this.cacheEnabled = cacheEnabled;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Integer getDefaultStatementTimeout() {
 | 
												
													
														
															|  | 
 |  | +		return defaultStatementTimeout;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setDefaultStatementTimeout(Integer defaultStatementTimeout) {
 | 
												
													
														
															|  | 
 |  | +		this.defaultStatementTimeout = defaultStatementTimeout;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean isUseColumnLabel() {
 | 
												
													
														
															|  | 
 |  | +		return useColumnLabel;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setUseColumnLabel(boolean useColumnLabel) {
 | 
												
													
														
															|  | 
 |  | +		this.useColumnLabel = useColumnLabel;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public LocalCacheScope getLocalCacheScope() {
 | 
												
													
														
															|  | 
 |  | +		return localCacheScope;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setLocalCacheScope(LocalCacheScope localCacheScope) {
 | 
												
													
														
															|  | 
 |  | +		this.localCacheScope = localCacheScope;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public JdbcType getJdbcTypeForNull() {
 | 
												
													
														
															|  | 
 |  | +		return jdbcTypeForNull;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setJdbcTypeForNull(JdbcType jdbcTypeForNull) {
 | 
												
													
														
															|  | 
 |  | +		this.jdbcTypeForNull = jdbcTypeForNull;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Properties getVariables() {
 | 
												
													
														
															|  | 
 |  | +		return variables;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setVariables(Properties variables) {
 | 
												
													
														
															|  | 
 |  | +		this.variables = variables;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public TypeHandlerRegistry getTypeHandlerRegistry() {
 | 
												
													
														
															|  | 
 |  | +		return typeHandlerRegistry;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public TypeAliasRegistry getTypeAliasRegistry() {
 | 
												
													
														
															|  | 
 |  | +		return typeAliasRegistry;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	/**
 | 
												
													
														
															|  | 
 |  | +	 * @since 3.2.2
 | 
												
													
														
															|  | 
 |  | +	 */
 | 
												
													
														
															|  | 
 |  | +	public MapperRegistry getMapperRegistry() {
 | 
												
													
														
															|  | 
 |  | +		return mapperRegistry;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public ObjectFactory getObjectFactory() {
 | 
												
													
														
															|  | 
 |  | +		return objectFactory;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setObjectFactory(ObjectFactory objectFactory) {
 | 
												
													
														
															|  | 
 |  | +		this.objectFactory = objectFactory;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public ObjectWrapperFactory getObjectWrapperFactory() {
 | 
												
													
														
															|  | 
 |  | +		return objectWrapperFactory;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setObjectWrapperFactory(
 | 
												
													
														
															|  | 
 |  | +			ObjectWrapperFactory objectWrapperFactory) {
 | 
												
													
														
															|  | 
 |  | +		this.objectWrapperFactory = objectWrapperFactory;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	/**
 | 
												
													
														
															|  | 
 |  | +	 * @since 3.2.2
 | 
												
													
														
															|  | 
 |  | +	 */
 | 
												
													
														
															|  | 
 |  | +	public List<Interceptor> getInterceptors() {
 | 
												
													
														
															|  | 
 |  | +		return interceptorChain.getInterceptors();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public LanguageDriverRegistry getLanguageRegistry() {
 | 
												
													
														
															|  | 
 |  | +		return languageRegistry;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void setDefaultScriptingLanguage(Class<?> driver) {
 | 
												
													
														
															|  | 
 |  | +		if (driver == null) {
 | 
												
													
														
															|  | 
 |  | +			driver = XMLLanguageDriver.class;
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +		getLanguageRegistry().setDefaultDriverClass(driver);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public LanguageDriver getDefaultScriptingLanuageInstance() {
 | 
												
													
														
															|  | 
 |  | +		return languageRegistry.getDefaultDriver();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public MetaObject newMetaObject(Object object) {
 | 
												
													
														
															|  | 
 |  | +		return MetaObject
 | 
												
													
														
															|  | 
 |  | +				.forObject(object, objectFactory, objectWrapperFactory);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public ParameterHandler newParameterHandler(
 | 
												
													
														
															|  | 
 |  | +			MappedStatement mappedStatement, Object parameterObject,
 | 
												
													
														
															|  | 
 |  | +			BoundSql boundSql) {
 | 
												
													
														
															|  | 
 |  | +		ParameterHandler parameterHandler = mappedStatement.getLang()
 | 
												
													
														
															|  | 
 |  | +				.createParameterHandler(mappedStatement, parameterObject,
 | 
												
													
														
															|  | 
 |  | +						boundSql);
 | 
												
													
														
															|  | 
 |  | +		parameterHandler = (ParameterHandler) interceptorChain
 | 
												
													
														
															|  | 
 |  | +				.pluginAll(parameterHandler);
 | 
												
													
														
															|  | 
 |  | +		return parameterHandler;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public ResultSetHandler newResultSetHandler(Executor executor,
 | 
												
													
														
															|  | 
 |  | +			MappedStatement mappedStatement, RowBounds rowBounds,
 | 
												
													
														
															|  | 
 |  | +			ParameterHandler parameterHandler, ResultHandler resultHandler,
 | 
												
													
														
															|  | 
 |  | +			BoundSql boundSql) {
 | 
												
													
														
															|  | 
 |  | +		ResultSetHandler resultSetHandler = new DefaultResultSetHandler(
 | 
												
													
														
															|  | 
 |  | +				executor, mappedStatement, parameterHandler, resultHandler,
 | 
												
													
														
															|  | 
 |  | +				boundSql, rowBounds);
 | 
												
													
														
															|  | 
 |  | +		resultSetHandler = (ResultSetHandler) interceptorChain
 | 
												
													
														
															|  | 
 |  | +				.pluginAll(resultSetHandler);
 | 
												
													
														
															|  | 
 |  | +		return resultSetHandler;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public StatementHandler newStatementHandler(Executor executor,
 | 
												
													
														
															|  | 
 |  | +			MappedStatement mappedStatement, Object parameterObject,
 | 
												
													
														
															|  | 
 |  | +			RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
 | 
												
													
														
															|  | 
 |  | +		StatementHandler statementHandler = new RoutingStatementHandler(
 | 
												
													
														
															|  | 
 |  | +				executor, mappedStatement, parameterObject, rowBounds,
 | 
												
													
														
															|  | 
 |  | +				resultHandler, boundSql);
 | 
												
													
														
															|  | 
 |  | +		statementHandler = (StatementHandler) interceptorChain
 | 
												
													
														
															|  | 
 |  | +				.pluginAll(statementHandler);
 | 
												
													
														
															|  | 
 |  | +		return statementHandler;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Executor newExecutor(Transaction transaction) {
 | 
												
													
														
															|  | 
 |  | +		return newExecutor(transaction, defaultExecutorType);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Executor newExecutor(Transaction transaction,
 | 
												
													
														
															|  | 
 |  | +			ExecutorType executorType) {
 | 
												
													
														
															|  | 
 |  | +		executorType = executorType == null ? defaultExecutorType
 | 
												
													
														
															|  | 
 |  | +				: executorType;
 | 
												
													
														
															|  | 
 |  | +		executorType = executorType == null ? ExecutorType.SIMPLE
 | 
												
													
														
															|  | 
 |  | +				: executorType;
 | 
												
													
														
															|  | 
 |  | +		Executor executor;
 | 
												
													
														
															|  | 
 |  | +		if (ExecutorType.BATCH == executorType) {
 | 
												
													
														
															|  | 
 |  | +			executor = new BatchExecutor(this, transaction);
 | 
												
													
														
															|  | 
 |  | +		} else if (ExecutorType.REUSE == executorType) {
 | 
												
													
														
															|  | 
 |  | +			executor = new ReuseExecutor(this, transaction);
 | 
												
													
														
															|  | 
 |  | +		} else {
 | 
												
													
														
															|  | 
 |  | +			executor = new SimpleExecutor(this, transaction);
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +		if (cacheEnabled) {
 | 
												
													
														
															|  | 
 |  | +			executor = new CachingExecutor(executor);
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +		executor = (Executor) interceptorChain.pluginAll(executor);
 | 
												
													
														
															|  | 
 |  | +		return executor;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addKeyGenerator(String id, KeyGenerator keyGenerator) {
 | 
												
													
														
															|  | 
 |  | +		keyGenerators.put(id, keyGenerator);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<String> getKeyGeneratorNames() {
 | 
												
													
														
															|  | 
 |  | +		return keyGenerators.keySet();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<KeyGenerator> getKeyGenerators() {
 | 
												
													
														
															|  | 
 |  | +		return keyGenerators.values();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public KeyGenerator getKeyGenerator(String id) {
 | 
												
													
														
															|  | 
 |  | +		return keyGenerators.get(id);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean hasKeyGenerator(String id) {
 | 
												
													
														
															|  | 
 |  | +		return keyGenerators.containsKey(id);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addCache(Cache cache) {
 | 
												
													
														
															|  | 
 |  | +		caches.put(cache.getId(), cache);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<String> getCacheNames() {
 | 
												
													
														
															|  | 
 |  | +		return caches.keySet();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<Cache> getCaches() {
 | 
												
													
														
															|  | 
 |  | +		return caches.values();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Cache getCache(String id) {
 | 
												
													
														
															|  | 
 |  | +		return caches.get(id);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean hasCache(String id) {
 | 
												
													
														
															|  | 
 |  | +		return caches.containsKey(id);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addResultMap(ResultMap rm) {
 | 
												
													
														
															|  | 
 |  | +		resultMaps.put(rm.getId(), rm);
 | 
												
													
														
															|  | 
 |  | +		checkLocallyForDiscriminatedNestedResultMaps(rm);
 | 
												
													
														
															|  | 
 |  | +		checkGloballyForDiscriminatedNestedResultMaps(rm);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<String> getResultMapNames() {
 | 
												
													
														
															|  | 
 |  | +		return resultMaps.keySet();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<ResultMap> getResultMaps() {
 | 
												
													
														
															|  | 
 |  | +		return resultMaps.values();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public ResultMap getResultMap(String id) {
 | 
												
													
														
															|  | 
 |  | +		return resultMaps.get(id);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean hasResultMap(String id) {
 | 
												
													
														
															|  | 
 |  | +		return resultMaps.containsKey(id);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addParameterMap(ParameterMap pm) {
 | 
												
													
														
															|  | 
 |  | +		parameterMaps.put(pm.getId(), pm);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<String> getParameterMapNames() {
 | 
												
													
														
															|  | 
 |  | +		return parameterMaps.keySet();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<ParameterMap> getParameterMaps() {
 | 
												
													
														
															|  | 
 |  | +		return parameterMaps.values();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public ParameterMap getParameterMap(String id) {
 | 
												
													
														
															|  | 
 |  | +		return parameterMaps.get(id);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean hasParameterMap(String id) {
 | 
												
													
														
															|  | 
 |  | +		return parameterMaps.containsKey(id);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addMappedStatement(MappedStatement ms) {
 | 
												
													
														
															|  | 
 |  | +		mappedStatements.put(ms.getId(), ms);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<String> getMappedStatementNames() {
 | 
												
													
														
															|  | 
 |  | +		buildAllStatements();
 | 
												
													
														
															|  | 
 |  | +		return mappedStatements.keySet();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<MappedStatement> getMappedStatements() {
 | 
												
													
														
															|  | 
 |  | +		buildAllStatements();
 | 
												
													
														
															|  | 
 |  | +		return mappedStatements.values();
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<XMLStatementBuilder> getIncompleteStatements() {
 | 
												
													
														
															|  | 
 |  | +		return incompleteStatements;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addIncompleteStatement(XMLStatementBuilder incompleteStatement) {
 | 
												
													
														
															|  | 
 |  | +		incompleteStatements.add(incompleteStatement);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<CacheRefResolver> getIncompleteCacheRefs() {
 | 
												
													
														
															|  | 
 |  | +		return incompleteCacheRefs;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addIncompleteCacheRef(CacheRefResolver incompleteCacheRef) {
 | 
												
													
														
															|  | 
 |  | +		incompleteCacheRefs.add(incompleteCacheRef);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<ResultMapResolver> getIncompleteResultMaps() {
 | 
												
													
														
															|  | 
 |  | +		return incompleteResultMaps;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addIncompleteResultMap(ResultMapResolver resultMapResolver) {
 | 
												
													
														
															|  | 
 |  | +		incompleteResultMaps.add(resultMapResolver);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addIncompleteMethod(MethodResolver builder) {
 | 
												
													
														
															|  | 
 |  | +		incompleteMethods.add(builder);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Collection<MethodResolver> getIncompleteMethods() {
 | 
												
													
														
															|  | 
 |  | +		return incompleteMethods;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public MappedStatement getMappedStatement(String id) {
 | 
												
													
														
															|  | 
 |  | +		return this.getMappedStatement(id, true);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public MappedStatement getMappedStatement(String id,
 | 
												
													
														
															|  | 
 |  | +			boolean validateIncompleteStatements) {
 | 
												
													
														
															|  | 
 |  | +		if (validateIncompleteStatements) {
 | 
												
													
														
															|  | 
 |  | +			buildAllStatements();
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +		return mappedStatements.get(id);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public Map<String, XNode> getSqlFragments() {
 | 
												
													
														
															|  | 
 |  | +		return sqlFragments;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addInterceptor(Interceptor interceptor) {
 | 
												
													
														
															|  | 
 |  | +		interceptorChain.addInterceptor(interceptor);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addMappers(String packageName, Class<?> superType) {
 | 
												
													
														
															|  | 
 |  | +		mapperRegistry.addMappers(packageName, superType);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addMappers(String packageName) {
 | 
												
													
														
															|  | 
 |  | +		mapperRegistry.addMappers(packageName);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public <T> void addMapper(Class<T> type) {
 | 
												
													
														
															|  | 
 |  | +		mapperRegistry.addMapper(type);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
 | 
												
													
														
															|  | 
 |  | +		return mapperRegistry.getMapper(type, sqlSession);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean hasMapper(Class<?> type) {
 | 
												
													
														
															|  | 
 |  | +		return mapperRegistry.hasMapper(type);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean hasStatement(String statementName) {
 | 
												
													
														
															|  | 
 |  | +		return hasStatement(statementName, true);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public boolean hasStatement(String statementName,
 | 
												
													
														
															|  | 
 |  | +			boolean validateIncompleteStatements) {
 | 
												
													
														
															|  | 
 |  | +		if (validateIncompleteStatements) {
 | 
												
													
														
															|  | 
 |  | +			buildAllStatements();
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +		return mappedStatements.containsKey(statementName);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	public void addCacheRef(String namespace, String referencedNamespace) {
 | 
												
													
														
															|  | 
 |  | +		cacheRefMap.put(namespace, referencedNamespace);
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	/*
 | 
												
													
														
															|  | 
 |  | +	 * Parses all the unprocessed statement nodes in the cache. It is
 | 
												
													
														
															|  | 
 |  | +	 * recommended to call this method once all the mappers are added as it
 | 
												
													
														
															|  | 
 |  | +	 * provides fail-fast statement validation.
 | 
												
													
														
															|  | 
 |  | +	 */
 | 
												
													
														
															|  | 
 |  | +	protected void buildAllStatements() {
 | 
												
													
														
															|  | 
 |  | +		if (!incompleteResultMaps.isEmpty()) {
 | 
												
													
														
															|  | 
 |  | +			synchronized (incompleteResultMaps) {
 | 
												
													
														
															|  | 
 |  | +				// This always throws a BuilderException.
 | 
												
													
														
															|  | 
 |  | +				incompleteResultMaps.iterator().next().resolve();
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +		if (!incompleteCacheRefs.isEmpty()) {
 | 
												
													
														
															|  | 
 |  | +			synchronized (incompleteCacheRefs) {
 | 
												
													
														
															|  | 
 |  | +				// This always throws a BuilderException.
 | 
												
													
														
															|  | 
 |  | +				incompleteCacheRefs.iterator().next().resolveCacheRef();
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +		if (!incompleteStatements.isEmpty()) {
 | 
												
													
														
															|  | 
 |  | +			synchronized (incompleteStatements) {
 | 
												
													
														
															|  | 
 |  | +				// This always throws a BuilderException.
 | 
												
													
														
															|  | 
 |  | +				incompleteStatements.iterator().next().parseStatementNode();
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +		if (!incompleteMethods.isEmpty()) {
 | 
												
													
														
															|  | 
 |  | +			synchronized (incompleteMethods) {
 | 
												
													
														
															|  | 
 |  | +				// This always throws a BuilderException.
 | 
												
													
														
															|  | 
 |  | +				incompleteMethods.iterator().next().resolve();
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	/*
 | 
												
													
														
															|  | 
 |  | +	 * Extracts namespace from fully qualified statement id.
 | 
												
													
														
															|  | 
 |  | +	 * 
 | 
												
													
														
															|  | 
 |  | +	 * @param statementId
 | 
												
													
														
															|  | 
 |  | +	 * 
 | 
												
													
														
															|  | 
 |  | +	 * @return namespace or null when id does not contain period.
 | 
												
													
														
															|  | 
 |  | +	 */
 | 
												
													
														
															|  | 
 |  | +	protected String extractNamespace(String statementId) {
 | 
												
													
														
															|  | 
 |  | +		int lastPeriod = statementId.lastIndexOf('.');
 | 
												
													
														
															|  | 
 |  | +		return lastPeriod > 0 ? statementId.substring(0, lastPeriod) : null;
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	// Slow but a one time cost. A better solution is welcome.
 | 
												
													
														
															|  | 
 |  | +	protected void checkGloballyForDiscriminatedNestedResultMaps(ResultMap rm) {
 | 
												
													
														
															|  | 
 |  | +		if (rm.hasNestedResultMaps()) {
 | 
												
													
														
															|  | 
 |  | +			for (Map.Entry<String, ResultMap> entry : resultMaps.entrySet()) {
 | 
												
													
														
															|  | 
 |  | +				Object value = entry.getValue();
 | 
												
													
														
															|  | 
 |  | +				if (value instanceof ResultMap) {
 | 
												
													
														
															|  | 
 |  | +					ResultMap entryResultMap = (ResultMap) value;
 | 
												
													
														
															|  | 
 |  | +					if (!entryResultMap.hasNestedResultMaps()
 | 
												
													
														
															|  | 
 |  | +							&& entryResultMap.getDiscriminator() != null) {
 | 
												
													
														
															|  | 
 |  | +						Collection<String> discriminatedResultMapNames = entryResultMap
 | 
												
													
														
															|  | 
 |  | +								.getDiscriminator().getDiscriminatorMap()
 | 
												
													
														
															|  | 
 |  | +								.values();
 | 
												
													
														
															|  | 
 |  | +						if (discriminatedResultMapNames.contains(rm.getId())) {
 | 
												
													
														
															|  | 
 |  | +							entryResultMap.forceNestedResultMaps();
 | 
												
													
														
															|  | 
 |  | +						}
 | 
												
													
														
															|  | 
 |  | +					}
 | 
												
													
														
															|  | 
 |  | +				}
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	// Slow but a one time cost. A better solution is welcome.
 | 
												
													
														
															|  | 
 |  | +	protected void checkLocallyForDiscriminatedNestedResultMaps(ResultMap rm) {
 | 
												
													
														
															|  | 
 |  | +		if (!rm.hasNestedResultMaps() && rm.getDiscriminator() != null) {
 | 
												
													
														
															|  | 
 |  | +			for (Map.Entry<String, String> entry : rm.getDiscriminator()
 | 
												
													
														
															|  | 
 |  | +					.getDiscriminatorMap().entrySet()) {
 | 
												
													
														
															|  | 
 |  | +				String discriminatedResultMapName = entry.getValue();
 | 
												
													
														
															|  | 
 |  | +				if (hasResultMap(discriminatedResultMapName)) {
 | 
												
													
														
															|  | 
 |  | +					ResultMap discriminatedResultMap = resultMaps
 | 
												
													
														
															|  | 
 |  | +							.get(discriminatedResultMapName);
 | 
												
													
														
															|  | 
 |  | +					if (discriminatedResultMap.hasNestedResultMaps()) {
 | 
												
													
														
															|  | 
 |  | +						rm.forceNestedResultMaps();
 | 
												
													
														
															|  | 
 |  | +						break;
 | 
												
													
														
															|  | 
 |  | +					}
 | 
												
													
														
															|  | 
 |  | +				}
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +	protected static class StrictMap<V> extends HashMap<String, V> {
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		private static final long serialVersionUID = -4950446264854982944L;
 | 
												
													
														
															|  | 
 |  | +		private String name;
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		public StrictMap(String name, int initialCapacity, float loadFactor) {
 | 
												
													
														
															|  | 
 |  | +			super(initialCapacity, loadFactor);
 | 
												
													
														
															|  | 
 |  | +			this.name = name;
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		public StrictMap(String name, int initialCapacity) {
 | 
												
													
														
															|  | 
 |  | +			super(initialCapacity);
 | 
												
													
														
															|  | 
 |  | +			this.name = name;
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		public StrictMap(String name) {
 | 
												
													
														
															|  | 
 |  | +			super();
 | 
												
													
														
															|  | 
 |  | +			this.name = name;
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		public StrictMap(String name, Map<String, ? extends V> m) {
 | 
												
													
														
															|  | 
 |  | +			super(m);
 | 
												
													
														
															|  | 
 |  | +			this.name = name;
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		// TODO 如果现在状态为刷新,则刷新(先删除后添加)
 | 
												
													
														
															|  | 
 |  | +		@SuppressWarnings("unchecked")
 | 
												
													
														
															|  | 
 |  | +		public V put(String key, V value) {
 | 
												
													
														
															|  | 
 |  | +			if (org.apache.ibatis.thread.Runnable.isRefresh()) {
 | 
												
													
														
															|  | 
 |  | +				remove(key);
 | 
												
													
														
															|  | 
 |  | +				org.apache.ibatis.thread.Runnable.log.debug("refresh key:"
 | 
												
													
														
															|  | 
 |  | +						+ key.substring(key.lastIndexOf(".") + 1));
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +			if (containsKey(key))
 | 
												
													
														
															|  | 
 |  | +				throw new IllegalArgumentException(name
 | 
												
													
														
															|  | 
 |  | +						+ " already contains value for " + key);
 | 
												
													
														
															|  | 
 |  | +			if (key.contains(".")) {
 | 
												
													
														
															|  | 
 |  | +				final String shortKey = getShortName(key);
 | 
												
													
														
															|  | 
 |  | +				if (super.get(shortKey) == null) {
 | 
												
													
														
															|  | 
 |  | +					super.put(shortKey, value);
 | 
												
													
														
															|  | 
 |  | +				} else {
 | 
												
													
														
															|  | 
 |  | +					super.put(shortKey, (V) new Ambiguity(shortKey));
 | 
												
													
														
															|  | 
 |  | +				}
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +			return super.put(key, value);
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		public V get(Object key) {
 | 
												
													
														
															|  | 
 |  | +			V value = super.get(key);
 | 
												
													
														
															|  | 
 |  | +			if (value == null) {
 | 
												
													
														
															|  | 
 |  | +				throw new IllegalArgumentException(name
 | 
												
													
														
															|  | 
 |  | +						+ " does not contain value for " + key);
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +			if (value instanceof Ambiguity) {
 | 
												
													
														
															|  | 
 |  | +				throw new IllegalArgumentException(
 | 
												
													
														
															|  | 
 |  | +						((Ambiguity) value).getSubject()
 | 
												
													
														
															|  | 
 |  | +								+ " is ambiguous in "
 | 
												
													
														
															|  | 
 |  | +								+ name
 | 
												
													
														
															|  | 
 |  | +								+ " (try using the full name including the namespace, or rename one of the entries)");
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +			return value;
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		private String getShortName(String key) {
 | 
												
													
														
															|  | 
 |  | +			final String[] keyparts = key.split("\\.");
 | 
												
													
														
															|  | 
 |  | +			final String shortKey = keyparts[keyparts.length - 1];
 | 
												
													
														
															|  | 
 |  | +			return shortKey;
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +		protected static class Ambiguity {
 | 
												
													
														
															|  | 
 |  | +			private String subject;
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +			public Ambiguity(String subject) {
 | 
												
													
														
															|  | 
 |  | +				this.subject = subject;
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +			public String getSubject() {
 | 
												
													
														
															|  | 
 |  | +				return subject;
 | 
												
													
														
															|  | 
 |  | +			}
 | 
												
													
														
															|  | 
 |  | +		}
 | 
												
													
														
															|  | 
 |  | +	}
 | 
												
													
														
															|  | 
 |  | +
 | 
												
													
														
															|  | 
 |  | +}
 |