
org.eweb4j.mvc.config.ActionAnnotationConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eweb4j-all Show documentation
Show all versions of eweb4j-all Show documentation
easy web framework for java, full-stack
The newest version!
package org.eweb4j.mvc.config;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.eweb4j.cache.ActionConfigBeanCache;
import org.eweb4j.cache.SingleBeanCache;
import org.eweb4j.config.Log;
import org.eweb4j.config.LogFactory;
import org.eweb4j.config.ScanPackage;
import org.eweb4j.mvc.ActionMethod;
import org.eweb4j.mvc.Http;
import org.eweb4j.mvc.action.RenderType;
import org.eweb4j.mvc.action.annotation.ActionLevel;
import org.eweb4j.mvc.action.annotation.Controller;
import org.eweb4j.mvc.action.annotation.Result;
import org.eweb4j.mvc.action.annotation.ShowValMess;
import org.eweb4j.mvc.action.annotation.Singleton;
import org.eweb4j.mvc.config.bean.ActionConfigBean;
import org.eweb4j.mvc.config.bean.ResultConfigBean;
import org.eweb4j.mvc.config.bean.ValidatorConfigBean;
import org.eweb4j.mvc.config.creator.ValidatorUtil;
import org.eweb4j.mvc.validator.annotation.Validate;
import org.eweb4j.util.CommonUtil;
import org.eweb4j.util.ReflectUtil;
public class ActionAnnotationConfig extends ScanPackage {
public final static Log log = LogFactory.getMVCLogger(ActionAnnotationConfig.class);
public ActionAnnotationConfig() {
super();
}
/**
* handle action class
*
* @param clsName
* @throws Exception
*/
public boolean handleClass(String clsName) {
//log.debug("handleClass -> " + clsName);
Class> cls = null;
try {
cls = Thread.currentThread().getContextClassLoader().loadClass(clsName);
if (cls == null)
return false;
String simpleName = cls.getSimpleName();
Controller controlAnn = cls.getAnnotation(Controller.class);
if (controlAnn == null && !simpleName.endsWith("Controller") && !simpleName.endsWith("Action") && !simpleName.endsWith("Control"))
return false;
String moduleName = CommonUtil.toLowCaseFirst(simpleName.replace("Controller", "").replace("Control", ""));
if (simpleName.endsWith("Action"))
moduleName = "";
if ("application".equals(moduleName))
moduleName = "/";
// boolean hasPath = JAXWSUtil.hasPath(cls);
// if (hasPath){
// moduleName = PathUtil.getPathValue(cls);
// }
Object obj = null;
try {
if (cls.getAnnotation(Singleton.class) != null) {
obj = SingleBeanCache.get(cls.getName());
if (obj == null) {
obj = cls.newInstance();
SingleBeanCache.add(cls.getName(), obj);
}
} else
obj = cls.newInstance();
} catch (Throwable e) {
log.warn("the action class new instance failued -> " + clsName + " | " + e.toString(), e);
return false;
}
ReflectUtil ru = new ReflectUtil(obj);
Method[] ms = ru.getMethods();
if (ms == null)
return false;
// 扫描方法的注解信息
for (Method m : ms) {
if (m.getModifiers() != 1)
continue;
boolean hasPath = JAXWSUtil.hasPath(m);
//log.debug("scan method->"+m+" has path->"+hasPath);
if (!hasPath) {
String methodName = m.getName();
Method getter = ru.getGetter(methodName.replace("get", ""));
Method setter = ru.getSetter(methodName.replace("set", ""));
// 默认下setter和getter不作为action方法
if (getter != null || setter != null)
continue;
}
handleActionConfigInfo(ru, cls, m, moduleName);
}
} catch (Error e) {
return false;
} catch (Exception e) {
return false;
}
return true;
}
/**
* 处理Action配置信息
*
* @param ru
* @param controller
* @param method
* @param moduleName
*/
private void handleActionConfigInfo(ReflectUtil ru, Class> controller, Method method, String moduleName) {
//log.debug("now parse the method...... moduleName->" + moduleName);
// 这一步解析约定好的方法名doXxxAtXxx
final ActionConfigBean action = parseUriMappingSuffix(moduleName, method);
//log.debug("parse uri mapping by default rule -> " + action);
if (action == null)
return;
action.setClazz(controller.getName());
action.setMethod(method.getName());
/* 解析出验证器错误信息输出类型 */
// action.setShowValErrorType(parseShowValErrType(controller, method));
/* 解析出Http Method */
String httpMethod = parseHttpMethodByAnnotation(controller, method);
// 如果方法上的注解不为空则覆盖约定好的
if (httpMethod != null && httpMethod.trim().length() > 0)
action.setHttpMethod(httpMethod);
//log.debug("parse httpMethod -> " + httpMethod);
/* 解析出最终的uriMapping */
String uriMapping = parseUriMapping(controller, moduleName, action.getUriMapping());
//log.debug("parse uriMapping -> " + uriMapping);
if (uriMapping != null && uriMapping.trim().length() > 0)
action.setUriMapping(uriMapping);
// 解析@Result注解
Result resultAnn = method.getAnnotation(Result.class);
if (resultAnn != null)
action.getResult().addAll(ResultAnnUtil.readResultAnn(resultAnn));
/* 解析@ActionLevel */
int level = parseActionLevel(controller, method);
action.setLevel(String.valueOf(level));
/* 解析@Produces */
List pcbs = parseProduces(method);
if (pcbs != null)
action.getProduces().addAll(pcbs);
/* 解析@Validator和各种验证器 */
List vals = parseValidators(ru, method);
if (vals != null)
action.getValidator().addAll(vals);
/* 解析最终的actionKey (包括合并http method、正则等) */
String actionConfigKey = parseFullUriMapping(controller, method, action.getHttpMethod(), action.getUriMapping());
//log.debug("parse actionConfigKey -> " + actionConfigKey);
if (actionConfigKey == null)
return;
// 将读取成功的配置信息放入缓存供框架运行期使用
//log.debug("action cache add key -> "+actionConfigKey + ", action->" + action);
ActionConfigBeanCache.add(actionConfigKey, action);
ActionClassCache.add(action.getClazz(), controller);
}
/**
* 解析 URI Mapping 后部分
*
* @param moduleName
* @param m
* @return
*/
private ActionConfigBean parseUriMappingSuffix(String moduleName, Method m) {
ActionConfigBean acb = new ActionConfigBean();
String methodName = m.getName();
String fullName = m.toString();
boolean hasPath = JAXWSUtil.hasPath(m);
//log.debug("has path of method "+m+" ->" + hasPath);
String uriMapping = null;
if (methodName.startsWith(ActionMethod.PREFIX)) {
uriMapping = methodName.substring(ActionMethod.PREFIX.length());
// doUriBindParam1AndParam2JoinUriAtPostOrGet
String at = null;
int indexOfAt = methodName.indexOf(ActionMethod.AT);
if (indexOfAt != -1) {
at = methodName.substring(indexOfAt + ActionMethod.AT.length());
if (methodName.startsWith(ActionMethod.PREFIX))
uriMapping = uriMapping.substring(0,
uriMapping.indexOf(ActionMethod.AT));
String[] httpMethods = at.split(ActionMethod.OR);
StringBuilder sb = new StringBuilder();
for (String httpMethod : httpMethods) {
if (sb.length() > 0)
sb.append("|");
sb.append(httpMethod.toUpperCase());
}
if (sb.length() > 0) {
acb.setHttpMethod(sb.toString());
}
}
String join = "";
String bind;
int indexOfBind = methodName.indexOf(ActionMethod.BIND);
if (indexOfBind != -1) {
if (indexOfAt != -1 && indexOfAt > indexOfBind) {
bind = methodName
.substring(
indexOfBind + ActionMethod.BIND.length(),
indexOfAt);
} else {
bind = methodName.substring(indexOfBind
+ ActionMethod.BIND.length());
}
uriMapping = uriMapping.substring(0,
uriMapping.indexOf(ActionMethod.BIND));
int indexOfJoin = bind.indexOf(ActionMethod.JOIN);
if (indexOfJoin != -1) {
String[] joins = bind.split(ActionMethod.JOIN);
if (joins.length > 1) {
bind = joins[0];
join = joins[1];
}
}
String[] pathParams = bind.split(ActionMethod.AND);
StringBuilder pathParamSB = new StringBuilder();
for (int i = 0; i < pathParams.length; i++) {
pathParams[i] = CommonUtil.toLowCaseFirst(pathParams[i]);
pathParamSB.append("/{").append(pathParams[i]).append("}");
}
if (pathParamSB.length() > 0)
uriMapping = uriMapping + pathParamSB.toString();
acb.setPathParams(pathParams);
}
uriMapping = CommonUtil.toLowCaseFirst(uriMapping);
uriMapping = CommonUtil.hump2ohter(uriMapping, "-");
if (join.length() > 0) {
join = CommonUtil.toLowCaseFirst(join);
join = CommonUtil.hump2ohter(join, "-");
uriMapping = uriMapping + "/" + join;
}
} else if (!hasPath) {
//log.debug("parse action by default rule......");
/* 8 个默认方法 */
ActionConfigBean defaultAcb = parseDefaultActionConfig(methodName, moduleName);
//log.debug("parse action by default rule......--->"+defaultAcb);
if (defaultAcb != null) {
acb.setHttpMethod(defaultAcb.getHttpMethod());
acb.getResult().addAll(defaultAcb.getResult());
uriMapping = defaultAcb.getUriMapping();
} else {
String info = fullName + " does not starts with '" + ActionMethod.PREFIX + "' so that can not be a valid action uri mapping";
//log.debug(info);
return null;
}
}
if (hasPath) {
uriMapping = CommonUtil.parsePropValue(org.eweb4j.mvc.config.PathUtil.getPathValue(m));
}
//log.debug("parse uri mapping first -> " + uriMapping + ", hasPath->" + hasPath);
acb.setUriMapping(uriMapping);
return acb;
}
/**
* 解析默认的Action配置
*
* @param methodReqMapVal
* @param moduleName
* @return
*/
private static ActionConfigBean parseDefaultActionConfig(String methodName, String modelName) {
String moduleName = null;
if (modelName.equals("/")){
moduleName = "";
}else{
moduleName = modelName.endsWith("/") ? modelName.substring(0, modelName.lastIndexOf("/")) : modelName;
}
String uriMapping = null;
String httpMethod = null;
ActionConfigBean acb = new ActionConfigBean();
if (ActionMethod.INDEX.equals(methodName)) {
uriMapping = "/";
httpMethod = Http.Method.GET;
ResultConfigBean rcb = new ResultConfigBean();
rcb.setName("jsp");
rcb.setLocation(moduleName + "/view/index.jsp");
acb.getResult().add(rcb);
ResultConfigBean rcb2 = new ResultConfigBean();
rcb2.setName("html");
rcb2.setType(RenderType.FREEMARKER);
rcb2.setLocation(moduleName + "/view/index.html");
acb.getResult().add(rcb2);
} else if (ActionMethod.CREATE.equals(methodName)) {
uriMapping = "/";
httpMethod = Http.Method.POST;
ResultConfigBean rcb = new ResultConfigBean();
rcb.setName(ActionMethod.INDEX);
rcb.setLocation(moduleName);
rcb.setType(RenderType.ACTION);
acb.getResult().add(rcb);
} else if (ActionMethod.UPDATE.equals(methodName)) {
uriMapping = "/{id}";
httpMethod = Http.Method.PUT;
ResultConfigBean rcb = new ResultConfigBean();
rcb.setName(ActionMethod.INDEX);
rcb.setLocation(moduleName);
rcb.setType(RenderType.ACTION);
acb.getResult().add(rcb);
} else if (ActionMethod.SHOW.equals(methodName)) {
uriMapping = "/{id}";
httpMethod = Http.Method.GET;
ResultConfigBean rcb = new ResultConfigBean();
rcb.setName("jsp");
rcb.setLocation(moduleName + "/view/show.jsp");
acb.getResult().add(rcb);
ResultConfigBean rcb2 = new ResultConfigBean();
rcb2.setName("html");
rcb2.setType(RenderType.FREEMARKER);
rcb2.setLocation(moduleName + "/view/show.html");
acb.getResult().add(rcb2);
} else if (ActionMethod.EDIT.equals(methodName)) {
uriMapping = "/{id}/edit";
httpMethod = Http.Method.GET;
ResultConfigBean rcb = new ResultConfigBean();
rcb.setName("jsp");
rcb.setLocation(moduleName + "/view/edit.jsp");
acb.getResult().add(rcb);
ResultConfigBean rcb2 = new ResultConfigBean();
rcb2.setName("html");
rcb2.setType(RenderType.FREEMARKER);
rcb2.setLocation(moduleName + "/view/edit.html");
acb.getResult().add(rcb2);
} else if (ActionMethod.DESTROY.equals(methodName)) {
uriMapping = "/{id}";
httpMethod = Http.Method.DELETE;
ResultConfigBean rcb = new ResultConfigBean();
rcb.setName(ActionMethod.INDEX);
rcb.setLocation(moduleName);
rcb.setType(RenderType.ACTION);
acb.getResult().add(rcb);
} else if (ActionMethod.NEW.equals(methodName)) {
uriMapping = "/new";
httpMethod = Http.Method.GET;
ResultConfigBean rcb = new ResultConfigBean();
rcb.setName("jsp");
rcb.setLocation(moduleName + "/view/new.jsp");
acb.getResult().add(rcb);
ResultConfigBean rcb2 = new ResultConfigBean();
rcb2.setName("html");
rcb2.setType(RenderType.FREEMARKER);
rcb2.setLocation(moduleName + "/view/new.html");
acb.getResult().add(rcb2);
} else {
acb = null;
}
if (acb != null) {
acb.setHttpMethod(httpMethod);
acb.setUriMapping(uriMapping);
}
return acb;
}
private static String parseHttpMethodByClazz(Class> cls) {
final String GET = Http.Method.GET;
final String POST = Http.Method.POST;
final String PUT = Http.Method.PUT;
final String DELETE = Http.Method.DELETE;
String[] methods = new String[4];
methods[0] = JAXWSUtil.hasGET(cls) ? GET : "";
methods[1] = JAXWSUtil.hasPOST(cls) ? POST : "";
methods[2] = JAXWSUtil.hasDELETE(cls) ? DELETE : "";
methods[3] = JAXWSUtil.hasPUT(cls) ? PUT : "";
StringBuilder m_sb = new StringBuilder();
for (String s : methods) {
if (m_sb.length() > 0 && s.length() > 0)
m_sb.append("|");
m_sb.append(s);
}
if (m_sb.length() == 0)
return null;
return m_sb.toString();
}
private static String parseFullUriMapping(Class> cls, Method m,
final String httpMethod, final String uriMapping) {
// Action全名,框架用,包括对“{xxx}”url参数的正则化,HttpRequestMethod
String actionFullName = ActionUrlUtil.mathersUrlMapping(m, uriMapping,
cls);
if (actionFullName == null)
return null;
if (actionFullName.endsWith("/")) {
actionFullName.substring(0, actionFullName.length() - 1);
}
actionFullName = actionFullName + ActionMethod.CON + httpMethod;
return actionFullName;
}
private static List parseValidators(ReflectUtil ru,
Method m) {
List vals = new ArrayList();
// 读取@Validate注解,拿到需要被验证的参数名称
Validate validate = m.getAnnotation(Validate.class);
if (validate == null)
return vals;
String[] fields = validate.value();
String[] excepts = validate.except();
if (fields != null) {
// 读取Action object 的属性 验证信息
List fieldVal = ValidatorUtil.readValidator(fields, excepts, null, ru, null, null);
if (fieldVal != null)
vals.addAll(fieldVal);
}
return vals;
}
private static List parseProduces(Method m) {
// 读取@Produces注解
// Produces producesAnn = m.getAnnotation(Produces.class);
boolean hasProduces = JAXWSUtil.hasProduces(m);
List pcbs = null;
if (hasProduces) {
pcbs = new ArrayList();
String producesStr = CommonUtil.parsePropValue(ProducesUtil.getProducesValue(m)[0]);
pcbs.add(producesStr);
}
return pcbs;
}
private static int parseActionLevel(Class> cls, Method m) {
// 读取@ActionLevel注解
ActionLevel actionLevel = cls.getAnnotation(ActionLevel.class);
if (actionLevel == null)
actionLevel = m.getAnnotation(ActionLevel.class);
int level = 1;
if (actionLevel != null)
level = actionLevel.value();
return level;
}
private static String parseShowValErrType(Class> cls, Method m) {
ShowValMess cls_vm = cls.getAnnotation(ShowValMess.class);
String clsShowValErr = cls_vm == null ? "alert" : cls_vm.value();
clsShowValErr = CommonUtil.parsePropValue(clsShowValErr);
String methodShowValErr = clsShowValErr.trim().length() == 0 ? "alert" : clsShowValErr;// 验证器验证信息输出方式默认”alert“
ShowValMess m_vm = m.getAnnotation(ShowValMess.class);
methodShowValErr = m_vm == null ? methodShowValErr : m_vm.value();
return methodShowValErr;
}
private static String parseHttpMethodByAnnotation(Class> cls, Method m) {
String methodHttpMethod = parseHttpMethodByMethodAnnotation(m);
if (methodHttpMethod != null)
return methodHttpMethod;
return parseHttpMethodByClazz(cls);
}
private static String parseHttpMethodByMethodAnnotation(Method m) {
String[] _methods = new String[4];
_methods[0] = JAXWSUtil.hasGET(m) ? Http.Method.GET : "";
_methods[1] = JAXWSUtil.hasPOST(m) ? Http.Method.POST : "";
_methods[2] = JAXWSUtil.hasDELETE(m) ? Http.Method.DELETE : "";
_methods[3] = JAXWSUtil.hasPUT(m) ? Http.Method.PUT : "";
StringBuilder _sb = new StringBuilder();
for (String s : _methods) {
if (s.trim().length() == 0)
continue;
if (_sb.length() > 0 && s.length() > 0)
_sb.append("|");
_sb.append(s);
}
return _sb.toString();
}
/**
* 解析 Uri Mapping 的前部分
*
* @param cls
* @param moduleName
* @return
*/
private static String parseUriMappingPrefix(Class> cls, String moduleName) {
boolean hasPath = JAXWSUtil.hasPath(cls);
//log.debug("has path of cls->" + cls + " is " + hasPath);
String clazzUriMapping = hasPath ? PathUtil.getPathValue(cls) : moduleName;
//log.debug("cls uri->" + clazzUriMapping);
clazzUriMapping = CommonUtil.parsePropValue(clazzUriMapping);
return clazzUriMapping;
}
/**
* 解析
*
* @param cls
* @param moduleName
* @param methodUriMapping
* @return
*/
private static String parseUriMapping(Class> cls, String moduleName, String uriMappingSuffix) {
String uriPrefix = parseUriMappingPrefix(cls, moduleName);
if (uriPrefix.length() > 0 && !uriMappingSuffix.startsWith("/"))
uriPrefix = uriPrefix + "/";
String uriMapping = uriPrefix + uriMappingSuffix;
if (uriMapping.startsWith("/"))
uriMapping = uriMapping.substring(1);
if (uriMapping.endsWith("/"))
uriMapping = uriMapping.substring(0, uriMapping.length() - 1);
//log.debug("parse class uri mapping after resolve->"+uriMapping);
return uriMapping;
}
@Override
protected void onOk() throws Exception {
// TODO Auto-generated method stub
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy