package li.mvc;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import li.annotation.Arg;
import li.annotation.At;
import li.ioc.IocContext;
import li.model.Action;
import li.model.Bean;
import li.util.Log;
import li.util.Reflect;
import li.util.Verify;
/**
* Action上下文,保存 了所有的Action
*
* @author li (limingwei@mail.com)
* @version 0.1.3 (2012-05-08)
*/
public class ActionContext {
private static final Log log = Log.init();
private static ActionContext ACTION_CONTEXT = null;// ActionContext的一个实例,用于单例地得到ActionContext的实例
private final Map<String, Action> ACTION_MAP = new ConcurrentHashMap<String, Action>();// 保存所有Action
/**
* 单例的得到一个ActionContext对象,第一次时候会初始化ActionContext
*/
public static/* synchronized */ActionContext getInstance() {
if (ACTION_CONTEXT == null) {
Long start = System.currentTimeMillis();
ACTION_CONTEXT = new ActionContext();
List<Bean> beans = IocContext.getInstance().getBeans();
for (Bean bean : beans) {
Method[] methods = bean.type.getDeclaredMethods();
for (Method method : methods) {
At at = method.getAnnotation(At.class);
if (null != at) {
for (String path : at.value()) {
for (String httpMethod : at.method()) {
Action action = new Action();
action.actionInstance = bean.instance;
action.actionMethod = method;
action.argTypes = method.getParameterTypes();
action.argNames = Reflect.argNames(method);
action.argAnnotations = Reflect.argAnnotations(method, Arg.class);
action.path = Verify.isEmpty(path) ? "/" + method.getName() : Verify.startWith(path, "/") ? path : "/" + path;// Action请求路径,如果不以斜杠开始会被加上斜杠,如果注解value值为空则直接使用方法名
action.httpMethod = httpMethod.toUpperCase(); // HTTP请求类型,这里转换为大写
ACTION_CONTEXT.ACTION_MAP.put(action.path + "#" + action.httpMethod, action);
log.info("ADD ACTION: @At(value=\"?\",method=\"?\") ?", action.path, action.httpMethod, action.actionMethod);
}
}
}
}
}
log.info("? actions started up in ?ms", ACTION_CONTEXT.ACTION_MAP.size(), (System.currentTimeMillis() - start));
}
return ACTION_CONTEXT;
}
/**
* 根据请求路径从ActionContext中得到对应的Action,或者NULL
*/
public Action getAction(String path, String method) {
return ACTION_MAP.get(path + "#" + method);
}
}