/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
+++ /dev/null
-/**
- * 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;
-
-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();
- }
-}
--- /dev/null
+/**
+ * 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;
+
+import java.io.File;
+import java.nio.file.Paths;
+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;
+
+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
+ * @author Holger Hees - Further development
+ */
+@Component(service = ScriptEngineFactory.class)
+@NonNullByDefault
+public class JythonScriptEngineFactory extends AbstractScriptEngineFactory {
+
+ 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 PYTHON_CACHEDIR = "python.cachedir";
+ private static final String PYTHON_CACHEDIR_PATH = Paths
+ .get(OpenHAB.getUserDataFolder(), "cache", JythonScriptEngineFactory.class.getPackageName(), "cachedir")
+ .toString();
+
+ 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");
+
+ 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()) {
+ Set<String> newPythonPathList = new TreeSet<>(Arrays.asList(existingPythonPath.split(File.pathSeparator)));
+ newPythonPathList.remove(PYTHON_DEFAULT_PATH);
+ System.setProperty(PYTHON_PATH, String.join(File.pathSeparator, newPythonPathList));
+ }
+
+ 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));
+ }
+}
--- /dev/null
+/**
+ * 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
+ */
+@org.osgi.annotation.bundle.Header(name = org.osgi.framework.Constants.DYNAMICIMPORT_PACKAGE, value = "*")
+package org.openhab.automation.jythonscripting.internal;
+
+/**
+ * Additional information for the Jython Scripting package
+ *
+ * @author Wouter Born - Initial contribution
+ * @author Holger Hees - Further development
+ */
--- /dev/null
+/**
+ * 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();
+ }
+}
+++ /dev/null
-/**
- * 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
- */
-@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
- */
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>