
de.tsl2.nano.incubation.specification.rules.RuleScript Maven / Gradle / Ivy
/*
* File: $HeadURL$
* Id : $Id$
*
* created by: Tom, Thomas Schneider
* created on: 04.11.2015
*
* Copyright: (c) Thomas Schneider 2015, all rights reserved
*/
package de.tsl2.nano.incubation.specification.rules;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.script.Bindings;
import javax.script.ScriptEngine;
import org.apache.commons.logging.Log;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.core.Commit;
import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.ManagedException;
import de.tsl2.nano.core.execution.ScriptEngineProvider;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.incubation.specification.ParType;
import de.tsl2.nano.incubation.specification.Pool;
import de.tsl2.nano.util.operation.Operator;
/**
* Uses javascript engine (java6+7: rhino, java8: nashorn) to evaluate an operation.
*
* @author Tom, Thomas Schneider
* @version $Revision$
*/
public class RuleScript extends AbstractRule {
/** serialVersionUID */
private static final long serialVersionUID = -6479357867492017791L;
private static final Log LOG = LogFactory.getLog(RuleScript.class);
@Attribute(required=false)
String language;
transient ScriptEngine engine;
public static final char PREFIX = '%';
/**
* constructor
*/
protected RuleScript() {
super();
}
public RuleScript(String name, String operation, LinkedHashMap parameter) {
this(null, name, operation, parameter);
}
/**
* constructor
*
* @param name
* @param operation
* @param parameter
*/
public RuleScript(String language, String name, String operation, LinkedHashMap parameter) {
super(name, operation, parameter);
init(language);
}
void init(String engineName) {
this.language = engineName;
}
protected ScriptEngine engine() {
if (engine == null)
engine = ActionScript.createEngine(language);
return engine;
}
@Override
public String prefix() {
return String.valueOf(PREFIX);
}
@Override
public T run(Map arguments, Object... extArgs) {
if (!initialized) {
importSubRules();
}
arguments = checkedArguments(arguments, ENV.get("app.mode.strict", false));
//in generics it is not possible to cast from Map(String,?) to Map(CharSequence, ?)
try {
LOG.debug("running rule <" + toString() + "> on arguments: " + arguments);
Object obj = engine().eval(getOperation(), bind(arguments));
T result = (T) transform(obj);
checkConstraint(Operator.KEY_RESULT, result);
return result;
} catch (Exception e) {
ManagedException.forward(e);
return null;
}
}
/**
* some java script objects like 'java.util.HashMap' must be transformed to real java objects. E.g. the javascript
* 'java.util.HashMap' seems not to implement Serializable!
*
* @param jsValue
* @return real java class object
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private T transform(Object jsValue) {
if (jsValue instanceof Map)
return (T) new LinkedHashMap((Map) jsValue);
else if (jsValue instanceof Collection)
return (T) new ArrayList((Collection) jsValue);
else
return (T) jsValue;
}
private Bindings bind(Map arguments) {
return ScriptEngineProvider.bind(engine(), arguments);
}
@Override
@Commit
protected void initDeserializing() {
init(language);
super.initDeserializing();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy