package com.alibaba.tamper.process.script;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils;
import com.alibaba.tamper.core.helper.ReflectionHelper;
import com.alibaba.tamper.process.script.jexl.JexlScriptExecutor;
/**
* script的function class操作helper类
*
* @author jianghang 2011-6-27 下午07:32:25
*/
public class ScriptHelper {
private static final String DEFAULT_SCRIPT = JexlScriptExecutor.class.getName();
private static final String property = "BeanMapping.Script.Executor";
private static volatile ScriptHelper singleton = null;
private volatile ScriptExecutor executor = null;
public ScriptHelper(){
}
/**
* 单例方法
*/
public static ScriptHelper getInstance() {
if (singleton == null) {
synchronized (ScriptHelper.class) {
if (singleton == null) { // double check
singleton = new ScriptHelper();
}
}
}
return singleton;
}
/**
* @return 返回对应的{@linkplain ScriptExecutor}
*/
public ScriptExecutor getScriptExecutor() {
if (executor == null) {
synchronized (ScriptHelper.class) {
if (executor == null) {
executor = createScriptExecutor();
}
}
}
return executor;
}
/**
* 注册对应的function,并绑定为指定的name
*/
public void registerFunctionClass(String name, Object function) {
getScriptExecutor().addFunction(name, function);
}
/**
* 批量注册function
*/
public void batchRegisterFunctionClass(Map<String, Object> functions) {
if (functions != null && functions.size() > 0) {
for (Entry<String, Object> entry : functions.entrySet()) {
registerFunctionClass(entry.getKey(), entry.getValue());
}
}
}
/**
* 创建ScriptExecutor
*
* <pre>
* 1. 从jvm system property加载对应的classname
* 2. 从META-INF/services/加载对应的classname
* </pre>
*/
private ScriptExecutor createScriptExecutor() {
String className = null;
ClassLoader loader = ScriptExecutor.class.getClassLoader();
// 1. try the JVM-instance-wide system property
try {
className = System.getProperty(property);
} catch (RuntimeException e) { /* normally fails for applets */
}
// 2. if that fails, try META-INF/services/
if (StringUtils.isEmpty(className)) {
try {
String service = "META-INF/services/" + property;
InputStream in;
BufferedReader reader;
if (loader == null) {
in = ClassLoader.getSystemResourceAsStream(service);
} else {
in = loader.getResourceAsStream(service);
}
if (in != null) {
reader = new BufferedReader(new InputStreamReader(in, System.getProperty("file.encoding", "UTF-8")));
className = reader.readLine();
in.close();
}
} catch (Exception e) {
}
}
// 3. Distro-specific fallback
if (className == null) {
className = DEFAULT_SCRIPT;
}
Class clazz = ReflectionHelper.forName(className, loader);
return (ScriptExecutor) ReflectionHelper.newInstance(clazz);
}
}