4、Eternalフレーム-所有者
所有者JAvaは、すべてのコントローラとブロッキングインスタンスを持ち、複数のブロッキングがブロッキングチェーンを構成しています.
初期化コントローラ:非常に簡単で、DispatcherServiceletの初期化時にContainerを呼び出す.Init(config)、initメソッドではすべてのclassファイルを検索し、Mapping注釈のメソッドがあり、検証後、コントローラです.
初期化ブロッキング:上と同じです.Mapping注記には2つのパラメータurl,cmiがあり、ここでcmiはカスタムブロッカー(cmiはc:controller,m:me,i:interceptor)である.Container.javaコードは以下の通りである.
Mapping.JAvaコード:
初期化コントローラ:非常に簡単で、DispatcherServiceletの初期化時にContainerを呼び出す.Init(config)、initメソッドではすべてのclassファイルを検索し、Mapping注釈のメソッドがあり、検証後、コントローラです.
初期化ブロッキング:上と同じです.Mapping注記には2つのパラメータurl,cmiがあり、ここでcmiはカスタムブロッカー(cmiはc:controller,m:me,i:interceptor)である.Container.javaコードは以下の通りである.
package cn.eternal.container;
import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import cn.eternal.annotation.Mapping;
import cn.eternal.config.Config;
import cn.eternal.config.ConfigException;
import cn.eternal.handler.InstanceHandler;
import cn.eternal.handler.MappingHandler;
import cn.eternal.interceptor.EmptyInterceptor;
import cn.eternal.interceptor.Interceptor;
import cn.eternal.renderer.Renderer;
import cn.eternal.util.ConverterUtil;
public class Container {
private static Log log = LogFactory.getLog(Container.class);
public static Map<MappingHandler,Interceptor[]> interceptors = new HashMap<MappingHandler,Interceptor[]>();
public static MappingHandler[] MappingHandlers = null;
public static Map<MappingHandler, InstanceHandler> mhih = new HashMap<MappingHandler, InstanceHandler>();
private static ConverterUtil converterUtil = new ConverterUtil();
public static void init(final Config config) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
initControllersAndInterceptors(config);
}
static void warnInvalidInstanceHandlerMethod(Method m, String string) {
log.warn("Init Invalid Controller method '" + m.toGenericString() + "': " + string);
}
public static void initControllersAndInterceptors(Config config) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
ClassLoader cld = Thread.currentThread().getContextClassLoader();
URL resource = cld.getResource("/");
File dirs = new File(resource.getFile());
ArrayList<Class> classList = new ArrayList<Class>();
findClass(dirs,"",classList);
findControllersAndInterceptors(classList,config.getInitParameter("interceptors"));
MappingHandlers = mhih.keySet().toArray(new MappingHandler[mhih.size()]);
Arrays.sort(
MappingHandlers,
new Comparator<MappingHandler>() {
public int compare(MappingHandler o1, MappingHandler o2) {
String u1 = o1.url;
String u2 = o2.url;
int n = u1.compareTo(u2);
if (n==0)
throw new ConfigException("Cannot mapping one url '" + u1 + "' to more than one Controller method.");
return n;
}
}
);
}
private static void findClass(File dirs,String basePack,ArrayList<Class> classList)
throws ClassNotFoundException {
File[] childs = dirs.listFiles();
for (int i = 0; i < childs.length; i++) {
String packPath =basePack+childs[i].getName()+".";
if (childs[i].isDirectory()) {
findClass(childs[i],packPath,classList);
} else {
String className = childs[i].getName();
if (className.endsWith(".class")) {
packPath=packPath.replace(".class.", "");
classList.add(Class.forName(packPath));
}
}
}
}
private static void findControllersAndInterceptors(ArrayList<Class> classLst,String inters)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
for (int c = 0; c < classLst.size(); c++) {
Class clazz = classLst.get(c);
Method mArr[] = clazz.getDeclaredMethods();
for (Method m:mArr) {
if (isControllerMethod(m)) {
Mapping mapping = m.getAnnotation(Mapping.class);
String url = mapping.url();
MappingHandler matcher = new MappingHandler(url);
if (matcher.getArgumentCount()!=m.getParameterTypes().length) {
warnInvalidInstanceHandlerMethod(m, "Arguments in URL '" + url + "' does not match the arguments of method.");
continue;
}
log.info("Init Controller "+m.toGenericString()+" Mapping url '" + url + "'.");
mhih.put(matcher, new InstanceHandler(clazz.newInstance(), m));
Class cmi = mapping.cmi();
String cinters = "";
if(cmi != null && cmi != EmptyInterceptor.class){
if(inters != "" && inters != null){
cinters = ","+cmi.getName();
log.info("Init Interceptor "+cmi.getName()+" For "+m.toGenericString()+".");
}
}
addInterceptors(matcher,(inters+cinters).split(","));
}
}
}
}
static void addInterceptors(MappingHandler matcher,String[] inters) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Interceptor[] interArr = new Interceptor[inters.length];
for(int i=0;i<inters.length;i++){
interArr[i] = (Interceptor)(Class.forName(inters[i])).newInstance();
}
interceptors.put(matcher,interArr);
}
static boolean isControllerMethod(Method m) {
Mapping mapping = m.getAnnotation(Mapping.class);
if (mapping==null)
return false;
if (mapping.url().length()==0) {
warnInvalidInstanceHandlerMethod(m, "Url mapping cannot be empty.");
return false;
}
if (Modifier.isStatic(m.getModifiers())) {
warnInvalidInstanceHandlerMethod(m, "method is static.");
return false;
}
Class<?>[] argTypes = m.getParameterTypes();
for (Class<?> argType : argTypes) {
if (!converterUtil.canConvert(argType)) {
warnInvalidInstanceHandlerMethod(m, "unsupported parameter '" + argType.getName() + "'.");
return false;
}
}
Class<?> retType = m.getReturnType();
if (retType.equals(void.class)
|| retType.equals(String.class)
|| Renderer.class.isAssignableFrom(retType)
)
return true;
warnInvalidInstanceHandlerMethod(m, "unsupported return type '" + retType.getName() + "'.");
return false;
}
public static void destroy() {
interceptors = null;
MappingHandlers = null;
mhih = null;
converterUtil = null;
}
public static MappingHandler[] getMappingHandlers() {
return MappingHandlers;
}
public static Map<MappingHandler, InstanceHandler> getMhih() {
return mhih;
}
public static Interceptor[] getInterceptors(MappingHandler matcher) {
return interceptors.get(matcher);
}
}
Mapping.JAvaコード:
package cn.eternal.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cn.eternal.interceptor.EmptyInterceptor;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Mapping {
String url();
Class<?> cmi() default EmptyInterceptor.class;
}