org.xbib.elasticsearch.script.nashorn.NashornScriptEngineService.java Source code

Java tutorial

Introduction

Here is the source code for org.xbib.elasticsearch.script.nashorn.NashornScriptEngineService.java

Source

/*
 * Licensed to Elasticsearch under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch licenses this file to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.xbib.elasticsearch.script.nashorn;

import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.ScriptEngineService;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.lookup.SearchLookup;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import javax.script.SimpleBindings;

import java.util.List;
import java.util.Map;

import jdk.nashorn.api.scripting.NashornScriptEngineFactory;

/**
 *
 */
public class NashornScriptEngineService extends AbstractComponent implements ScriptEngineService {

    private final ScriptEngine engine;

    @Inject
    public NashornScriptEngineService(Settings settings) {
        super(settings);
        // setup the engine to share the definition of the Ecma script built-in objects: aka NashornGlobal.
        //      System.setProperty("nashorn.args", "--global-per-engine");
        //      ScriptEngineManager m = new ScriptEngineManager();
        //      this.engine = m.getEngineByName("nashorn");
        // changing a system property is not allowed by the tests.
        // Use the internal API instead
        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
        this.engine = factory.getScriptEngine(new String[] { "--global-per-engine" });
    }

    @Override
    public void close() {
    }

    @Override
    public String[] types() {
        List<String> list = engine.getFactory().getNames();
        return list.toArray(new String[list.size()]);
    }

    @Override
    public String[] extensions() {
        List<String> list = engine.getFactory().getExtensions();
        return list.toArray(new String[list.size()]);
    }

    @Override
    public Object compile(String script) {
        Compilable compilable = (Compilable) engine;
        try {
            return compilable.compile(script);
        } catch (ScriptException e) {
            throw new org.elasticsearch.script.ScriptException(e.getMessage(), e);
        }
    }

    @Override
    public ExecutableScript executable(Object compiledScript, Map<String, Object> vars) {
        CompiledScript script = (CompiledScript) compiledScript;
        return new NashornExecutableScript(script, bind(vars));
    }

    @Override
    public SearchScript search(Object compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
        return new NashornSearchScript(lookup, (CompiledScript) compiledScript, bind(bind(lookup.asMap()), vars));
    }

    @Override
    public Object execute(Object compiledScript, Map<String, Object> vars) {
        CompiledScript script = (CompiledScript) compiledScript;
        try {
            return script.eval(bind(vars));
        } catch (ScriptException e) {
            throw new org.elasticsearch.script.ScriptException(e.getMessage(), e);
        }
    }

    @Override
    public Object unwrap(Object value) {
        return NashornUnwrapper.unwrapValue(value);
    }

    /**
     * Nashorn does not accept Java Lists/Collections, and silently fails.
     * Convert them to object arrays before binding them
     *
     * @param vars vars
     * @return bindings
     */
    private Bindings bind(Map<String, Object> vars) {
        return bind(new SimpleBindings(), vars);
    }

    private Bindings bind(Bindings bindings, Map<String, Object> vars) {
        if (vars != null) {
            for (Map.Entry<String, Object> me : vars.entrySet()) {
                Object o = me.getValue();
                bindings.put(me.getKey(), o instanceof List ? ((List) o).toArray() : o);
            }
        }
        return bindings;
    }

}