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