mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 07:02:02 +01:00
[jythonscripting] Refactor, improve and simplify (#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 <holger.hees@gmail.com>
This commit is contained in:
parent
9af5bd0944
commit
e857f32a8a
@ -9,7 +9,7 @@
|
||||
/bundles/org.openhab.automation.jrubyscripting/ @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.jythonscripting/ @HolgerHees
|
||||
/bundles/org.openhab.automation.pidcontroller/ @fwolter
|
||||
/bundles/org.openhab.automation.pwm/ @fwolter
|
||||
/bundles/org.openhab.binding.adorne/ @theiding
|
||||
|
@ -10,15 +10,15 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.automation.jythonscripting;
|
||||
package org.openhab.automation.jythonscripting.internal;
|
||||
|
||||
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 java.util.stream.Stream;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
|
||||
@ -36,93 +36,84 @@ import org.osgi.service.component.annotations.Deactivate;
|
||||
*
|
||||
* @author Scott Rushworth - Initial contribution
|
||||
* @author Wouter Born - Initial contribution
|
||||
* @author Holger Hees - Further development
|
||||
*/
|
||||
@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_HOME_PATH = JythonScriptEngineFactory.class.getProtectionDomain().getCodeSource()
|
||||
.getLocation().toString().replace("file:", "");
|
||||
|
||||
private static final String PYTHON_PATH = "python.path";
|
||||
private static final String PYTHON_DEFAULT_PATH = Paths
|
||||
.get(OpenHAB.getConfigFolder(), "automation", "jython", "lib").toString();
|
||||
|
||||
private static final String DEFAULT_PYTHON_PATH = Paths
|
||||
.get(OpenHAB.getConfigFolder(), "automation", "lib", "python").toString();
|
||||
private static final String PYTHON_CACHEDIR = "python.cachedir";
|
||||
private static final String PYTHON_CACHEDIR_PATH = Paths
|
||||
.get(OpenHAB.getUserDataFolder(), "cache", JythonScriptEngineFactory.class.getPackageName(), "cachedir")
|
||||
.toString();
|
||||
|
||||
private static final String SCRIPT_TYPE = "py";
|
||||
private static final javax.script.ScriptEngineManager ENGINE_MANAGER = new javax.script.ScriptEngineManager();
|
||||
private static final org.python.jsr223.PyScriptEngineFactory factory = new org.python.jsr223.PyScriptEngineFactory();
|
||||
|
||||
private final List<String> scriptTypes = (List<String>) Stream.of(factory.getExtensions(), factory.getMimeTypes())
|
||||
.flatMap(List::stream) //
|
||||
.toList();
|
||||
|
||||
@Activate
|
||||
public JythonScriptEngineFactory() {
|
||||
logger.debug("Loading JythonScriptEngineFactory");
|
||||
|
||||
String pythonHome = JythonScriptEngineFactory.class.getProtectionDomain().getCodeSource().getLocation()
|
||||
.toString().replace("file:", "");
|
||||
System.setProperty(PYTHON_HOME, pythonHome);
|
||||
System.setProperty(PYTHON_HOME, PYTHON_HOME_PATH);
|
||||
|
||||
Set<String> pythonPathList = new TreeSet<>(Arrays.asList(PYTHON_DEFAULT_PATH));
|
||||
String existingPythonPath = System.getProperty(PYTHON_PATH);
|
||||
if (existingPythonPath != null && !existingPythonPath.isEmpty()) {
|
||||
pythonPathList.addAll(Arrays.asList(existingPythonPath.split(File.pathSeparator)));
|
||||
}
|
||||
System.setProperty(PYTHON_PATH, String.join(File.pathSeparator, pythonPathList));
|
||||
|
||||
System.setProperty(PYTHON_CACHEDIR, PYTHON_CACHEDIR_PATH);
|
||||
|
||||
logPythonPaths();
|
||||
}
|
||||
|
||||
@Deactivate
|
||||
public void cleanup() {
|
||||
logger.debug("Unloading JythonScriptEngineFactory");
|
||||
|
||||
System.clearProperty(PYTHON_HOME);
|
||||
|
||||
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)) {
|
||||
if (existingPythonPath != null && !existingPythonPath.isEmpty()) {
|
||||
Set<String> newPythonPathList = new TreeSet<>(Arrays.asList(existingPythonPath.split(File.pathSeparator)));
|
||||
newPythonPathList.add(DEFAULT_PYTHON_PATH);
|
||||
newPythonPathList.remove(PYTHON_DEFAULT_PATH);
|
||||
System.setProperty(PYTHON_PATH, String.join(File.pathSeparator, newPythonPathList));
|
||||
}
|
||||
|
||||
System.setProperty(PYTHON_CACHEDIR, Paths
|
||||
.get(OpenHAB.getUserDataFolder(), "cache", JythonScriptEngineFactory.class.getPackageName(), "cachedir")
|
||||
.toString());
|
||||
System.clearProperty(PYTHON_CACHEDIR);
|
||||
|
||||
logPythonPaths();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getScriptTypes() {
|
||||
return scriptTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ScriptEngine createScriptEngine(String scriptType) {
|
||||
if (!scriptTypes.contains(scriptType)) {
|
||||
return null;
|
||||
}
|
||||
return factory.getScriptEngine();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
@ -11,10 +11,11 @@
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
@org.osgi.annotation.bundle.Header(name = org.osgi.framework.Constants.DYNAMICIMPORT_PACKAGE, value = "*")
|
||||
package org.openhab.automation.jythonscripting;
|
||||
package org.openhab.automation.jythonscripting.internal;
|
||||
|
||||
/**
|
||||
* Additional information for the Jython Scripting package
|
||||
*
|
||||
* @author Wouter Born - Initial contribution
|
||||
* @author Holger Hees - Further development
|
||||
*/
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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.jythonscripting.internal.watch;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.automation.module.script.ScriptDependencyTracker;
|
||||
import org.openhab.core.automation.module.script.ScriptEngineManager;
|
||||
import org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher;
|
||||
import org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileWatcher;
|
||||
import org.openhab.core.service.ReadyService;
|
||||
import org.openhab.core.service.StartLevelService;
|
||||
import org.openhab.core.service.WatchService;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* Monitors {@code <openHAB-conf>/automation/jython} for Jython files, but not libraries
|
||||
*
|
||||
* @author Holger Hees - Initial contribution
|
||||
*/
|
||||
@Component(immediate = true, service = { ScriptFileWatcher.class, ScriptDependencyTracker.Listener.class })
|
||||
@NonNullByDefault
|
||||
public class JythonScriptFileWatcher extends AbstractScriptFileWatcher {
|
||||
private static final String FILE_DIRECTORY = "automation" + File.separator + "jython";
|
||||
|
||||
@Activate
|
||||
public JythonScriptFileWatcher(
|
||||
final @Reference(target = WatchService.CONFIG_WATCHER_FILTER) WatchService watchService,
|
||||
final @Reference ScriptEngineManager manager, final @Reference ReadyService readyService,
|
||||
final @Reference StartLevelService startLevelService) {
|
||||
super(watchService, manager, readyService, startLevelService, FILE_DIRECTORY, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> getScriptType(Path scriptFilePath) {
|
||||
String scriptType = super.getScriptType(scriptFilePath).orElse(null);
|
||||
if (!scriptFilePath.startsWith(getWatchPath().resolve("lib")) && ("py".equals(scriptType))) {
|
||||
return Optional.of(scriptType);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
@ -4,8 +4,11 @@
|
||||
xsi:schemaLocation="https://openhab.org/schemas/addon/v1.0.0 https://openhab.org/schemas/addon-1.0.0.xsd">
|
||||
|
||||
<type>automation</type>
|
||||
<name>Jython Scripting (DEPRECATED)</name>
|
||||
<name>Jython Scripting</name>
|
||||
<description>This adds a Jython script engine.</description>
|
||||
<connection>none</connection>
|
||||
|
||||
<service-id>org.openhab.automation.jythonscripting</service-id>
|
||||
<config-description-ref uri="automation:jythonscripting"/>
|
||||
|
||||
</addon:addon>
|
||||
|
Loading…
Reference in New Issue
Block a user