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); } }