]> git.basschouten.com Git - openhab-addons.git/blob
213ce39bdee18872fae805934ea509070a7e39a9
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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;
14
15 import java.io.File;
16 import java.nio.file.Paths;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.List;
20 import java.util.Set;
21 import java.util.TreeSet;
22
23 import javax.script.ScriptEngine;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.openhab.core.OpenHAB;
28 import org.openhab.core.automation.module.script.AbstractScriptEngineFactory;
29 import org.openhab.core.automation.module.script.ScriptEngineFactory;
30 import org.osgi.service.component.annotations.Activate;
31 import org.osgi.service.component.annotations.Component;
32 import org.osgi.service.component.annotations.Deactivate;
33
34 /**
35  * This is an implementation of {@link ScriptEngineFactory} for Jython.
36  *
37  * @author Scott Rushworth - Initial contribution
38  * @author Wouter Born - Initial contribution
39  */
40 @Component(service = ScriptEngineFactory.class)
41 @NonNullByDefault
42 public class JythonScriptEngineFactory extends AbstractScriptEngineFactory {
43
44     private static final String PYTHON_CACHEDIR = "python.cachedir";
45     private static final String PYTHON_HOME = "python.home";
46     private static final String PYTHON_PATH = "python.path";
47
48     private static final String DEFAULT_PYTHON_PATH = Paths
49             .get(OpenHAB.getConfigFolder(), "automation", "lib", "python").toString();
50
51     private static final String SCRIPT_TYPE = "py";
52     private static final javax.script.ScriptEngineManager ENGINE_MANAGER = new javax.script.ScriptEngineManager();
53
54     @Activate
55     public JythonScriptEngineFactory() {
56         logger.debug("Loading JythonScriptEngineFactory");
57
58         String pythonHome = JythonScriptEngineFactory.class.getProtectionDomain().getCodeSource().getLocation()
59                 .toString().replace("file:", "");
60         System.setProperty(PYTHON_HOME, pythonHome);
61
62         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));
69         }
70
71         System.setProperty(PYTHON_CACHEDIR, Paths
72                 .get(OpenHAB.getUserDataFolder(), "cache", JythonScriptEngineFactory.class.getPackageName(), "cachedir")
73                 .toString());
74
75         logPythonPaths();
76     }
77
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));
83     }
84
85     @Override
86     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         }
97         return scriptTypes;
98     }
99
100     @Override
101     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);
108         }
109         return scriptEngine;
110     }
111
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();
127     }
128 }