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

gu.sql2java.Managers Maven / Gradle / Ivy

There is a newer version: 5.3.3
Show newest version
package gu.sql2java;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static gu.sql2java.SimpleLog.log;
import static gu.sql2java.SimpleLog.logString;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import gu.sql2java.Constant.JdbcProperty;
import gu.sql2java.Constant.UpdateStrategy;

/**
 * 数据库操作实例({@link TableManager})管理类
 * @author guyadong
 *
 */
public class Managers {
	/**
	 * 设置是否输出调试信息标志
	 */
	private static boolean debug = false;
	private Managers() {
	}

	private static final ImmutableMap> 
	tableManagerInstances = loadTableManager();
	private static final  ImmutableMap, TableManager> 
	tableManagerTypeMaps = asTypeMap(tableManagerInstances);
	private static final  ImmutableMap, TableManager> 
	tableManagerBeanTypeMaps = asBeanTypeMap(tableManagerInstances);
	private static final  Map, TableManager> cacheManagers = Maps.newHashMap();
	private static final  Map, TableManager> cacheBeanTypeManagers = Maps.newHashMap();
	private static final  Map> cacheNameManagers = Maps.newHashMap();

	/**
	 * @return 返回所有数据库操作实例(非cache)
	 */
	public static ImmutableMap> getTableManagers() {
		return tableManagerInstances;
	}

	/**
	 * SPI(Service Provider Interface)机制加载 {@link TableManager}所有实例
	 * @return 表名和 {@link TableManager}实例的映射对象 
	 */
	private static ImmutableMap> loadTableManager() {		
		ImmutableMap.Builder> builder = ImmutableMap.builder();
		for(RowMetaData data:RowMetaData.tableMetadata.values()){
			TableManager manager = TableManagerDecorator.makeInterfaceInstance(new BaseTableManager<>(data.tablename));
			builder.put(data.tablename,	manager);
			if(debug){
				log("TableManagerDecorator instance create for {} ",data.tablename);
			}
		}
		return builder.build();
	}

	private static final ImmutableMap, TableManager> asTypeMap(Map>input){
		return Maps.uniqueIndex(input.values(), new Function,Class>(){
			@Override
			public Class apply(TableManager input) {
				for(Class clazz:input.getClass().getInterfaces()){
					for(Class c:clazz.getInterfaces()){
						if(c.equals(TableManager.class)){
							return clazz;
						}
					}
				}
				throw new IllegalStateException(logString("NOT FOUND immplements interface class for %s ", input.getClass()));
			}});
	}

	private static final ImmutableMap, TableManager> asBeanTypeMap(Map>input){
		return Maps.uniqueIndex(input.values(), new Function,Class>(){
	
			@Override
			public Class apply(TableManager input) {
				if(input instanceof BaseTableManager){
					return ((BaseTableManager)input).metaData.beanType;
				}else if(Proxy.isProxyClass(input.getClass())){
					InvocationHandler handler = Proxy.getInvocationHandler(input);
					checkArgument(handler instanceof TableManagerDecorator,"UNKNOW HANDLER %s",handler.getClass() );
					return ((TableManagerDecorator)handler).metaData.beanType;
				}
				throw new IllegalArgumentException(logString("UNKNOW SUPPORTED TableManager instance %s",input.getClass()));
			}});
	}

	/** 
	 * 根据表操作接口类型返回数据库操作实例(非cache)
	 * @param interfaceClass  接口类型
	 * @return {@link TableManager}实例,找不到则抛出异常
	 */
	@SuppressWarnings("unchecked")
	public static final >M 
	getTableManager(ClassinterfaceClass) {
		TableManager manager = tableManagerTypeMaps.get(interfaceClass);
		return checkNotNull((M) manager,"INVALID manager type %s",interfaceClass);
	}

	/**
	 * 根据表记录类型返回数据库操作实例(非cache)
	 * @param beanType java bean type
	 * @return {@link TableManager}实例,找不到则抛出异常
	 */
	@SuppressWarnings("unchecked")
	public static final >M 
	getTableManagerByBeanType(ClassbeanType) {
		TableManager manager = tableManagerBeanTypeMaps.get(beanType);
		return checkNotNull((M) manager,"INVALID bean type %s",beanType);
	}

