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

javax0.jamal.tools.ScriptingTools Maven / Gradle / Ivy

package javax0.jamal.tools;

import javax0.jamal.api.BadSyntax;
import javax0.jamal.api.JShellEngine;

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

/**
 * Utility class containing static methods handling scripting. Scripting is handled through the JSR223 defined interface
 * and no interpreter specific API is used, thus the scripts can be written in any scripting implementation that is on
 * the classpath runtime.
 */
public class ScriptingTools {


    /**
     * Populate the scripting engine with the key/value pair. This means that the global variable that has the name
     * specified in the parameter {@code key} will have the value specified in the parameter {@code value}.
     * 

* If the string given in the parameter {@code value} can be interpreted as an integer then the population converts * the value to {@code Integer}. If the string can be interpreted as a floating point number then it will be * converted to a {@code Double}. If the value if {@code "true"} (any case, even mixed case) then the value will be * {@code Boolean} {@code true}. Likewise if the value is {@code "false"} then it is converted to {@code false}. *

* In any other cases the string is stored and assigned to the global variable. * * @param engine that stores the global variables for later execution * @param key the name of the global variable * @param value the value to be assigned to the global variable */ public static void populate(ScriptEngine engine, String key, String value) { try { engine.put(key, Long.parseLong(value)); return; } catch (NumberFormatException ignored) { } try { engine.put(key, Double.parseDouble(value)); return; } catch (NumberFormatException ignored) { } if ("true".equalsIgnoreCase(value)) { engine.put(key, true); return; } if ("false".equalsIgnoreCase(value)) { engine.put(key, false); return; } engine.put(key, value); } public static void populateJShell(JShellEngine engine, String key, String value) throws BadSyntax { try { engine.define("long " + key + "= " + Long.parseLong(value) + ";"); return; } catch (NumberFormatException ignored) { } try { engine.define("double " + key + "= " + Double.parseDouble(value) + ";"); return; } catch (NumberFormatException ignored) { } if ("true".equalsIgnoreCase(value)) { engine.define("boolean " + key + "= true;"); return; } if ("false".equalsIgnoreCase(value)) { engine.define("boolean " + key + "= false;"); return; } engine.define("String " + key + "= \"" + escape(value) + "\";"); } private static String escape(String s) { return s.replaceAll("\\\\", "\\\\\\\\").replaceAll("\n", "\\\\n").replaceAll("\"", "\\\\\""); } public static String unescape(String s) { return s.substring(1, s.length() - 1).replaceAll("\\\\\"", "\"").replaceAll("\\\\n", "\n").replaceAll("\\\\\\\\", "\\\\"); } /** * Return the string representation of the object. If the object is a {@code Double} then the trailing {@code .0} is * chopped off. This is to help the macro evaluation and use in case the scripting implementation returns a {@code * Double} even for integer values. * * @param obj to convert to string * @return the converted string */ public static String resultToString(Object obj) { if (obj instanceof Double) { return obj.toString().replaceAll(".0$", ""); } return obj.toString(); } /** * Get the scripting engine based on the name of the script type e.g.: {@code JavaScript}. * * @param scriptType the name of the scripting language * @return the engine for the specified script type * @throws BadSyntax when there is no scripting engine with the given name */ public static ScriptEngine getEngine(String scriptType) throws BadSyntax { final var engine = new ScriptEngineManager().getEngineByName(scriptType); BadSyntax.when(engine == null, "There is no script engine named '%s'", scriptType); return engine; } /** * Evaluate the content using the scripting engine. * * @param engine to be used to execute the evaluation * @param content the program code to be evaluated * @return the result of the evaluation * @throws ScriptException when there is an error executing the script */ public static Object evaluate(ScriptEngine engine, String content) throws ScriptException { return engine.eval(content); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy