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

com.inmorn.webmvc.context.MornWebApplicationContext Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2016- the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.inmorn.webmvc.context;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.NotFoundException;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;

import javax.servlet.FilterConfig;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.inmorn.context.annotation.Action;
import com.inmorn.context.annotation.Interceptor;
import com.inmorn.context.beans.factory.AbstractFactoryBean;
import com.inmorn.context.beans.factory.ContextFactoryBean;
import com.inmorn.core.util.StringUtils;
import com.inmorn.webmvc.annotation.RequestRoute;
import com.inmorn.webmvc.handler.ActionHandler;
import com.inmorn.webmvc.handler.Handler;
import com.inmorn.webmvc.interceptor.ActionInterceptor;
import com.inmorn.webmvc.support.InterceptorChain;
import com.inmorn.webmvc.support.ReqMapping;

/**
 * @author Jeff.Li
 * @date 2016年9月20日
 */
public class MornWebApplicationContext implements MornApplication{

	protected final Logger LOG = LoggerFactory.getLogger(getClass());
	private Map reqMappingMaps;
	private FilterConfig filterConfig;
	private List interceptorChains;
	private String scanPackage;
	private Set> classList;
	private Handler handler;
	private AbstractFactoryBean factoryBean;
	
	public MornWebApplicationContext(){
		reqMappingMaps = new LinkedHashMap();
	}
	
	public Handler getHandler(){
		return handler;
	}
	
	public void init(String scanPackage,FilterConfig filterConfig) {
		this.filterConfig = filterConfig;
		this.scanPackage = scanPackage;
		
		initFactoryBean();
		initInterceptor();
		initWebAction();
		handler = new ActionHandler(factoryBean,reqMappingMaps);
	}
	
	private void initWebAction(){
		ClassPool pool = ClassPool.getDefault();
		for (Class cl : classList) {
			Action action = cl.getAnnotation(Action.class);
			if(action == null) continue;
			
			String actionName = factoryBean.getBeanName(cl);
			if(LOG.isDebugEnabled()){
				LOG.debug("Morn Framework put action:" + actionName
						+ ",actionClass:" + cl);
			}
			
			CtClass cc = null;
			pool.insertClassPath(new ClassClassPath(cl));
			try {
				cc = pool.get(cl.getName());
			} catch (NotFoundException e1) {
				e1.printStackTrace();
			}
			
			RequestRoute actionReq = cl.getAnnotation(RequestRoute.class);
			String actionUrl = "";
			if(actionReq != null && StringUtils.isNotEmpty(actionReq.value())){
				actionUrl = actionReq.value();
			}
			
			Method[] methods = cl.getMethods();
			for (Method method : methods) {
				RequestRoute req = method.getAnnotation(RequestRoute.class);
				if(req != null){
					String uri = actionUrl + req.value();
					try {
						CtMethod cm = cc.getDeclaredMethod(method.getName());
						MethodInfo methodInfo = cm.getMethodInfo();  
			            CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
			            LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);  
			            if (attr == null) continue;
			            
			            String[] paramNames = new String[cm.getParameterTypes().length];
			            int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
			            for (int i = 0; i < paramNames.length; i++)
			                paramNames[i] = attr.variableName(i + pos);
			            
			            reqMappingMaps.put(uri,new ReqMapping(method.getParameterTypes(),
			            									  method.getParameterAnnotations(),
														  	  method.getReturnType(),
														      req.value(),
														      method.getName(),
														      paramNames,
														      method.getAnnotations(),
														      actionName,
														      getUriInterceptor(uri),
														      req.method()
														      )
			            );
			            if(LOG.isInfoEnabled()){
			            	LOG.info("Application add action url:" + uri + ",mapping actionClass:" + cl);
			            }
					} catch (NotFoundException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public void initInterceptor(){
		interceptorChains = new ArrayList();
		Map orderMap = new HashMap();
		for (Class cl : classList) {
			Interceptor interceptor = cl.getAnnotation(Interceptor.class);
			if(interceptor == null) continue;
			
			Class[] interfaces = cl.getInterfaces();
			boolean isInterceptorInterface = false;
			for (Class interfa : interfaces) {
				if(interfa == ActionInterceptor.class){
					isInterceptorInterface = true;
					break;
				}
			}
			
			if(!isInterceptorInterface){
				throw new RuntimeException("Interceptor class:" + cl 
						+ " not implements:" + ActionInterceptor.class);
			}
			
			int order = interceptor.order();
			if(orderMap.containsKey(order)){
				throw new RuntimeException("Interceptor " + cl 
						+ " order:" + order +" exist ");
			}
			
			orderMap.put(order, "");
			String[] path = interceptor.path();
			if(path == null || path.length == 0){
				throw new NullPointerException("Interceptor " + cl 
						+ " @Interceptor path not set. ");
			}
			
			for(String p : path){
				if(StringUtils.isEmpty(p) || p.indexOf("/**") == -1){
					throw new NullPointerException("Interceptor " + cl 
							+ " @Interceptor path is empty or path must include /**");
				}
			}
			
			String name = factoryBean.getBeanName(cl);
			ActionInterceptor actionInterceptor = (ActionInterceptor) factoryBean.getBean(name);
			interceptorChains.add(new InterceptorChain(order,path, actionInterceptor));
			LOG.info("Init Web Application Interceptor -->"+cl);
		}
		Collections.sort(interceptorChains);
	}
	
	public void initFactoryBean(){
		LOG.info("init Web Application Context ");
		factoryBean = new ContextFactoryBean(scanPackage,filterConfig.getInitParameter("contextProperties"));
		factoryBean.createContextBeans();
		classList = factoryBean.getAnnotationClasses();
	}
	
	public List getUriInterceptor(String uri){
		if(interceptorChains.isEmpty()){
			return null;
		}
		
		List interceptorList = new ArrayList();
		boolean uriExistsInterceptor = false;
		for (InterceptorChain chain : interceptorChains) {
			String[] paths = chain.getPath();
			for(String path : paths){
				path = path.replace("**", "");
				if(uri.startsWith(path)){
					uriExistsInterceptor = true;
					interceptorList.add(chain.getInterceptor());
				}
			}
		}
		
		if(!uriExistsInterceptor){
			return null;
		}
		return interceptorList;
	}
	
	public void shutdown() {
		filterConfig = null;
		reqMappingMaps.clear();
		handler = null;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy