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

com.github.yydf.struts.core.StrutsContext Maven / Gradle / Ivy

There is a newer version: 1.0.2
Show newest version
package com.github.yydf.struts.core;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;

import com.github.yydf.struts.annotation.Order;
import com.github.yydf.struts.mapper.ActionMapper;
import com.github.yydf.struts.util.StringUtils;
import com.github.yydf.struts.util.WebContextUtils;

public class StrutsContext {

	private ServletContext mCtx;
	private ArrayList> classes = new ArrayList<>();
	private ArrayList intercepters = new ArrayList<>();
	private ArrayList initializes = new ArrayList<>();
	private HashMap actionMap = new HashMap<>();
	private HashMap patternActionMap = new HashMap<>();

	public void init(ServletContext ctx) {
		this.mCtx = ctx;
		scanClasses(ctx.getResourcePaths("/"));
		ctx.log("Struts context initialized");
	}

	private void scanClasses(Set resourcePaths) {
		if (resourcePaths != null) {
			for (String path : resourcePaths) {
				if (path.endsWith("/"))
					scanClasses(mCtx.getResourcePaths(path));
				else if (path.endsWith(".class")) {
					Class cla = getClass(path);
					if (WebContextUtils.isController(cla))
						bindAction(cla);
					else if (WebContextUtils.isIntercepter(cla))
						addInterceptor(cla);
					else if (WebContextUtils.isProjectInitialize(cla))
						addProjectInitialize(cla);
					classes.add(cla);
				}
			}
		}
	}

	private void addProjectInitialize(Class cla) {
		try {
			initializes.add((ProjectInitialize) cla.newInstance());
		} catch (InstantiationException | IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void addInterceptor(Class cla) {
		try {
			intercepters.add((ActionIntercepter) cla.newInstance());
		} catch (InstantiationException | IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void bindAction(Class cla) {
		String pkg = WebContextUtils.getRequestPath(cla);
		Method[] methods = cla.getMethods();
		String action;
		for (Method method : methods) {
			// 获取request路径
			action = WebContextUtils.getRequestPath(pkg, method);
			if (StringUtils.isNotBlank(action)) {
				if (action.contains("{") && action.contains("}")) {
					ArrayList paras = new ArrayList<>();
					String para;
					String pattern = action;
					while ((para = WebContextUtils.getParameter(pattern)) != null) {
						paras.add(para.replace("{", "").replace("}", ""));
						pattern = pattern.replace(para, "(.*)");
					}
					addAction(pattern, method, paras);
				} else
					addAction(action, method);
			}
		}
	}

	private void addAction(String action, Method method) {
		ActionMapper actionMapper = actionMap.put(action, new ActionMapper(method));
		if (actionMapper != null)
			mCtx.log("Action " + action + " exist, override with " + method.getName());
	}

	private void addAction(String pattern, Method method, ArrayList paras) {
		ActionMapper actionMapper = patternActionMap.put(pattern, new ActionMapper(method, paras));
		if (actionMapper != null)
			mCtx.log("Action pattern " + pattern + " exist, override with " + method.getName());
	}

	private static Class getClass(String path) {
		path = path.replace("/WEB-INF/classes/", "");
		path = path.replace(".class", "");
		path = path.replace('/', '.');
		try {
			return Class.forName(path);
		} catch (ClassNotFoundException e) {
			return null;
		}
	}

	public void startup() {
		// 查找@Resource的实现类
		findResource();
		if (actionMap.size() > 0) {
			mappingAction(mCtx.getFilterRegistration("globalFilter"));
		}
		if (intercepters.size() > 0) {
			sortInterceptor(intercepters.size() > 1);
		}
		if (initializes.size() > 0) {
			startInitializes();
		}
		mCtx.log("Struts context started");
	}

	private void startInitializes() {
		for (ProjectInitialize init : initializes) {
			try {
				init.init(mCtx);
			} catch (RuntimeException e) {
				mCtx.log(init.getClass().getName() + " init faild", e);
			}
		}
	}

	private void sortInterceptor(boolean sort) {
		if (sort) {
			// 按Order注解排序
			Collections.sort(intercepters, new Comparator() {
				@Override
				public int compare(ActionIntercepter arg0, ActionIntercepter arg1) {
					Integer o1 = 0, o2 = 0;
					Order order0 = arg0.getClass().getAnnotation(Order.class);
					if (order0 != null)
						o1 = order0.value();
					Order order1 = arg1.getClass().getAnnotation(Order.class);
					if (order1 != null)
						o2 = order1.value();
					return o1.compareTo(o2);
				}
			});
		}
	}

	private void mappingAction(FilterRegistration filterRegistration) {
		EnumSet dispatcherTypes = EnumSet.allOf(DispatcherType.class);
		dispatcherTypes.add(DispatcherType.REQUEST);
		dispatcherTypes.add(DispatcherType.FORWARD);
		// 如果没有通配符的链接
		if (patternActionMap.isEmpty()) {
			Set actions = actionMap.keySet();
			for (String action : actions) {
				filterRegistration.addMappingForUrlPatterns(dispatcherTypes, true, action);
			}
		} else {
			filterRegistration.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
		}
	}

	private void findResource() {

	}

	public ActionMapper findAction(String servletPath) {
		ActionMapper mapper = actionMap.get(servletPath);
		// 如果没有找到,则遍历所有正则路径
		if (mapper == null && !patternActionMap.isEmpty()) {
			Set patterns = patternActionMap.keySet();
			for (String pattern : patterns) {
				Matcher match = Pattern.compile(pattern).matcher(servletPath);
				while (match.find()) {
					mapper = patternActionMap.get(pattern);
					mapper.setParasValue(match);
					break;
				}
			}
		}
		return mapper;
	}

	public void destroy() {
		classes.clear();
		intercepters.clear();
		initializes.clear();
		actionMap.clear();
		patternActionMap.clear();
		mCtx.log("StrutsContext destroied");
		mCtx = null;
	}

	public Object getBean(Class cla) {
		try {
			Object obj = cla.newInstance();
			annotationInject(obj, cla);
			return obj;
		} catch (InstantiationException | IllegalAccessException e) {
			mCtx.log("Create '" + cla.getName() + "' bean faild", e);
		}
		return null;
	}

	private void annotationInject(Object obj, Class cla) throws IllegalArgumentException, IllegalAccessException {
		Field[] fields = cla.getDeclaredFields();
		for (Field field : fields) {
			if (field.getAnnotation(Resource.class) != null) {
				for (Class class1 : classes) {
					if (WebContextUtils.isResource(class1, field.getType())) {
						field.setAccessible(true);
						field.set(obj, getBean(field.getType()));
						field.setAccessible(false);
						break;
					}
				}
			}
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy