All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ch.obermuhlner.scriptengine.java.JavaCompiledScript Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
package ch.obermuhlner.scriptengine.java;

import ch.obermuhlner.scriptengine.java.execution.ExecutionStrategy;

import javax.script.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class JavaCompiledScript extends CompiledScript {
    private final JavaScriptEngine engine;
    private final Class instanceClass;
    private final Object instance;
    private ExecutionStrategy executionStrategy;

    JavaCompiledScript(JavaScriptEngine engine, Class instanceClass, Object instance, ExecutionStrategy executionStrategy) {
        this.engine = engine;
        this.instanceClass = instanceClass;
        this.instance = instance;
        this.executionStrategy = executionStrategy;
    }

    public Class getInstanceClass() {
        return instanceClass;
    }

    public Object getInstance() {
        return instance;
    }

    public void setExecutionStrategy(ExecutionStrategy executionStrategy) {
        this.executionStrategy = executionStrategy;
    }

    @Override
    public ScriptEngine getEngine() {
        return engine;
    }

    @Override
    public Object eval(ScriptContext context) throws ScriptException {
        Bindings globalBindings = context.getBindings(ScriptContext.GLOBAL_SCOPE);
        Bindings engineBindings = context.getBindings(ScriptContext.ENGINE_SCOPE);

        pushVariables(globalBindings, engineBindings);
        Object result = executionStrategy.execute(instance);
        pullVariables(globalBindings, engineBindings);

        return result;
    }

    private void pushVariables(Bindings globalBindings, Bindings engineBindings) throws ScriptException {
        Map mergedBindings = mergeBindings(globalBindings, engineBindings);

        for (Map.Entry entry : mergedBindings.entrySet()) {
            String name = entry.getKey();
            Object value = entry.getValue();

            Class clazz = instance.getClass();
            try {
                Field field = clazz.getField(name);
                field.set(instance, value);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new ScriptException(e);
            }
        }
    }

    private void pullVariables(Bindings globalBindings, Bindings engineBindings) throws ScriptException {
        Class clazz = instance.getClass();

        for (Field field : clazz.getFields()) {
            try {
                String name = field.getName();
                Object value = field.get(instance);
                setBindingsValue(globalBindings, engineBindings, name, value);
            } catch (IllegalAccessException e) {
                throw new ScriptException(e);
            }
        }
    }

    private void setBindingsValue(Bindings globalBindings, Bindings engineBindings, String name, Object value) {
        if (!engineBindings.containsKey(name) && globalBindings.containsKey(name)) {
            globalBindings.put(name, value);
        } else {
            engineBindings.put(name, value);
        }
    }

    private Map mergeBindings(Bindings... bindingsToMerge) {
        Map variables = new HashMap<>();

        for (Bindings bindings : bindingsToMerge) {
            if (bindings != null) {
                for (Map.Entry globalEntry : bindings.entrySet()) {
                    variables.put(globalEntry.getKey(), globalEntry.getValue());
                }
            }
        }

        return variables;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy