/**
* Alipay.com Inc.
* Copyright (c) 2004-2012 All Rights Reserved.
*/
package com.alipay.zdal.rule.groovy;
import groovy.lang.GroovyClassLoader;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import com.alipay.zdal.rule.bean.AdvancedParameter;
import com.alipay.zdal.rule.ruleengine.cartesianproductcalculator.SamplingField;
import com.alipay.zdal.rule.ruleengine.exception.ZdalRuleCalculateException;
import com.alipay.zdal.rule.ruleengine.rule.CartesianProductBasedListResultRule;
import com.alipay.zdal.rule.ruleengine.rule.ResultAndMappingKey;
public class GroovyListRuleEngine extends CartesianProductBasedListResultRule {
private static final Logger logger = Logger.getLogger(GroovyListRuleEngine.class);
private Object ruleObj;
private Method m_routingRuleMap;
private static final String IMPORT_STATIC_METHOD = "import static com.alipay.zdal.rule.groovy.staticmethod.GroovyStaticMethod.*;";
protected void initInternal() {
if (expression == null) {
throw new IllegalArgumentException("δָ�� expression");
}
GroovyClassLoader loader = AccessController
.doPrivileged(new PrivilegedAction<GroovyClassLoader>() {
public GroovyClassLoader run() {
return new GroovyClassLoader(GroovyListRuleEngine.class.getClassLoader());
}
});
String groovyRule = getGroovyRule(expression);
Class<?> c_groovy = loader.parseClass(groovyRule);
try {
// �½���ʵ��
ruleObj = c_groovy.newInstance();
// ��ȡ����
m_routingRuleMap = getMethod(c_groovy, "eval", Map.class);
if (m_routingRuleMap == null) {
throw new IllegalArgumentException("����û�ҵ�");
}
m_routingRuleMap.setAccessible(true);
} catch (Throwable t) {
throw new IllegalArgumentException("ʵ�����������ʧ��", t);
}
}
private static final Pattern RETURN_WHOLE_WORD_PATTERN = Pattern.compile("\\breturn\\b",
Pattern.CASE_INSENSITIVE); // ȫ��ƥ��
private static final Pattern DOLLER_PATTERN = Pattern.compile("#.*?#");
// Integer.valueOf(#userIdStr#.substring(0,1),16).intdiv(8)
protected String getGroovyRule(String expression) {
StringBuffer sb = new StringBuffer();
sb.append(IMPORT_STATIC_METHOD);
Set<AdvancedParameter> params = new HashSet<AdvancedParameter>();
Matcher matcher = DOLLER_PATTERN.matcher(expression);
sb.append("public class RULE ").append("{");
sb.append("public Object eval(Map map){");
// StringBuffer sb = new StringBuffer();
// �滻����װadvancedParameter
int start = 0;
Matcher returnMarcher = RETURN_WHOLE_WORD_PATTERN.matcher(expression);
if (!returnMarcher.find()) {
sb.append("return ");
}
while (matcher.find(start)) {
String realParam = matcher.group();
realParam = realParam.substring(1, realParam.length() - 1);
AdvancedParameter advancedParameter = getAdvancedParamByParamToken(realParam);
params.add(advancedParameter);
sb.append(expression.substring(start, matcher.start()));
sb.append("(map.get(\"");
// �滻��(map.get("key"));
sb.append(advancedParameter.key);
sb.append("\"))");
start = matcher.end();
}
// ������Ҫ�õ��IJ���
setAdvancedParameter(params);
sb.append(expression.substring(start));
sb.append(";");
sb.append("}");
sb.append("}");
if (logger.isDebugEnabled()) {
logger.debug(sb.toString());
}
return sb.toString();
}
public ResultAndMappingKey evalueateSamplingField(SamplingField samplingField) {
List<String> columns = samplingField.getColumns();
List<Object> values = samplingField.getEnumFields();
int size = columns.size();
Map<String, Object> argumentMap = new HashMap<String, Object>(size);
for (int i = 0; i < size; i++) {
argumentMap.put(columns.get(i), values.get(i));
}
// ����Ӧ���Զ����ֶ�
if (GroovyContextHelper.getContext() != null) {
for (Map.Entry<String, Object> entry : GroovyContextHelper.getContext().entrySet()) {
argumentMap.put(entry.getKey(), entry.getValue());
}
}
// ����Ӧ��threadLocal�Զ����ֶ�
if (GroovyThreadLocalContext.getContext() != null) {
for (Map.Entry<String, Object> entry : GroovyThreadLocalContext.getContext().entrySet()) {
argumentMap.put(entry.getKey(), entry.getValue());
}
}
Object[] args = new Object[] { argumentMap };
try {
String result = imvokeMethod(args);
if (result != null) {
return new ResultAndMappingKey(result);
} else {
throw new IllegalArgumentException("��������Ľ������Ϊnull");
}
} catch (Exception e) {
throw new ZdalRuleCalculateException("��������������,���ֵ=" + argumentMap, e);
}
}
/**
* ����Ŀ�귽��
*
* @param args
* @return
*/
public String imvokeMethod(Object[] args) {
Object value = invoke(ruleObj, m_routingRuleMap, args);
String retString = null;
if (value == null) {
return null;
} else {
retString = String.valueOf(value);
return retString;
}
}
private static Method getMethod(Class<?> c, String name, Class<?>... parameterTypes) {
try {
return c.getMethod(name, parameterTypes);
} catch (SecurityException e) {
throw new IllegalArgumentException("ʵ�����������ʧ��", e);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("û���������" + name, e);
}
}
private static Object invoke(Object obj, Method m, Object... args) {
try {
return m.invoke(obj, args);
} catch (Throwable t) {
// logger.warn("���÷�����" + m + "ʧ��", t);
// return null;
throw new IllegalArgumentException("���÷���ʧ��: " + m, t);
}
}
@Override
public String toString() {
return "GroovyListRuleEngine [expression=" + expression + ", parameters=" + parameters
+ "]";
}
}