package com.artfess.base.groovy; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import com.artfess.base.exception.BaseException; import com.artfess.base.util.BeanUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import groovy.lang.GroovyShell; /** * groovy脚本引擎 *
 * 
 * 配置方法如下:
 * <bean id="scriptEngine" class="com.artfess.base.core.engine.script.GroovyScriptEngine">
 *		<property name="bindingInterface">
 *			<list>
 *				<value>com.artfess.base.core.engine.script.IScript</value>
 *				<value>com.artfess.base.core.engine.script.IUserScript</value>
 *				<value>com.artfess.base.manager.api.Manager</value>
 *			</list>
 *		</property>
 *	</bean>
 *
 * bindingInterface:表示系统中继承了这些接口的类可以在脚本引擎中进行使用。
 * 
 * 上面的配置,说明:
 * 1.实现了IScript接口的类;
 * 2.实现了IUserScript接口的类;
 * 3.实现了Manager接口的类。
 * 可以在脚本中使用。
 * 
 * 
* * @company 广州宏天软件股份有限公司 * @author heyifan * @email heyf@jee-soft.cn * @date 2018年4月11日 */ public class GroovyScriptEngine implements BeanPostProcessor { private Log logger = LogFactory.getLog(getClass()); private GroovyBinding binding = new GroovyBinding(); /** 绑定接口 */ private List bindingInterface; /** * @return the bindingInterface */ public List getBindingInterface() { return bindingInterface; } /** * @param bindingInterface * the bindingInterface to set */ public void setBindingInterface(List bindingInterface) { this.bindingInterface = bindingInterface; } /** * 执行groovy代码无返回。 * * @param script */ public void execute(String script) { executeObject(script, null); } /** * 执行groovy代码无返回。 * * @param script * 脚本 * @param vars * 变量 */ public void execute(String script, Map vars) { executeObject(script, vars); } /** * 执行groovy代码返回布尔型。 * * @param script * @return * @throws Exception */ public boolean executeBoolean(String script, Map vars) { return (Boolean) executeObject(script, vars); } /** * 执行脚本返回字符串数据。 * * @param script * @return 字符串数据 */ public String executeString(String script, Map vars) { return BeanUtils.ObjectToString(executeObject(script, vars)); } /** * 执行脚本返回整形数据。 * * @param script * @return 整形数据 */ public int executeInt(String script, Map vars) { return (Integer) executeObject(script, vars); } /** * 执行脚本返回浮点型数据。 * * @param script * @return 浮点型数据 */ public float executeFloat(String script, Map vars) { return (Float) executeObject(script, vars); } /** * 执行脚本返回对象数据。 * * @param script * @return 对象数据 */ public Object executeObject(String script, Map vars) { try { //在执行时清除变量。 binding.clearVariables(); logger.debug("执行:" + script); GroovyShell shell = new GroovyShell(binding); this.setParameters(shell, vars); script = script.replace("'", "'").replace(""", "\"") .replace(">", ">").replace("<", "<") .replace("&nuot;", "\n").replace("&", "&"); Object rtn = shell.evaluate(script); return rtn; }catch (Exception e) { e.printStackTrace(); throw new BaseException("执行脚本" + script + "报错,请检查脚本"); } } /** * 设置执行参数。 * * @param shell * @param vars */ private void setParameters(GroovyShell shell, Map vars) { if (vars == null) return; Set> set = vars.entrySet(); for (Iterator> it = set.iterator(); it .hasNext();) { Map.Entry entry = (Map.Entry) it .next(); shell.setVariable(entry.getKey(), entry.getValue()); } } /** * 给groovy脚本引擎注入对象的引用。 */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { List> list=new ArrayList>(); for (String str : bindingInterface) { try{ Class clazz = Class.forName(str); list.add(clazz); } catch (ClassNotFoundException e) { e.printStackTrace(); logger.debug(e.getException()); } } for(Class clazz:list){ boolean isImpl = BeanUtils.isInherit(bean.getClass(), clazz); if(!isImpl) continue; if (isImpl){ binding.setProperty(beanName, bean); } } return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } }