Skip to content

Commit

Permalink
[jsscriptingnashorn] JavaScript Scripting Nashorn Automation (openhab…
Browse files Browse the repository at this point in the history
…#14013)

* [jsscriptingnashorn] JavaScript Scripting Nashorn Automation

This add-on allows you to use your older JavaScript (ECMAScript 5.1) rules on newer Java versions until they are migrated to JavaScript (ECMAScript 2021+).
The add-on uses a standalone [Nashorn Engine](https://github.com/openjdk/nashorn) which was part of Java until it was removed in Java 15.

* Update parent to 3.4.0-SNAPSHOT and nashorn-core to 15.4

For the Nashorn changelog, see:

https://github.com/openjdk/nashorn/blob/main/CHANGELOG.md

* Update parent to 4.0.0-SNAPSHOT
* Remove removeUnsupportedNashornArgs
* Update scriptTypes
* Add CODEOWNERS entry
* Recycle ScriptScopeOSGiTest.java

It got removed in openhab/openhab-core#2994

* Remove redundant new line from pom.xml

Signed-off-by: Wouter Born <[email protected]>
  • Loading branch information
wborn authored Dec 26, 2022
1 parent 605574b commit 88c0b72
Show file tree
Hide file tree
Showing 17 changed files with 652 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/bundles/org.openhab.automation.groovyscripting/ @wborn
/bundles/org.openhab.automation.jrubyscripting/ @boc-tothefuture @ccutrer @jimtng
/bundles/org.openhab.automation.jsscripting/ @jpg0 @florian-h05
/bundles/org.openhab.automation.jsscriptingnashorn/ @wborn
/bundles/org.openhab.automation.jythonscripting/ @openhab/add-ons-maintainers
/bundles/org.openhab.automation.pidcontroller/ @fwolter
/bundles/org.openhab.automation.pwm/ @fwolter
Expand Down Expand Up @@ -414,6 +415,7 @@
/bundles/org.openhab.voice.voicerss/ @JochenHiller @lolodomo
/bundles/org.openhab.voice.voskstt/ @GiviMAD
/bundles/org.openhab.voice.watsonstt/ @GiviMAD
/itests/org.openhab.automation.jsscriptingnashorn.tests/ @wborn
/itests/org.openhab.binding.astro.tests/ @gerrieg
/itests/org.openhab.binding.avmfritz.tests/ @cweitkamp
/itests/org.openhab.binding.feed.tests/ @svilenvul
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
<artifactId>org.openhab.automation.jsscripting</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.jsscriptingnashorn</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.jythonscripting</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.automation.jsscriptingnashorn/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-addons
49 changes: 49 additions & 0 deletions bundles/org.openhab.automation.jsscriptingnashorn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# JavaScript Scripting (Nashorn)

This add-on allows you to use your older ECMAScript 5.1 code on newer Java versions until the code is migrated to ECMAScript 2021+.
It should only be installed for providing backwards compatibility.
When writing new code it is preferred to do this using ECMAScript 2021+ for which support is provided by installing the [JavaScript Scripting](https://www.openhab.org/addons/automation/jsscripting/) add-on.

This add-on uses a standalone [Nashorn Engine](https://github.com/openjdk/nashorn) to run ECMAScript 5.1 code.
The Nashorn Engine was pre-installed in openHAB 2 and openHAB 3 because it was part of Java.
Since Java 15 the Nashorn Engine has been removed from Java.

## Creating JavaScript Scripts

When this add-on is installed, JavaScript script actions will be run by this add-on and allow ECMAScript 5.1 features.

Alternatively, you can create scripts in the `automation/jsr223` configuration directory.
If you create an empty file called `test.nashornjs`, you will see a log line with information similar to:

```text
... [INFO ] [.a.m.s.r.i.l.ScriptFileWatcher:150 ] - Loading script 'test.nashornjs'
```

To enable debug logging, use the [console logging]({{base}}/administration/logging.html) commands to enable debug logging for the automation functionality:

```text
log:set DEBUG org.openhab.core.automation
```

For more information on the available APIs in scripts see the [JSR223 Scripting]({{base}}/configuration/jsr223.html) documentation.

## Script Examples

JavaScript scripts provide access to almost all the functionality in an openHAB runtime environment.
As a simple example, the following script logs "Hello, World!".
Note that `console.log` will usually not work since the output has no terminal to display the text.
The openHAB server uses the [SLF4J](https://www.slf4j.org/) library for logging.

```js
var LoggerFactory = Java.type('org.slf4j.LoggerFactory');

LoggerFactory.getLogger("org.openhab.core.automation.examples").info("Hello, World!");
```

Depending on the openHAB logging configuration, you may need to prefix logger names with `org.openhab.core.automation` for them to show up in the log file (or you modify the logging configuration).

The script uses the [LoggerFactory](https://www.slf4j.org/apidocs/org/slf4j/Logger.html) to obtain a named logger and then logs a message like:

```text
... [INFO ] [org.openhab.core.automation.examples ] - Hello, World!
```
56 changes: 56 additions & 0 deletions bundles/org.openhab.automation.jsscriptingnashorn/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>4.0.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.automation.jsscriptingnashorn</artifactId>

<name>openHAB Add-ons :: Bundles :: Automation :: JavaScript Scripting (Nashorn)</name>

<properties>
<bnd.importpackage>jdk.dynalink.*;resolution:=optional</bnd.importpackage>
<asm.version>7.3.1</asm.version>
</properties>

<dependencies>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>15.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-analysis</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-tree</artifactId>
<version>${asm.version}</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-util</artifactId>
<version>${asm.version}</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.automation.jsscriptingnashorn-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

<feature name="openhab-automation-jsscriptingnashorn" description="JavaScript Scripting (Nashorn)" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.automation.jsscriptingnashorn/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Copyright (c) 2010-2022 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.jsscriptingnashorn.internal;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

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

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.module.script.AbstractScriptEngineFactory;
import org.openhab.core.automation.module.script.ScriptEngineFactory;
import org.osgi.service.component.annotations.Component;

/**
* This is an implementation of a {@link ScriptEngineFactory} for Nashorn.
*
* @author Wouter Born - Initial contribution
*/
@Component(service = ScriptEngineFactory.class)
@NonNullByDefault
public class NashornScriptEngineFactory extends AbstractScriptEngineFactory {

private final org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory factory = new org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory();

private final List<String> scriptTypes = createScriptTypes();

private List<String> createScriptTypes() {
List<String> extensions = List.of("nashornjs");

String mimeTypeVersion = ";version=ECMAScript-5.1";
List<String> mimeTypes = factory.getMimeTypes().stream().map(mimeType -> mimeType + mimeTypeVersion)
.collect(Collectors.toUnmodifiableList());

return Stream.of(extensions, mimeTypes).flatMap(List::stream).collect(Collectors.toUnmodifiableList());
}

@Override
public List<String> getScriptTypes() {
return scriptTypes;
}

@Override
public void scopeValues(ScriptEngine scriptEngine, Map<String, Object> scopeValues) {
Set<String> expressions = new HashSet<>();

for (Entry<String, Object> entry : scopeValues.entrySet()) {
scriptEngine.put(entry.getKey(), entry.getValue());
if (entry.getValue() instanceof Class) {
expressions.add(String.format("%s = %<s.static;", entry.getKey()));
}
}
String scriptToEval = String.join("\n", expressions);
try {
scriptEngine.eval(scriptToEval);
} catch (ScriptException ex) {
logger.error("ScriptException while importing scope: {}", ex.getMessage());
}
}

@Override
public @Nullable ScriptEngine createScriptEngine(String scriptType) {
return scriptTypes.contains(scriptType)
? factory.getScriptEngine(NashornScriptEngineFactory.class.getClassLoader())
: null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright (c) 2010-2022 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
*/
@org.osgi.annotation.bundle.Header(name = org.osgi.framework.Constants.DYNAMICIMPORT_PACKAGE, value = "*")
package org.openhab.automation.jsscriptingnashorn.internal;

/**
* Additional information for the JavaScript Scripting Nashorn package
*
* @author Wouter Born - Initial contribution
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2010-2022 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.jsscriptingnashorn;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;

import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
import org.openhab.automation.jsscriptingnashorn.internal.NashornScriptEngineFactory;

/**
* Tests {@link NashornScriptEngineFactory}.
*
* @author Wouter Born - Initial contribution
*/
@NonNullByDefault
public class NashornScriptEngineFactoryTest {

@Test
public void scriptTypesAreNashornSpecific() {
List<String> scriptTypes = new NashornScriptEngineFactory().getScriptTypes();

assertThat(scriptTypes,
contains("nashornjs", "application/javascript;version=ECMAScript-5.1",
"application/ecmascript;version=ECMAScript-5.1", "text/javascript;version=ECMAScript-5.1",
"text/ecmascript;version=ECMAScript-5.1"));
assertThat(scriptTypes.size(), is(5));
}
}
1 change: 1 addition & 0 deletions bundles/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<module>org.openhab.automation.groovyscripting</module>
<module>org.openhab.automation.jrubyscripting</module>
<module>org.openhab.automation.jsscripting</module>
<module>org.openhab.automation.jsscriptingnashorn</module>
<module>org.openhab.automation.jythonscripting</module>
<module>org.openhab.automation.pidcontroller</module>
<module>org.openhab.automation.pwm</module>
Expand Down
13 changes: 13 additions & 0 deletions itests/org.openhab.automation.jsscriptingnashorn.tests/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-addons
Loading

0 comments on commit 88c0b72

Please sign in to comment.