Skip to content

Commit e857f32

Browse files
authored
[jythonscripting] Refactor, improve and simplify (openhab#16508)
* moved implementation to 'internal' * refactored JythonScriptEngineFactory * implemented JythonScriptFileWatcher * fixed addon.xml & package-info.java * simplify stream list collector in JythonScriptEngineFactory * changed codeowner for jythonscripting * organized imports in JythonScriptEngineFactory Signed-off-by: Holger Hees <[email protected]>
1 parent 9af5bd0 commit e857f32

File tree

5 files changed

+111
-59
lines changed

5 files changed

+111
-59
lines changed

CODEOWNERS

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
/bundles/org.openhab.automation.jrubyscripting/ @ccutrer @jimtng
1010
/bundles/org.openhab.automation.jsscripting/ @jpg0 @florian-h05
1111
/bundles/org.openhab.automation.jsscriptingnashorn/ @wborn
12-
/bundles/org.openhab.automation.jythonscripting/ @openhab/add-ons-maintainers
12+
/bundles/org.openhab.automation.jythonscripting/ @HolgerHees
1313
/bundles/org.openhab.automation.pidcontroller/ @fwolter
1414
/bundles/org.openhab.automation.pwm/ @fwolter
1515
/bundles/org.openhab.binding.adorne/ @theiding

bundles/org.openhab.automation.jythonscripting/src/main/java/org/openhab/automation/jythonscripting/JythonScriptEngineFactory.java bundles/org.openhab.automation.jythonscripting/src/main/java/org/openhab/automation/jythonscripting/internal/JythonScriptEngineFactory.java

+47-56
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010
*
1111
* SPDX-License-Identifier: EPL-2.0
1212
*/
13-
package org.openhab.automation.jythonscripting;
13+
package org.openhab.automation.jythonscripting.internal;
1414

1515
import java.io.File;
1616
import java.nio.file.Paths;
17-
import java.util.ArrayList;
1817
import java.util.Arrays;
1918
import java.util.List;
2019
import java.util.Set;
2120
import java.util.TreeSet;
21+
import java.util.stream.Stream;
2222

2323
import javax.script.ScriptEngine;
2424

@@ -36,93 +36,84 @@
3636
*
3737
* @author Scott Rushworth - Initial contribution
3838
* @author Wouter Born - Initial contribution
39+
* @author Holger Hees - Further development
3940
*/
4041
@Component(service = ScriptEngineFactory.class)
4142
@NonNullByDefault
4243
public class JythonScriptEngineFactory extends AbstractScriptEngineFactory {
4344

44-
private static final String PYTHON_CACHEDIR = "python.cachedir";
4545
private static final String PYTHON_HOME = "python.home";
46+
private static final String PYTHON_HOME_PATH = JythonScriptEngineFactory.class.getProtectionDomain().getCodeSource()
47+
.getLocation().toString().replace("file:", "");
48+
4649
private static final String PYTHON_PATH = "python.path";
50+
private static final String PYTHON_DEFAULT_PATH = Paths
51+
.get(OpenHAB.getConfigFolder(), "automation", "jython", "lib").toString();
52+
53+
private static final String PYTHON_CACHEDIR = "python.cachedir";
54+
private static final String PYTHON_CACHEDIR_PATH = Paths
55+
.get(OpenHAB.getUserDataFolder(), "cache", JythonScriptEngineFactory.class.getPackageName(), "cachedir")
56+
.toString();
4757

48-
private static final String DEFAULT_PYTHON_PATH = Paths
49-
.get(OpenHAB.getConfigFolder(), "automation", "lib", "python").toString();
58+
private static final org.python.jsr223.PyScriptEngineFactory factory = new org.python.jsr223.PyScriptEngineFactory();
5059

51-
private static final String SCRIPT_TYPE = "py";
52-
private static final javax.script.ScriptEngineManager ENGINE_MANAGER = new javax.script.ScriptEngineManager();
60+
private final List<String> scriptTypes = (List<String>) Stream.of(factory.getExtensions(), factory.getMimeTypes())
61+
.flatMap(List::stream) //
62+
.toList();
5363

5464
@Activate
5565
public JythonScriptEngineFactory() {
5666
logger.debug("Loading JythonScriptEngineFactory");
5767

58-
String pythonHome = JythonScriptEngineFactory.class.getProtectionDomain().getCodeSource().getLocation()
59-
.toString().replace("file:", "");
60-
System.setProperty(PYTHON_HOME, pythonHome);
68+
System.setProperty(PYTHON_HOME, PYTHON_HOME_PATH);
6169

70+
Set<String> pythonPathList = new TreeSet<>(Arrays.asList(PYTHON_DEFAULT_PATH));
6271
String existingPythonPath = System.getProperty(PYTHON_PATH);
63-
if (existingPythonPath == null || existingPythonPath.isEmpty()) {
64-
System.setProperty(PYTHON_PATH, DEFAULT_PYTHON_PATH);
65-
} else if (!existingPythonPath.contains(DEFAULT_PYTHON_PATH)) {
66-
Set<String> newPythonPathList = new TreeSet<>(Arrays.asList(existingPythonPath.split(File.pathSeparator)));
67-
newPythonPathList.add(DEFAULT_PYTHON_PATH);
68-
System.setProperty(PYTHON_PATH, String.join(File.pathSeparator, newPythonPathList));
72+
if (existingPythonPath != null && !existingPythonPath.isEmpty()) {
73+
pythonPathList.addAll(Arrays.asList(existingPythonPath.split(File.pathSeparator)));
6974
}
75+
System.setProperty(PYTHON_PATH, String.join(File.pathSeparator, pythonPathList));
7076

71-
System.setProperty(PYTHON_CACHEDIR, Paths
72-
.get(OpenHAB.getUserDataFolder(), "cache", JythonScriptEngineFactory.class.getPackageName(), "cachedir")
73-
.toString());
77+
System.setProperty(PYTHON_CACHEDIR, PYTHON_CACHEDIR_PATH);
7478

7579
logPythonPaths();
7680
}
7781

78-
private void logPythonPaths() {
79-
logger.trace("{}: {}, {}: {}, {}: {}", //
80-
PYTHON_HOME, System.getProperty(PYTHON_HOME), //
81-
PYTHON_PATH, System.getProperty(PYTHON_PATH), //
82-
PYTHON_CACHEDIR, System.getProperty(PYTHON_CACHEDIR));
82+
@Deactivate
83+
public void cleanup() {
84+
logger.debug("Unloading JythonScriptEngineFactory");
85+
86+
System.clearProperty(PYTHON_HOME);
87+
88+
String existingPythonPath = System.getProperty(PYTHON_PATH);
89+
if (existingPythonPath != null && !existingPythonPath.isEmpty()) {
90+
Set<String> newPythonPathList = new TreeSet<>(Arrays.asList(existingPythonPath.split(File.pathSeparator)));
91+
newPythonPathList.remove(PYTHON_DEFAULT_PATH);
92+
System.setProperty(PYTHON_PATH, String.join(File.pathSeparator, newPythonPathList));
93+
}
94+
95+
System.clearProperty(PYTHON_CACHEDIR);
96+
97+
logPythonPaths();
8398
}
8499

85100
@Override
86101
public List<String> getScriptTypes() {
87-
List<String> scriptTypes = new ArrayList<>();
88-
89-
for (javax.script.ScriptEngineFactory factory : ENGINE_MANAGER.getEngineFactories()) {
90-
List<String> extensions = factory.getExtensions();
91-
92-
if (extensions.contains(SCRIPT_TYPE)) {
93-
scriptTypes.addAll(extensions);
94-
scriptTypes.addAll(factory.getMimeTypes());
95-
}
96-
}
97102
return scriptTypes;
98103
}
99104

100105
@Override
101106
public @Nullable ScriptEngine createScriptEngine(String scriptType) {
102-
ScriptEngine scriptEngine = ENGINE_MANAGER.getEngineByExtension(scriptType);
103-
if (scriptEngine == null) {
104-
scriptEngine = ENGINE_MANAGER.getEngineByMimeType(scriptType);
105-
}
106-
if (scriptEngine == null) {
107-
scriptEngine = ENGINE_MANAGER.getEngineByName(scriptType);
107+
if (!scriptTypes.contains(scriptType)) {
108+
return null;
108109
}
109-
return scriptEngine;
110+
return factory.getScriptEngine();
110111
}
111112

112-
@Deactivate
113-
public void removePythonPath() {
114-
logger.debug("Unloading JythonScriptEngineFactory");
115-
116-
String existingPythonPath = System.getProperty(PYTHON_PATH);
117-
if (existingPythonPath != null && existingPythonPath.contains(DEFAULT_PYTHON_PATH)) {
118-
Set<String> newPythonPathList = new TreeSet<>(Arrays.asList(existingPythonPath.split(File.pathSeparator)));
119-
newPythonPathList.remove(DEFAULT_PYTHON_PATH);
120-
System.setProperty(PYTHON_PATH, String.join(File.pathSeparator, newPythonPathList));
121-
}
122-
123-
System.clearProperty(PYTHON_HOME);
124-
System.clearProperty(PYTHON_CACHEDIR);
125-
126-
logPythonPaths();
113+
private void logPythonPaths() {
114+
logger.trace("{}: {}, {}: {}, {}: {}", //
115+
PYTHON_HOME, System.getProperty(PYTHON_HOME), //
116+
PYTHON_PATH, System.getProperty(PYTHON_PATH), //
117+
PYTHON_CACHEDIR, System.getProperty(PYTHON_CACHEDIR));
127118
}
128119
}

bundles/org.openhab.automation.jythonscripting/src/main/java/org/openhab/automation/jythonscripting/package-info.java bundles/org.openhab.automation.jythonscripting/src/main/java/org/openhab/automation/jythonscripting/internal/package-info.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
* SPDX-License-Identifier: EPL-2.0
1212
*/
1313
@org.osgi.annotation.bundle.Header(name = org.osgi.framework.Constants.DYNAMICIMPORT_PACKAGE, value = "*")
14-
package org.openhab.automation.jythonscripting;
14+
package org.openhab.automation.jythonscripting.internal;
1515

1616
/**
1717
* Additional information for the Jython Scripting package
1818
*
1919
* @author Wouter Born - Initial contribution
20+
* @author Holger Hees - Further development
2021
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Copyright (c) 2010-2024 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.automation.jythonscripting.internal.watch;
14+
15+
import java.io.File;
16+
import java.nio.file.Path;
17+
import java.util.Optional;
18+
19+
import org.eclipse.jdt.annotation.NonNullByDefault;
20+
import org.openhab.core.automation.module.script.ScriptDependencyTracker;
21+
import org.openhab.core.automation.module.script.ScriptEngineManager;
22+
import org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher;
23+
import org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileWatcher;
24+
import org.openhab.core.service.ReadyService;
25+
import org.openhab.core.service.StartLevelService;
26+
import org.openhab.core.service.WatchService;
27+
import org.osgi.service.component.annotations.Activate;
28+
import org.osgi.service.component.annotations.Component;
29+
import org.osgi.service.component.annotations.Reference;
30+
31+
/**
32+
* Monitors {@code <openHAB-conf>/automation/jython} for Jython files, but not libraries
33+
*
34+
* @author Holger Hees - Initial contribution
35+
*/
36+
@Component(immediate = true, service = { ScriptFileWatcher.class, ScriptDependencyTracker.Listener.class })
37+
@NonNullByDefault
38+
public class JythonScriptFileWatcher extends AbstractScriptFileWatcher {
39+
private static final String FILE_DIRECTORY = "automation" + File.separator + "jython";
40+
41+
@Activate
42+
public JythonScriptFileWatcher(
43+
final @Reference(target = WatchService.CONFIG_WATCHER_FILTER) WatchService watchService,
44+
final @Reference ScriptEngineManager manager, final @Reference ReadyService readyService,
45+
final @Reference StartLevelService startLevelService) {
46+
super(watchService, manager, readyService, startLevelService, FILE_DIRECTORY, true);
47+
}
48+
49+
@Override
50+
protected Optional<String> getScriptType(Path scriptFilePath) {
51+
String scriptType = super.getScriptType(scriptFilePath).orElse(null);
52+
if (!scriptFilePath.startsWith(getWatchPath().resolve("lib")) && ("py".equals(scriptType))) {
53+
return Optional.of(scriptType);
54+
}
55+
return Optional.empty();
56+
}
57+
}

bundles/org.openhab.automation.jythonscripting/src/main/resources/OH-INF/addon/addon.xml

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
xsi:schemaLocation="https://openhab.org/schemas/addon/v1.0.0 https://openhab.org/schemas/addon-1.0.0.xsd">
55

66
<type>automation</type>
7-
<name>Jython Scripting (DEPRECATED)</name>
7+
<name>Jython Scripting</name>
88
<description>This adds a Jython script engine.</description>
99
<connection>none</connection>
1010

11+
<service-id>org.openhab.automation.jythonscripting</service-id>
12+
<config-description-ref uri="automation:jythonscripting"/>
13+
1114
</addon:addon>

0 commit comments

Comments
 (0)