package com.github.zhongl.hs4j.kit.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import com.github.zhongl.hs4j.kit.annotations.Repository;
/**
* {@link ProxyFactory}
*
* @author <a href=mailto:zhong.lunfu@gmail.com>zhongl</a>
* @created 2011-6-2
*
*/
public abstract class ProxyFactory {
@SuppressWarnings("unchecked")
public <T> T newProxyOf(Class<T> clazz) {
scanAndMapMethodToInvacationHandlerWith(clazz);
Class<?>[] interfaces = { clazz };
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), interfaces, dispatcher);
}
protected abstract InvocationHandler createInvocationHandlerWith(Method method, String database, String table);
private void scanAndMapMethodToInvacationHandlerWith(Class<?> clazz) {
final Repository repository = clazz.getAnnotation(Repository.class);
if (repository == null)
throw new IllegalArgumentException(Repository.class + " should be annotated to class: " + clazz);
final String database = repository.database();
final String table = repository.table();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
InvocationHandler handler = createInvocationHandlerWith(method, database, table);
if ((handler == null)) continue; // no need to map, so skip.
invocationMap.put(method, handler);
}
}
protected final Map<Method, InvocationHandler> invocationMap = new HashMap<Method, InvocationHandler>();
private final Dispatcher dispatcher = new Dispatcher();
private final class Dispatcher implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
InvocationHandler invocationHandler = invocationMap.get(method);
if (invocationHandler == null) throw new UnsupportedOperationException("No implement method: " + method);
return invocationHandler.invoke(proxy, method, args);
}
}
}