package org.theonefx.wcframework.aop;
import java.lang.reflect.Method;
import org.theonefx.wcframework.aop.exception.AopMetadataException;
import org.theonefx.wcframework.utils.StringUtils;
import org.theonefx.wcframework.utils.WildcardMatcher;
/**
* @File : ExpressionPointcut.java
* @ClassName : ExpressionPointcut
* @Author : TheoneFx
* @Date : 2013-3-7 下午01:40:16
* @Version : v1.0
* @Description : 基于表达式的切入点<br>
* 表达式规则:<br>
* [a]:[b]([c])<br>
* [a]代表class部分。 必填 可以使用包名.类名的方式,也可以使用通配符。<br>
* [b]代表mathod部分。 必填 可以使用方法全名,也可以部分输入然后使用通配符。<br>
* [c]代表args部分。 可不填 如果填写,外层必须使用圆括号,如果内部有多个参数,各个参数之间使用逗号','分隔,参数如果是基本类型可以使用基本类型的小写形式代替,如果是自定义类型,那么需要填写类全名和包名,同样支持通配符;<br>
* 如果不填写,圆括号也可以省略;当然也可以只写一个圆括号内部不填写内容。<br>
* [a][b]之间使用:分隔<br>
* [a][b][c]三个部分都可以使用如下通配符<br>
* * 代表任意长度字符串<br>
* ? 代表任意一个字符<br>
*/
public class ExpressionPointcut implements Pointcut {
private final String expression;
private String classPart;
private String methodPart;
private String[] argsPart;
public ExpressionPointcut(String expression) {
if (StringUtils.isBlank(expression)) {
error("表达式为空");
}
this.expression = StringUtils.trimWhitespace(expression);
parseExpression();
}
private void parseExpression() {
int index1 = expression.indexOf(":");
int index2 = expression.indexOf("(");
int index3 = expression.lastIndexOf(")");
if (index1 < 0) {
error("表达式没有类和方法的分隔符':'");
}
if (index1 == 0) {
error("没有定义类和包部分");
}
if (index2 >= 0) {
if (index2 == index1 + 1) {
error("表达式没有定义方法部分");
}
if (index3 < index2) {
error("参数表达式没有闭合");
}
} else {
if (index1 + 1 == expression.length()) {
error("表达式没有定义方法部分");
}
}
classPart = expression.substring(0, index1);
String argsExpression;
if (index2 > 0) {
methodPart = expression.substring(index1 + 1, index2);
argsExpression = expression.substring(index2 + 1, index3);
if(StringUtils.isBlank(argsExpression)){
argsExpression = "*";
}
} else {
methodPart = expression.substring(index1 + 1);
argsExpression = "*";
}
if (!"*".equals(argsExpression)) {
argsPart = argsExpression.split(",");
}
}
@Override
public ClassFilter getClassFilter() {
return expressClassFilter;
}
@Override
public MethodMatcher getMethodMatcher() {
return expressMethodMatcher;
}
private ClassFilter expressClassFilter = new ClassFilter() {
@Override
public boolean matches(Class<?> clazz) {
String fullname = clazz.getCanonicalName();
return WildcardMatcher.match(fullname, classPart);
}
};
private MethodMatcher expressMethodMatcher = new MethodMatcher() {
@Override
public boolean match(Method method) {
// 不匹配Object原生的方法,这些方法AOP了也没有意义
if (method.getDeclaringClass() == Object.class) {
return false;
}
String methodName = method.getName();
boolean match = WildcardMatcher.match(methodName, methodPart);
if (match) {
if (argsPart != null) {
Class<?>[] types = method.getParameterTypes();
if (types.length != argsPart.length) {
match = false;
} else {
for (int i = 0; i < types.length; i++) {
match = match && WildcardMatcher.match(types[i].getCanonicalName(), argsPart[i]);
if (!match) {
break;
}
}
}
}
}
return match;
}
};
private void error(String reason) {
throw new AopMetadataException("无效的表达式'" + expression + "':" + reason);
}
public static void main(String[] args) {
}
}