001package jmri.script;
002
003import java.util.*;
004
005import javax.annotation.Nonnull;
006import javax.script.ScriptEngineFactory;
007import javax.script.ScriptException;
008
009import jmri.InstanceManagerAutoDefault;
010import jmri.script.ScriptEngineSelector.Engine;
011
012/**
013 * Internal class for the ScriptEngineSelector
014 * @author Daniel Bergqvist (C) 2022
015 */
016public class InternalScriptEngineSelector implements InstanceManagerAutoDefault {
017
018    private final Engine _defaultEngine;
019    private final List<Engine> _engines = new ArrayList<>();
020    private final Map<String, Engine> _engineMap = new HashMap<>();
021    private final Set<String> languageNames = new HashSet<>();
022
023
024    public InternalScriptEngineSelector() {
025        // get list of language names (to display) and IDs (for call)
026        JmriScriptEngineManager.getDefault().getManager().getEngineFactories().stream().forEach((ScriptEngineFactory factory) -> {
027            String version = factory.getEngineVersion();
028            if (version != null) {
029                String name = JmriScriptEngineManager.fileForLanguage(factory.getEngineName(), factory.getLanguageName());
030                if (!languageNames.contains(name)) {
031                    String languageName = factory.getLanguageName();
032                    try {
033                        languageNames.add(name);
034                        Engine engine = new Engine(name, languageName);
035                        _engines.add(engine);
036                        _engineMap.put(languageName, engine);
037                    } catch (ScriptException e) {
038                        log.error("Cannot load script engine {}, {}", name, languageName);
039                    }
040                }
041            }
042        });
043
044        if (_engineMap.containsKey("python")) {
045            _defaultEngine = _engineMap.get("python");
046        } else {
047            if (!_engineMap.isEmpty()) {
048                _defaultEngine = _engineMap.values().iterator().next();
049            } else {
050                _defaultEngine = null;
051            }
052        }
053    }
054
055    Engine getDefaultEngine() {
056        return _defaultEngine;
057    }
058
059    Engine getEngineFromLanguage(String language) {
060        return _engineMap.get(language);
061    }
062
063    @Nonnull
064    public List<Engine> getAllEngines() {
065        return Collections.unmodifiableList(_engines);
066    }
067
068    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(InternalScriptEngineSelector.class);
069
070}