com.cybermkd.route.core.RouteInvocation Maven / Gradle / Ivy
package com.cybermkd.route.core;
import com.cybermkd.common.http.HttpRequest;
import com.cybermkd.common.http.HttpResponse;
import com.cybermkd.common.http.exception.WebException;
import com.cybermkd.common.http.result.HttpStatus;
import com.cybermkd.common.http.result.WebResult;
import com.cybermkd.common.spring.SpringBuilder;
import com.cybermkd.common.spring.SpringHolder;
import com.cybermkd.log.Logger;
import com.cybermkd.route.interceptor.Interceptor;
import com.cybermkd.route.render.RenderFactory;
import com.cybermkd.route.valid.ValidResult;
import com.cybermkd.route.valid.Validator;
import java.awt.image.RenderedImage;
import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.cybermkd.common.util.Checker.checkNotNull;
/**
* ActionInvocation invoke the action
*/
public class RouteInvocation {
private final static Logger logger = Logger.getLogger(RouteInvocation.class);
private Route route;
private RouteMatch routeMatch;
private Interceptor[] interceptors;
private int index = 0;
private boolean wasInvoke = false;
private Object invokeResult = null;
// ActionInvocationWrapper need this constructor
private RouteInvocation() {
}
public RouteInvocation(Route route, RouteMatch routeMatch) {
this.route = route;
this.routeMatch = routeMatch;
this.interceptors = route.getInterceptors();
}
/**
* Invoke the route.
*/
private void methodInvoke() {
if (index < interceptors.length) {
interceptors[index++].intercept(this);
} else if (index++ == interceptors.length) {
Resource resource;
try {
//初始化resource
if (SpringHolder.alive) {
resource = SpringBuilder.getBean(route.getResourceClass());
} else {
resource = route.getResourceClass().newInstance();
}
checkNotNull(resource, "Could init '" + route.getResourceClass() + "' before invoke method.");
resource.setRouteMatch(routeMatch);
//获取所有参数
Params params = routeMatch.getParams();
//数据验证
validate(params);
Method method = route.getMethod();
method.setAccessible(true);
//执行方法
if (route.getAllParamNames().size() > 0) {
List> allParamTypes = route.getAllParamTypes();
List allParamNames = route.getAllParamNames();
//执行方法的参数
Object[] args = new Object[allParamNames.size()];
int i = 0;
for (String name : allParamNames) {
if (HttpRequest.class.isAssignableFrom(allParamTypes.get(i))) {
args[i++] = routeMatch.getRequest();
} else if (HttpResponse.class.isAssignableFrom(allParamTypes.get(i))) {
args[i++] = routeMatch.getResponse();
} else if (Headers.class.isAssignableFrom(allParamTypes.get(i))) {
args[i++] = routeMatch.getHeaders();
} else if (Params.class.isAssignableFrom(allParamTypes.get(i))) {
args[i++] = routeMatch.getParams();
} else {
args[i++] = params.get(name);
}
}
invokeResult = method.invoke(resource, args);
} else {
invokeResult = method.invoke(resource);
}
wasInvoke = true;
//输出结果
render(invokeResult);
} catch (Exception e) {
route.throwException(e);
}
}
}
/**
* 输出内容
*
* @param invokeResult invokeResult
*/
public void render(Object invokeResult) {
Object result;
HttpRequest request = routeMatch.getRequest();
HttpResponse response = routeMatch.getResponse();
//通过特定的webresult返回并携带状态码
if (invokeResult instanceof WebResult) {
WebResult webResult = (WebResult) invokeResult;
response.setStatus(webResult.getStatus());
Map headers = webResult.getHeaders();
if (headers != null && headers.size() > 0) {
for (Map.Entry headersEntry : headers.entrySet()) {
response.setHeader(headersEntry.getKey(), headersEntry.getValue());
}
}
result = webResult.getResult();
} else {
result = invokeResult;
}
String extension = routeMatch.getExtension();
//file render
if ((result instanceof File && extension.equals("")) || extension.equals(RenderFactory.FILE)) {
RenderFactory.getFileRender().render(request, response, result);
} else if ((result instanceof RenderedImage && extension.equals("")) || extension.equals(RenderFactory.IMAGE)) {
//如果是string 表示为文件类型
if (result instanceof String) {
RenderFactory.getFileRender().render(request, response, result);
} else {
RenderFactory.getImageRender().render(request, response, result);
}
} else {
RenderFactory.get(extension).render(request, response, result);
}
}
/**
* 请求参数验证
*
* @param params 参数
*/
private void validate(Params params) {
Validator[] validators = route.getValidators();
if (validators.length > 0) {
Map errors = new HashMap();
HttpStatus status = HttpStatus.UNPROCESSABLE_ENTITY;
ValidResult vr;
for (Validator validator : validators) {
//数据验证
vr = validator.validate(params, routeMatch);
errors.putAll(vr.getErrors());
if (!status.equals(vr.getStatus()))
status = vr.getStatus();
if (errors.size() > 0) {
throw new WebException(status, errors);
}
}
}
}
public Method getMethod() {
return route.getMethod();
}
public Class getResourceClass() {
return route.getResourceClass();
}
public RouteMatch getRouteMatch() {
return routeMatch;
}
public Object invoke() {
if (!wasInvoke) {
methodInvoke();
}
return invokeResult;
}
}