001package jmri.script;
002
003import java.util.*;
004
005import javax.annotation.CheckForNull;
006import javax.annotation.Nonnull;
007import javax.script.*;
008
009import jmri.InstanceManager;
010
011/**
012 * Selects a valid scripting engine.
013 *
014 * @author Daniel Bergqvist (C) 2022
015 */
016public class ScriptEngineSelector {
017
018    public static final String JYTHON = "python";
019    public static final String ECMA_SCRIPT = "ECMAScript";
020
021    private Engine _selectedEngine = InstanceManager.getDefault(
022            InternalScriptEngineSelector.class).getDefaultEngine();
023
024
025    /**
026     * Get the selected engine.
027     * @return the engine
028     */
029    @CheckForNull
030    public Engine getSelectedEngine() {
031        return _selectedEngine;
032    }
033
034    /**
035     * Sets the selected engine.
036     * @param engine the engine
037     */
038    public void setSelectedEngine(@Nonnull Engine engine) {
039        _selectedEngine = engine;
040    }
041
042    /**
043     * Sets the selected engine from the language name.
044     * @param languageName the engine
045     */
046    public void setSelectedEngine(@Nonnull String languageName) {
047        Engine engine = InstanceManager.getDefault(
048                InternalScriptEngineSelector.class).getEngineFromLanguage(languageName);
049        if (engine != null) {
050            setSelectedEngine(engine);
051        } else {
052            log.warn("Cannot select engine for the language {}", languageName);
053        }
054    }
055
056    /**
057     * Get a unmodifiable list of all the engines.
058     * @return the list
059     */
060    @Nonnull
061    public static List<Engine> getAllEngines() {
062        return Collections.unmodifiableList(InstanceManager.getDefault(
063                InternalScriptEngineSelector.class).getAllEngines());
064    }
065
066
067    public static class Engine {
068
069        private final String _name;
070        private final String _languageName;
071        private final ScriptEngine _engine;
072
073        Engine(String name, String id) throws ScriptException {
074            _name = name;
075            _languageName = id;
076            _engine = JmriScriptEngineManager.getDefault().getEngineByName(_languageName);
077
078            log.debug("Load script engine: {}, {}, {}", _name, _languageName, _engine);
079        }
080
081        /**
082         * Get the name.
083         * @return the name
084         */
085        @Nonnull
086        public String getName() {
087            return _name;
088        }
089
090        /**
091         * Get the name.
092         * @return the name
093         */
094        @Nonnull
095        public String getLanguageName() {
096            return _languageName;
097        }
098
099        /**
100         * Get the script engine.
101         * @return the script engine
102         */
103        @Nonnull
104        public ScriptEngine getScriptEngine() {
105            return _engine;
106        }
107
108        /**
109         * Is this engine for Jython/Python?
110         * @return true if Jython/Python, false otherwise
111         */
112        public boolean isJython() {
113            return "python".equalsIgnoreCase(_languageName)
114                    || "jython".equalsIgnoreCase(_languageName);
115        }
116
117        /**
118         * Is this engine for JavaScript/ECMAscript?
119         * @return true if JavaScript/ECMAscript, false otherwise
120         */
121        public boolean isJavaScript() {
122            return "javascript".equalsIgnoreCase(_languageName)
123                    || "ecmascript".equalsIgnoreCase(_languageName);
124        }
125
126        /** {@inheritDoc} */
127        @Override
128        public String toString() {
129            return _name;
130        }
131    }
132
133
134    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ScriptEngineSelector.class);
135
136}