	/**
	 * 根据表名返回数据库操作实例(非cache)
	 * @param tablename table name
	 * @return {@link TableManager}实例,找不到则抛出异常
	 */
	@SuppressWarnings("unchecked")
	public static final >M 
	getTableManager(String tablename) {
		TableManager manager = tableManagerInstances.get(tablename);
		return checkNotNull((M) manager,"INVALID tablename %s",tablename);
	}

	/**
	 * 根据表名返回数据库操作实例(非cache)
	 * @param tablename table name
	 * @return {@link BaseTableManager}实例,找不到则抛出异常
	 */
	@SuppressWarnings("unchecked")
	public static final >M 
	getBaseTableManager(String tablename) {
		return (M) baseManagerOf((TableManager)getTableManager(tablename));
	}

    /**
     * 注册cache manager
* @param tablename table name * @param updateStrategy cache update strategy,{@link Constant#DEFAULT_STRATEGY} be used if {@code null} * @param maximumSize maximum capacity of cache ,{@link Constant#DEFAULT_CACHE_MAXIMUMSIZE } be used if {@code null} or <=0,see also {@link CacheBuilder#maximumSize(long)} * @param duration cache data expired time,{@link Constant#DEFAULT_DURATION} be used if {@code null} or <=0,see also {@link CacheBuilder#expireAfterWrite(long, TimeUnit)} * @param unit time unit for {@code duration},{@link Constant#DEFAULT_TIME_UNIT} be used if {@code null},see also {@link CacheBuilder#expireAfterWrite(long, TimeUnit)} */ public static synchronized final > void registerCacheManager( String tablename, UpdateStrategy updateStrategy, long maximumSize, long duration, TimeUnit unit){ TableManager cacheManager = CacheManager.makeCacheInstance(tablename, updateStrategy, maximumSize, duration, unit); BaseTableManager manager = baseManagerOf(cacheManager); cacheManagers.put(manager.metaData.managerInterfaceClass, cacheManager); cacheNameManagers.put(manager.metaData.tablename, cacheManager); cacheBeanTypeManagers.put(manager.metaData.beanType, cacheManager); if(debug){ log("REGISTER CACHE MANAGER {}",cacheManager); } } /** * @return 返回所有支持缓存的数据库操作实例 * @see CacheManager */ public static Map, TableManager> getCacheManagers() { return Collections.unmodifiableMap(cacheManagers); } /** * 根据目标类型返回对应的支持缓存的 {@link TableManager}实例 * @param interfaceClass 目标接口类型 * @return {@link TableManager}实例 * @throws NoSuchElementException 找不到时抛出异常 */ @SuppressWarnings("unchecked") public static final >M getCacheManager(final ClassinterfaceClass) throws NoSuchElementException { checkArgument(interfaceClass != null,"targetType is null"); TableManager manager; if(null != (manager = cacheManagers.get(interfaceClass))){ return (M) manager; } return (M) Iterables.find(cacheManagers.values(), new Predicate>() { @Override public boolean apply(TableManager input) { return interfaceClass.isInstance(input); } }); } /** * 根据表记录类型返回支持缓存的数据库操作实例 * @param beanType java bean type * @return {@link TableManager}实例,找不到时抛出异常 */ @SuppressWarnings("unchecked") public static final TableManager getCacheManagerByBeanType(Class beanType) { TableManager manager = cacheBeanTypeManagers.get(beanType); return ( TableManager) checkNotNull(manager,"INVALID bean type %s",beanType); } /** * 根据表名返回支持缓存的数据库操作实例 * @param tablename * @return {@link TableManager}实例,找不到时抛出异常 */ @SuppressWarnings("unchecked") public static final TableManager getCacheManager(String tablename) { TableManager manager = cacheNameManagers.get(tablename); return (TableManager) checkNotNull(manager,"INVALID table name %s",tablename); } /** * 根据表记录类型返回数据库操作实例
* 优先返回支持缓存的数据库操作实例(cache) * @param interfaceClass 接口类 * @return {@link TableManager}实例,找不到时抛出异常 */ public static >M instanceOf(ClassinterfaceClass) { try { return getCacheManager(interfaceClass); } catch (Exception e) { return getTableManager(interfaceClass); } } /** * 根据表名返回数据库操作实例
* 优先返回支持缓存的数据库操作实例(cache) * @param tablename table name * @return {@link TableManager}实例,找不到时抛出异常 */ public static TableManager managerOf(String tablename) { try { return getCacheManager(tablename); } catch (Exception e) { return getTableManager(tablename); } } /** * 将数据库操作实例转换对应的{@link BaseTableManager}实例
* @param manager * @return {@link BaseTableManager}实例,转换失败时抛出异常 */ @SuppressWarnings({ "unchecked", "rawtypes" }) static BaseTableManager baseManagerOf(TableManager manager){ checkArgument(manager != null,"manager is null"); if(manager instanceof BaseTableManager){ return (BaseTableManager) manager; }else if(Proxy.isProxyClass(manager.getClass())){ InvocationHandler handler = Proxy.getInvocationHandler(manager); checkArgument(handler instanceof TableManagerDecorator,"UNKNOW HANDLER TYPE %s",manager.getClass()); return ((TableManagerDecorator)handler).delegate; }else { throw new IllegalArgumentException(logString("UNKNOW TableManager instance type %s",manager.getClass())); } } /** * 从数据库操作接口类获取对应的{@link BaseTableManager}实例
* @param interfaceClass * @return {@link BaseTableManager}实例,转换失败时抛出异常 */ static >BaseTableManager baseManagerOf(Class interfaceClass){ return baseManagerOf(instanceOf(interfaceClass)); } /** * 根据表名返回对应的{@link BaseTableManager}实例 * 优先返回支持缓存的数据库操作实例(cache) * @param tablename table name * @return {@link BaseTableManager}实例,找不到时抛出异常 */ @SuppressWarnings("unchecked") static BaseTableManager baseManagerOf(String tablename) { return baseManagerOf((TableManager)managerOf(tablename)); } /** * 根据数据表名(驼峰命名格式)返回对应的{@link TableManager}实例
* 优先返回支持缓存的数据库操作实例(cache) * @param coreClass * @return {@link TableManager}实例,找不到时抛出异常 */ public static TableManager managerOfCoreClass(String coreClass) { String tablename = RowMetaData.getRowMetaDataByCoreClassName(coreClass).tablename; try { return getCacheManager(tablename); } catch (Exception e) { return getTableManager(tablename); } } /** * 根据表记录类型返回数据库操作实例(非cache)
* 优先返回支持缓存的数据库操作实例 * @param beanType java bean type * @return {@link TableManager}实例,找不到时抛出异常 */ public static TableManager managerOf(Class beanType) { try { return getCacheManagerByBeanType(beanType); } catch (Exception e) { return getTableManagerByBeanType(beanType); } } public enum Module{ MANAGER,CACHE,DECORATOR,MANAGERS,BASETABLEMANAGER } /** * set debug flag that determine if output log message,default : false * @param debug flag for debug message output * @param modules modules array to be set debug flag,all modules used if be null or empty */ public static void setDebug(boolean debug,Module... modules){ if(modules == null || modules.length == 0){ modules = Module.values(); } for(Module module:modules){ if(null != module){ switch (module) { case MANAGER: Manager.getInstance().setDebug(debug); break; case CACHE: ColumnCache.setDebug(debug); break; case DECORATOR: TableManagerDecorator.setDebug(debug); break; case MANAGERS: Managers.debug = debug; break; case BASETABLEMANAGER: BaseTableManager.setDebug(debug); break; default: break; } } } } /** * inject properties to {@link Manager#databaseProperties}
* be effected only while called before initializing singleton instance * @param properties * @param prefix the prefix of properties,ignore if {@code null} * @see JdbcProperty */ public static final void injectProperties(Map properties,String prefix){ if(null != properties){ EnumMap enumMap = new EnumMap(JdbcProperty.class); JdbcProperty property; for(Entry entry:properties.entrySet()){ if(null != (property = JdbcProperty.fromKey(entry.getKey(),prefix))){ enumMap.put(property, entry.getValue()); } } Manager.injectProperties(enumMap); } } /** * inject properties to {@link Manager#databaseProperties}
* be effected only while called before initializing singleton instance * @param properties * @see JdbcProperty */ public static final void injectProperties(Map properties){ injectProperties(properties,null); } /** * inject properties to {@link Manager#databaseProperties}
* be effected only while called before initializing singleton instance * @param properties * @param prefix the prefix of properties,ignore if {@code null} * @see JdbcProperty */ public static final void injectProperties(Properties properties,String prefix){ HashMap m = null; if(null != properties){ m =new HashMap<>(); for(String name : properties.stringPropertyNames()){ m.put(name, properties.getProperty(name)); } } injectProperties(m,prefix); } /** * @return singleton instance of {@link Manager} as {@link SqlRunner} instance */ public static SqlRunner getSqlRunner(){ return Manager.getInstance(); } }