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

org.springframework.scripting.support.StandardScriptEvaluator Maven / Gradle / Ivy

/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed 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
 *
 *      https://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.springframework.scripting.support;

import java.io.IOException;
import java.util.Map;

import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.scripting.ScriptCompilationException;
import org.springframework.scripting.ScriptEvaluator;
import org.springframework.scripting.ScriptSource;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * {@code javax.script} (JSR-223) based implementation of Spring's {@link ScriptEvaluator}
 * strategy interface.
 *
 * @author Juergen Hoeller
 * @author Costin Leau
 * @since 4.0
 * @see ScriptEngine#eval(String)
 */
public class StandardScriptEvaluator implements ScriptEvaluator, BeanClassLoaderAware {

	@Nullable
	private String engineName;

	@Nullable
	private volatile Bindings globalBindings;

	@Nullable
	private volatile ScriptEngineManager scriptEngineManager;


	/**
	 * Construct a new {@code StandardScriptEvaluator}.
	 */
	public StandardScriptEvaluator() {
	}

	/**
	 * Construct a new {@code StandardScriptEvaluator} for the given class loader.
	 * @param classLoader the class loader to use for script engine detection
	 */
	public StandardScriptEvaluator(ClassLoader classLoader) {
		this.scriptEngineManager = new ScriptEngineManager(classLoader);
	}

	/**
	 * Construct a new {@code StandardScriptEvaluator} for the given JSR-223
	 * {@link ScriptEngineManager} to obtain script engines from.
	 * @param scriptEngineManager the ScriptEngineManager (or subclass thereof) to use
	 * @since 4.2.2
	 */
	public StandardScriptEvaluator(ScriptEngineManager scriptEngineManager) {
		this.scriptEngineManager = scriptEngineManager;
	}


	/**
	 * Set the name of the language meant for evaluating the scripts (e.g. "Groovy").
	 * 

This is effectively an alias for {@link #setEngineName "engineName"}, * potentially (but not yet) providing common abbreviations for certain languages * beyond what the JSR-223 script engine factory exposes. * @see #setEngineName */ public void setLanguage(String language) { this.engineName = language; } /** * Set the name of the script engine for evaluating the scripts (e.g. "Groovy"), * as exposed by the JSR-223 script engine factory. * @since 4.2.2 * @see #setLanguage */ public void setEngineName(String engineName) { this.engineName = engineName; } /** * Set the globally scoped bindings on the underlying script engine manager, * shared by all scripts, as an alternative to script argument bindings. * @since 4.2.2 * @see #evaluate(ScriptSource, Map) * @see javax.script.ScriptEngineManager#setBindings(Bindings) * @see javax.script.SimpleBindings */ public void setGlobalBindings(Map globalBindings) { Bindings bindings = StandardScriptUtils.getBindings(globalBindings); this.globalBindings = bindings; ScriptEngineManager scriptEngineManager = this.scriptEngineManager; if (scriptEngineManager != null) { scriptEngineManager.setBindings(bindings); } } @Override public void setBeanClassLoader(ClassLoader classLoader) { ScriptEngineManager scriptEngineManager = this.scriptEngineManager; if (scriptEngineManager == null) { scriptEngineManager = new ScriptEngineManager(classLoader); this.scriptEngineManager = scriptEngineManager; Bindings bindings = this.globalBindings; if (bindings != null) { scriptEngineManager.setBindings(bindings); } } } @Override @Nullable public Object evaluate(ScriptSource script) { return evaluate(script, null); } @Override @Nullable public Object evaluate(ScriptSource script, @Nullable Map argumentBindings) { ScriptEngine engine = getScriptEngine(script); try { if (CollectionUtils.isEmpty(argumentBindings)) { return engine.eval(script.getScriptAsString()); } else { Bindings bindings = StandardScriptUtils.getBindings(argumentBindings); return engine.eval(script.getScriptAsString(), bindings); } } catch (IOException ex) { throw new ScriptCompilationException(script, "Cannot access script for ScriptEngine", ex); } catch (ScriptException ex) { throw new ScriptCompilationException(script, new StandardScriptEvalException(ex)); } } /** * Obtain the JSR-223 ScriptEngine to use for the given script. * @param script the script to evaluate * @return the ScriptEngine (never {@code null}) */ protected ScriptEngine getScriptEngine(ScriptSource script) { ScriptEngineManager scriptEngineManager = this.scriptEngineManager; if (scriptEngineManager == null) { scriptEngineManager = new ScriptEngineManager(); this.scriptEngineManager = scriptEngineManager; } if (StringUtils.hasText(this.engineName)) { return StandardScriptUtils.retrieveEngineByName(scriptEngineManager, this.engineName); } else if (script instanceof ResourceScriptSource) { Resource resource = ((ResourceScriptSource) script).getResource(); String extension = StringUtils.getFilenameExtension(resource.getFilename()); if (extension == null) { throw new IllegalStateException( "No script language defined, and no file extension defined for resource: " + resource); } ScriptEngine engine = scriptEngineManager.getEngineByExtension(extension); if (engine == null) { throw new IllegalStateException("No matching engine found for file extension '" + extension + "'"); } return engine; } else { throw new IllegalStateException( "No script language defined, and no resource associated with script: " + script); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy