package com.jqmobile.core.server.service;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import com.jqmobile.core.server.db.DBPool;
import com.jqmobile.core.service.Service;
import com.jqmobile.core.utils.ClassForNameUtil;
/**
* Manager实例化工厂
* @author MODI
*
* @project com.jiuqi.mobile.core
* @date 2013年11月15日
*/
public abstract class ServiceFactory {
private static ServiceFactory mf = new BaseManagerFactory();
/**
* 自定义默认实例化工程。仅限框架底层使用
* @param factory void
*/
public static void setServiceFactory(ServiceFactory factory){
mf = factory;
}
/**
* 实例化Manager
* @param c
* @return
*/
public static <T> T instance(Class<T> c){
return mf.instanceService(c);
}
/**
* 实例化Manager
* @param c
* @return
*/
@SuppressWarnings("unchecked")
public <T> T instanceService(Class<T> c){
return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{c}, getInvocationHandler(c));
}
/**
* 获得切面代理
* @return
*/
protected abstract InvocationHandler getInvocationHandler(Class<?> c);
/**
* 获得数据库连接
* @return
*/
public abstract Connection newConnection();
//=============================================================
static final class BaseManagerFactory extends ServiceFactory{
@Override
protected InvocationHandler getInvocationHandler(Class<?> c) {
return new BaseInvocationHandler(c);
}
@Override
public Connection newConnection() {
try {
return DBPool.getInstance().getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
//=============================================================
final class BaseInvocationHandler implements InvocationHandler{
private Class<?> c;
BaseInvocationHandler(Class<?> c){
this.c=c;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
long uuid = Thread.currentThread().getId();
BaseManagerUtil util = new BaseManagerUtil();
try{
ServiceUtil.utils.put(uuid, util);
try{
Service annotation = c.getAnnotation(Service.class);
if(null == annotation){
throw new ServiceAnnotationException(c);
}
String impl = annotation.impl();
Class<?> ci = ClassForNameUtil.forName(impl);
// Class<?> ci = Class.forName(impl, false, Thread.currentThread().getContextClassLoader());
Object obj = ci.newInstance();
//
try{
//pre
if(null != util.getPreAction()){
util.getPreAction().action();
}
Object result = method.invoke(obj, args);
//succeed
if(null != util.getSucceedAction()){
util.getSucceedAction().action();
}
util.commit();
return result;
}catch(Throwable e){
util.rollback();
//exception
if(null != util.getExceptionAction()){
util.getExceptionAction().action(e);
}
throw e;
}
//
}finally{
ServiceUtil.utils.remove(uuid);
}
}finally{
util.close();
//finish
if(null != util.getFinishAction()){
util.getFinishAction().action();
}
}
}
}
final class BaseManagerUtil extends ServiceUtil{
private Connection connection;
public Connection getConnection() {
if(null == connection) connection = newConnection();
return connection;
}
private void commit() throws Exception{
if(null != connection) connection.commit();
}
private void rollback() throws Exception{
if(null != connection) connection.rollback();
}
private void close() throws Exception{
if(null != connection) connection.close();
}
}
}