Skip to content

Commit

Permalink
Add Jython Scripting (openhab#9404)
Browse files Browse the repository at this point in the history
* Add Jython Scripting

Also-by: Scott Rushworth <openhab@5iver.com>
Signed-off-by: Wouter Born <github@maindrain.net>
  • Loading branch information
wborn authored and seaside1 committed Dec 28, 2020
1 parent 94d7b11 commit 997f59f
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 1 deletion.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

# Add-on maintainers:
/bundles/org.openhab.automation.groovyscripting/ @wborn
/bundles/org.openhab.automation.jythonscripting/ @openhab/add-ons-maintainers
/bundles/org.openhab.binding.adorne/ @theiding
/bundles/org.openhab.binding.airquality/ @kubawolanin
/bundles/org.openhab.binding.airvisualnode/ @3cky
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 @@ -21,6 +21,11 @@
<artifactId>org.openhab.automation.groovyscripting</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.automation.jythonscripting</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.adorne</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.automation.jythonscripting/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
5 changes: 5 additions & 0 deletions bundles/org.openhab.automation.jythonscripting/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Jython Scripting

This addon provides a [Jython](https://www.jython.org/) 2.7.2 for use with scripted automation and eliminates the need to download Jython and create `EXTRA_JAVA_OPTS` entries for `bootclasspath`, `python.home` and `python.path`.
The `python.home` System property will be set to the path of the add-on.
The `python.path` System property will be set to `$OPENHAB_CONF/automation/lib/python`, but any existing `python.path` will be appended to it.
31 changes: 31 additions & 0 deletions bundles/org.openhab.automation.jythonscripting/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?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 http://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>3.0.0-SNAPSHOT</version>
</parent>

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

<name>openHAB Add-ons :: Automation :: Jython Scripting</name>

<properties>
<bnd.fixupmessages><![CDATA["Classes found in the wrong directory","The default package '.' is not permitted by the Import-Package syntax"; restrict:=error; is:=warning]]></bnd.fixupmessages>
<bnd.importpackage>*blockhound*;resolution:=optional,com.cloudius.util;resolution:=optional,com.github.luben.zstd;resolution:=optional,com.informix.jdbc;resolution:=optional,com.jcraft.jzlib;resolution:=optional,com.ning.compress.*;resolution:=optional,com.oracle.svm.core.annotate;resolution:=optional,com.sun.management;resolution:=optional,custom_proxymaker.tests;resolution:=optional,jnr.*;resolution;resolution:=optional,*jpountz*;resolution:=optional,junit.framework;resolution:=optional,lzma.sdk.*;resolution:=optional,oracle.*;resolution:=optional,org.antlr.stringtemplate;resolution:=optional,org.apache.tools.*;resolution:=optional,org.brotli.dec;resolution:=optional,org.checkerframework.*;resolution:=optional,org.conscrypt;resolution:=optional,org.eclipse.jetty.*;resolution:=optional,org.hamcrest;resolution:=optional,org.jboss.marshalling;resolution:=optional,org.junit.*;resolution:=optional,org.python.apache.xml.resolver.*;resolution:=optional,org.python.google.*;resolution:=optional,org.python.netty.internal.tcnative;resolution:=optional,org.python.objectweb.asm.tree.*;resolution:=optional,org.python.proxies;resolution:=optional,org.tukaani.xz;resolution:=optional,sun.*;resolution:=optional</bnd.importpackage>
</properties>

<dependencies>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.2</version>
<scope>compile</scope>
</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.jythonscripting-${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-jythonscripting" description="Jython Scripting" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.automation.jythonscripting/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* Copyright (c) 2010-2020 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.jythonscripting;

import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.script.ScriptEngine;

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

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

private static final String PYTHON_CACHEDIR = "python.cachedir";
private static final String PYTHON_HOME = "python.home";
private static final String PYTHON_PATH = "python.path";

private static final String DEFAULT_PYTHON_PATH = Paths
.get(OpenHAB.getConfigFolder(), "automation", "lib", "python").toString();

private static final String SCRIPT_TYPE = "py";
private static final javax.script.ScriptEngineManager ENGINE_MANAGER = new javax.script.ScriptEngineManager();

@Activate
public JythonScriptEngineFactory() {
logger.debug("Loading JythonScriptEngineFactory");

String pythonHome = JythonScriptEngineFactory.class.getProtectionDomain().getCodeSource().getLocation()
.toString().replace("file:", "");
System.setProperty(PYTHON_HOME, pythonHome);

String existingPythonPath = System.getProperty(PYTHON_PATH);
if (existingPythonPath == null || existingPythonPath.isEmpty()) {
System.setProperty(PYTHON_PATH, DEFAULT_PYTHON_PATH);
} else if (!existingPythonPath.contains(DEFAULT_PYTHON_PATH)) {
Set<String> newPythonPathList = new TreeSet<>(Arrays.asList(existingPythonPath.split(File.pathSeparator)));
newPythonPathList.add(DEFAULT_PYTHON_PATH);
System.setProperty(PYTHON_PATH, String.join(File.pathSeparator, newPythonPathList));
}

System.setProperty(PYTHON_CACHEDIR, Paths
.get(OpenHAB.getUserDataFolder(), "cache", JythonScriptEngineFactory.class.getPackageName(), "cachedir")
.toString());

logPythonPaths();
}

private void logPythonPaths() {
logger.trace("{}: {}, {}: {}, {}: {}", //
PYTHON_HOME, System.getProperty(PYTHON_HOME), //
PYTHON_PATH, System.getProperty(PYTHON_PATH), //
PYTHON_CACHEDIR, System.getProperty(PYTHON_CACHEDIR));
}

@Override
public List<String> getScriptTypes() {
List<String> scriptTypes = new ArrayList<>();

for (javax.script.ScriptEngineFactory factory : ENGINE_MANAGER.getEngineFactories()) {
List<String> extensions = factory.getExtensions();

if (extensions.contains(SCRIPT_TYPE)) {
scriptTypes.addAll(extensions);
scriptTypes.addAll(factory.getMimeTypes());
}
}
return scriptTypes;
}

@Override
public @Nullable ScriptEngine createScriptEngine(String scriptType) {
ScriptEngine scriptEngine = ENGINE_MANAGER.getEngineByExtension(scriptType);
if (scriptEngine == null) {
scriptEngine = ENGINE_MANAGER.getEngineByMimeType(scriptType);
}
if (scriptEngine == null) {
scriptEngine = ENGINE_MANAGER.getEngineByName(scriptType);
}
return scriptEngine;
}

@Deactivate
public void removePythonPath() {
logger.debug("Unloading JythonScriptEngineFactory");

String existingPythonPath = System.getProperty(PYTHON_PATH);
if (existingPythonPath != null && existingPythonPath.contains(DEFAULT_PYTHON_PATH)) {
Set<String> newPythonPathList = new TreeSet<>(Arrays.asList(existingPythonPath.split(File.pathSeparator)));
newPythonPathList.remove(DEFAULT_PYTHON_PATH);
System.setProperty(PYTHON_PATH, String.join(File.pathSeparator, newPythonPathList));
}

System.clearProperty(PYTHON_HOME);
System.clearProperty(PYTHON_CACHEDIR);

logPythonPaths();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (c) 2010-2020 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.jythonscripting;

/**
* Additional information for the Jython Scripting package
*
* @author Wouter Born - Initial contribution
*/
1 change: 1 addition & 0 deletions bundles/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<modules>
<!-- automation -->
<module>org.openhab.automation.groovyscripting</module>
<module>org.openhab.automation.jythonscripting</module>
<!-- io -->
<module>org.openhab.io.homekit</module>
<module>org.openhab.io.hueemulation</module>
Expand Down
4 changes: 3 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@

<bnd.importpackage/>
<bnd.exportpackage/>
<bnd.fixupmessages/>
<bnd.includeresource>-${.}/NOTICE, -${.}/*.xsd</bnd.includeresource>

<feature.directory>src/main/feature/feature.xml</feature.directory>
Expand Down Expand Up @@ -153,7 +154,8 @@ Import-Package: \\
${bnd.exportpackage}
-sources: false
-contract: *
-includeresource: ${bnd.includeresource}]]></bnd>
-includeresource: ${bnd.includeresource}
-fixupmessages: ${bnd.fixupmessages}]]></bnd>
<!-- -dsannotations-options: norequirements -->
<!-- Bundle-SymbolicName: ${project.groupId}.${project.artifactId} -->
</configuration>
Expand Down

0 comments on commit 997f59f

Please sign in to comment.