mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 23:22:02 +01:00
[jsscripting] Implement javax.script.Compilable
(#16970)
* [jsscripting] Restructure & Comment POM * [jsscripting] Use OPENHAB_TRANSFORMATION_SCRIPT constant from core Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
This commit is contained in:
parent
ef3ffff2bc
commit
e69fd47ef2
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<!-- exclude META-INF/services/com.oracle.truffle.api.TruffleLanguage$Provider when unpacking dependencies -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
@ -42,6 +43,7 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!-- bundle the openhab-js library -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.github.eirslett</groupId>
|
<groupId>com.github.eirslett</groupId>
|
||||||
<artifactId>frontend-maven-plugin</artifactId>
|
<artifactId>frontend-maven-plugin</artifactId>
|
||||||
@ -112,6 +114,7 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<!-- run SAT -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.openhab.tools.sat</groupId>
|
<groupId>org.openhab.tools.sat</groupId>
|
||||||
<artifactId>sat-plugin</artifactId>
|
<artifactId>sat-plugin</artifactId>
|
||||||
@ -123,32 +126,33 @@
|
|||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>org.graalvm.truffle</groupId>
|
|
||||||
<artifactId>truffle-api</artifactId>
|
|
||||||
<version>${graal.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.graalvm.js</groupId>
|
|
||||||
<artifactId>js-scriptengine</artifactId>
|
|
||||||
<version>${graal.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.graalvm.sdk</groupId>
|
<groupId>org.graalvm.sdk</groupId>
|
||||||
<artifactId>graal-sdk</artifactId>
|
<artifactId>graal-sdk</artifactId>
|
||||||
<version>${graal.version}</version>
|
<version>${graal.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.graalvm.truffle</groupId>
|
||||||
|
<artifactId>truffle-api</artifactId>
|
||||||
|
<version>${graal.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Graal JavaScript ScriptEngine JSR 223 support -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.graalvm.js</groupId>
|
||||||
|
<artifactId>js-scriptengine</artifactId>
|
||||||
|
<version>${graal.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Graal TRegex engine (internally used by Graal JavaScript engine) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.graalvm.regex</groupId>
|
<groupId>org.graalvm.regex</groupId>
|
||||||
<artifactId>regex</artifactId>
|
<artifactId>regex</artifactId>
|
||||||
<version>${graal.version}</version>
|
<version>${graal.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency> <!-- this must come AFTER the regex lib -->
|
<!-- Graal JavaScript engine (depends on Graal TRegex engine, must be added after it) -->
|
||||||
|
<dependency>
|
||||||
<groupId>org.graalvm.js</groupId>
|
<groupId>org.graalvm.js</groupId>
|
||||||
<artifactId>js</artifactId>
|
<artifactId>js</artifactId>
|
||||||
<version>${graal.version}</version>
|
<version>${graal.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- GraalJS changelog says that com.ibm.icu/icu4j is not required for GraalJS >= 22.0.0 as it moved to org.graalvm.truffle;
|
|
||||||
but GraalJS >= 22.2.0 requires it, so we'll need to add it when we upgrade -->
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -12,16 +12,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.automation.jsscripting.internal;
|
package org.openhab.automation.jsscripting.internal;
|
||||||
|
|
||||||
|
import static org.openhab.core.automation.module.script.ScriptTransformationService.OPENHAB_TRANSFORMATION_SCRIPT;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.script.Compilable;
|
||||||
import javax.script.Invocable;
|
import javax.script.Invocable;
|
||||||
import javax.script.ScriptContext;
|
import javax.script.ScriptContext;
|
||||||
import javax.script.ScriptEngine;
|
import javax.script.ScriptEngine;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.graalvm.polyglot.PolyglotException;
|
import org.graalvm.polyglot.PolyglotException;
|
||||||
import org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable;
|
import org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndCompilableAndAutoCloseable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -31,10 +34,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @author Jonathan Gilbert - Initial contribution
|
* @author Jonathan Gilbert - Initial contribution
|
||||||
* @author Florian Hotze - Improve logger name, Fix memory leak caused by exception logging
|
* @author Florian Hotze - Improve logger name, Fix memory leak caused by exception logging
|
||||||
*/
|
*/
|
||||||
class DebuggingGraalScriptEngine<T extends ScriptEngine & Invocable & AutoCloseable>
|
class DebuggingGraalScriptEngine<T extends ScriptEngine & Invocable & AutoCloseable & Compilable>
|
||||||
extends InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable<T> {
|
extends InvocationInterceptingScriptEngineWithInvocableAndCompilableAndAutoCloseable<T> {
|
||||||
|
|
||||||
private static final String SCRIPT_TRANSFORMATION_ENGINE_IDENTIFIER = "openhab-transformation-script-";
|
|
||||||
private static final int STACK_TRACE_LENGTH = 5;
|
private static final int STACK_TRACE_LENGTH = 5;
|
||||||
|
|
||||||
private @Nullable Logger logger;
|
private @Nullable Logger logger;
|
||||||
@ -91,9 +93,8 @@ class DebuggingGraalScriptEngine<T extends ScriptEngine & Invocable & AutoClosea
|
|||||||
} else if (ruleUID != null) {
|
} else if (ruleUID != null) {
|
||||||
identifier = ruleUID.toString();
|
identifier = ruleUID.toString();
|
||||||
} else if (ohEngineIdentifier != null) {
|
} else if (ohEngineIdentifier != null) {
|
||||||
if (ohEngineIdentifier.toString().startsWith(SCRIPT_TRANSFORMATION_ENGINE_IDENTIFIER)) {
|
if (ohEngineIdentifier.toString().startsWith(OPENHAB_TRANSFORMATION_SCRIPT)) {
|
||||||
identifier = ohEngineIdentifier.toString().replaceAll(SCRIPT_TRANSFORMATION_ENGINE_IDENTIFIER,
|
identifier = ohEngineIdentifier.toString().replaceAll(OPENHAB_TRANSFORMATION_SCRIPT, "transformation.");
|
||||||
"transformation.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ import org.openhab.automation.jsscripting.internal.fs.DelegatingFileSystem;
|
|||||||
import org.openhab.automation.jsscripting.internal.fs.PrefixedSeekableByteChannel;
|
import org.openhab.automation.jsscripting.internal.fs.PrefixedSeekableByteChannel;
|
||||||
import org.openhab.automation.jsscripting.internal.fs.ReadOnlySeekableByteArrayChannel;
|
import org.openhab.automation.jsscripting.internal.fs.ReadOnlySeekableByteArrayChannel;
|
||||||
import org.openhab.automation.jsscripting.internal.fs.watch.JSDependencyTracker;
|
import org.openhab.automation.jsscripting.internal.fs.watch.JSDependencyTracker;
|
||||||
import org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable;
|
import org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndCompilableAndAutoCloseable;
|
||||||
import org.openhab.core.automation.module.script.ScriptExtensionAccessor;
|
import org.openhab.core.automation.module.script.ScriptExtensionAccessor;
|
||||||
import org.openhab.core.items.Item;
|
import org.openhab.core.items.Item;
|
||||||
import org.openhab.core.library.types.QuantityType;
|
import org.openhab.core.library.types.QuantityType;
|
||||||
@ -69,7 +69,7 @@ import com.oracle.truffle.js.scriptengine.GraalJSScriptEngine;
|
|||||||
* {@link Lock} for multi-thread synchronization; globals and openhab-js injection code caching
|
* {@link Lock} for multi-thread synchronization; globals and openhab-js injection code caching
|
||||||
*/
|
*/
|
||||||
public class OpenhabGraalJSScriptEngine
|
public class OpenhabGraalJSScriptEngine
|
||||||
extends InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable<GraalJSScriptEngine> {
|
extends InvocationInterceptingScriptEngineWithInvocableAndCompilableAndAutoCloseable<GraalJSScriptEngine> {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(OpenhabGraalJSScriptEngine.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(OpenhabGraalJSScriptEngine.class);
|
||||||
private static final Source GLOBAL_SOURCE;
|
private static final Source GLOBAL_SOURCE;
|
||||||
|
@ -15,6 +15,8 @@ package org.openhab.automation.jsscripting.internal.scriptengine;
|
|||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
|
||||||
import javax.script.Bindings;
|
import javax.script.Bindings;
|
||||||
|
import javax.script.Compilable;
|
||||||
|
import javax.script.CompiledScript;
|
||||||
import javax.script.Invocable;
|
import javax.script.Invocable;
|
||||||
import javax.script.ScriptContext;
|
import javax.script.ScriptContext;
|
||||||
import javax.script.ScriptEngine;
|
import javax.script.ScriptEngine;
|
||||||
@ -29,11 +31,11 @@ import org.eclipse.jdt.annotation.NonNull;
|
|||||||
*
|
*
|
||||||
* @author Jonathan Gilbert - Initial contribution
|
* @author Jonathan Gilbert - Initial contribution
|
||||||
*/
|
*/
|
||||||
public abstract class DelegatingScriptEngineWithInvocableAndAutocloseable<T extends ScriptEngine & Invocable & AutoCloseable>
|
public abstract class DelegatingScriptEngineWithInvocableAndCompilableAndAutocloseable<T extends ScriptEngine & Invocable & Compilable & AutoCloseable>
|
||||||
implements ScriptEngine, Invocable, AutoCloseable {
|
implements ScriptEngine, Invocable, Compilable, AutoCloseable {
|
||||||
protected @NonNull T delegate;
|
protected @NonNull T delegate;
|
||||||
|
|
||||||
public DelegatingScriptEngineWithInvocableAndAutocloseable(@NonNull T delegate) {
|
public DelegatingScriptEngineWithInvocableAndCompilableAndAutocloseable(@NonNull T delegate) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,6 +130,16 @@ public abstract class DelegatingScriptEngineWithInvocableAndAutocloseable<T exte
|
|||||||
return delegate.getInterface(o, aClass);
|
return delegate.getInterface(o, aClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompiledScript compile(String s) throws ScriptException {
|
||||||
|
return delegate.compile(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompiledScript compile(Reader reader) throws ScriptException {
|
||||||
|
return delegate.compile(reader);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
delegate.close();
|
delegate.close();
|
@ -16,22 +16,24 @@ import java.io.Reader;
|
|||||||
import java.lang.reflect.UndeclaredThrowableException;
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
|
|
||||||
import javax.script.Bindings;
|
import javax.script.Bindings;
|
||||||
|
import javax.script.Compilable;
|
||||||
|
import javax.script.CompiledScript;
|
||||||
import javax.script.Invocable;
|
import javax.script.Invocable;
|
||||||
import javax.script.ScriptContext;
|
import javax.script.ScriptContext;
|
||||||
import javax.script.ScriptEngine;
|
import javax.script.ScriptEngine;
|
||||||
import javax.script.ScriptException;
|
import javax.script.ScriptException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegate allowing AOP-style interception of calls, either before Invocation, or upon a {@link ScriptException}.
|
* Delegate allowing AOP-style interception of calls, either before Invocation, or upon a {@link ScriptException} being
|
||||||
* being thrown.
|
* thrown.
|
||||||
*
|
*
|
||||||
* @param <T> The delegate class
|
* @param <T> The delegate class
|
||||||
* @author Jonathan Gilbert - Initial contribution
|
* @author Jonathan Gilbert - Initial contribution
|
||||||
*/
|
*/
|
||||||
public abstract class InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable<T extends ScriptEngine & Invocable & AutoCloseable>
|
public abstract class InvocationInterceptingScriptEngineWithInvocableAndCompilableAndAutoCloseable<T extends ScriptEngine & Invocable & Compilable & AutoCloseable>
|
||||||
extends DelegatingScriptEngineWithInvocableAndAutocloseable<T> {
|
extends DelegatingScriptEngineWithInvocableAndCompilableAndAutocloseable<T> {
|
||||||
|
|
||||||
public InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable(T delegate) {
|
public InvocationInterceptingScriptEngineWithInvocableAndCompilableAndAutoCloseable(T delegate) {
|
||||||
super(delegate);
|
super(delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,4 +157,28 @@ public abstract class InvocationInterceptingScriptEngineWithInvocableAndAutoClos
|
|||||||
throw new UndeclaredThrowableException(afterThrowsInvocation(e)); // Wrap and rethrow other exceptions
|
throw new UndeclaredThrowableException(afterThrowsInvocation(e)); // Wrap and rethrow other exceptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompiledScript compile(String s) throws ScriptException {
|
||||||
|
try {
|
||||||
|
beforeInvocation();
|
||||||
|
return (CompiledScript) afterInvocation(super.compile(s));
|
||||||
|
} catch (ScriptException se) {
|
||||||
|
throw (ScriptException) afterThrowsInvocation(se);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(afterThrowsInvocation(e)); // Wrap and rethrow other exceptions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompiledScript compile(Reader reader) throws ScriptException {
|
||||||
|
try {
|
||||||
|
beforeInvocation();
|
||||||
|
return (CompiledScript) afterInvocation(super.compile(reader));
|
||||||
|
} catch (ScriptException se) {
|
||||||
|
throw (ScriptException) afterThrowsInvocation(se);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(afterThrowsInvocation(e)); // Wrap and rethrow other exceptions
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,3 +1,3 @@
|
|||||||
# Please check here how to add suppressions https://maven.apache.org/plugins/maven-pmd-plugin/examples/violation-exclusions.html
|
# Please check here how to add suppressions https://maven.apache.org/plugins/maven-pmd-plugin/examples/violation-exclusions.html
|
||||||
org.openhab.automation.jsscripting.internal.OpenhabGraalJSScriptEngine=UnusedPrivateField
|
org.openhab.automation.jsscripting.internal.OpenhabGraalJSScriptEngine=UnusedPrivateField
|
||||||
org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable=AvoidThrowingNullPointerException,AvoidCatchingNPE
|
org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndCompilableAndAutoCloseable=AvoidThrowingNullPointerException,AvoidCatchingNPE
|
||||||
|
Loading…
Reference in New Issue
Block a user