]> git.basschouten.com Git - openhab-addons.git/commitdiff
[jrubyscripting] Inject `ctx` in compiled scripts (#17140)
authorjimtng <2554958+jimtng@users.noreply.github.com>
Thu, 25 Jul 2024 20:09:48 +0000 (06:09 +1000)
committerGitHub <noreply@github.com>
Thu, 25 Jul 2024 20:09:48 +0000 (22:09 +0200)
Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
bundles/org.openhab.automation.jrubyscripting/src/main/java/org/openhab/automation/jrubyscripting/internal/JRubyCompiledScriptWrapper.java [new file with mode: 0644]
bundles/org.openhab.automation.jrubyscripting/src/main/java/org/openhab/automation/jrubyscripting/internal/JRubyEngineWrapper.java

diff --git a/bundles/org.openhab.automation.jrubyscripting/src/main/java/org/openhab/automation/jrubyscripting/internal/JRubyCompiledScriptWrapper.java b/bundles/org.openhab.automation.jrubyscripting/src/main/java/org/openhab/automation/jrubyscripting/internal/JRubyCompiledScriptWrapper.java
new file mode 100644 (file)
index 0000000..82397d8
--- /dev/null
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.automation.jrubyscripting.internal;
+
+import java.util.Objects;
+
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * This is a wrapper for {@link CompiledScript}.
+ * 
+ * The purpose of this class is to intercept the call to eval and save the context into
+ * a global variable for use in the helper library.
+ *
+ * @author Jimmy Tanagra - Initial contribution
+ */
+@NonNullByDefault
+public class JRubyCompiledScriptWrapper extends CompiledScript {
+
+    private final CompiledScript compiledScript;
+
+    private static final String CONTEXT_VAR_NAME = "ctx";
+    private static final String GLOBAL_VAR_NAME = "$" + CONTEXT_VAR_NAME;
+
+    JRubyCompiledScriptWrapper(CompiledScript compiledScript) {
+        this.compiledScript = Objects.requireNonNull(compiledScript);
+    }
+
+    @Override
+    public Object eval(@Nullable ScriptContext context) throws ScriptException {
+        Object ctx = Objects.requireNonNull(context).getBindings(ScriptContext.ENGINE_SCOPE).get(CONTEXT_VAR_NAME);
+        if (ctx == null) {
+            return compiledScript.eval(context);
+        }
+
+        context.setAttribute(GLOBAL_VAR_NAME, ctx, ScriptContext.ENGINE_SCOPE);
+        try {
+            return compiledScript.eval(context);
+        } finally {
+            context.removeAttribute(GLOBAL_VAR_NAME, ScriptContext.ENGINE_SCOPE);
+        }
+    }
+
+    @Override
+    public ScriptEngine getEngine() {
+        return compiledScript.getEngine();
+    }
+}
index 7b6770fb9403727da28de38f46f90f95fb77ca48..07d13577c7f6cdd252cf1563ccabcfd359c70f3c 100644 (file)
@@ -50,12 +50,12 @@ public class JRubyEngineWrapper implements Compilable, Invocable, ScriptEngine {
 
     @Override
     public CompiledScript compile(@Nullable String script) throws ScriptException {
-        return engine.compile(script);
+        return new JRubyCompiledScriptWrapper(engine.compile(script));
     }
 
     @Override
     public CompiledScript compile(@Nullable Reader reader) throws ScriptException {
-        return engine.compile(reader);
+        return new JRubyCompiledScriptWrapper(engine.compile(reader));
     }
 
     @Override