package net.sf.openrocket.simulation.extension.impl; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.l10n.L10N; import net.sf.openrocket.simulation.SimulationConditions; import net.sf.openrocket.simulation.exception.SimulationException; import net.sf.openrocket.simulation.extension.AbstractSimulationExtension; import net.sf.openrocket.simulation.listeners.SimulationListener; import com.google.inject.Inject; public class ScriptingExtension extends AbstractSimulationExtension { private static final String DEFAULT_LANGUAGE = "JavaScript"; @Inject private ScriptingUtil util; public ScriptingExtension() { setLanguage(DEFAULT_LANGUAGE); setScript(""); setEnabled(true); } @Override public String getName() { String name = trans.get("SimulationExtension.scripting.name"); name = L10N.replace(name, "{language}", getLanguage()); return name; } @Override public String getDescription() { return trans.get("SimulationExtension.scripting.desc"); } @Override public void documentLoaded(OpenRocketDocument document, Simulation simulation, WarningSet warnings) { /* * Scripts that the user has not explicitly indicated as trusted are disabled * when loading from a file. This is to prevent trojans. */ if (isEnabled()) { if (!util.isTrustedScript(getLanguage(), getScript())) { setEnabled(false); warnings.add(Warning.fromString(trans.get("SimulationExtension.scripting.warning.disabled"))); } } } @Override public void initialize(SimulationConditions conditions) throws SimulationException { if (isEnabled()) { conditions.getSimulationListenerList().add(getListener()); } } public String getScript() { return config.getString("script", ""); } public void setScript(String script) { config.put("script", script); } public String getLanguage() { return config.getString("language", DEFAULT_LANGUAGE); } public void setLanguage(String language) { config.put("language", language); } public boolean isEnabled() { return config.getBoolean("enabled", false); } public void setEnabled(boolean enabled) { config.put("enabled", enabled); } SimulationListener getListener() throws SimulationException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName(getLanguage()); if (engine == null) { throw new SimulationException("Your JRE does not support the scripting language '" + getLanguage() + "'"); } try { engine.eval(getScript()); } catch (ScriptException e) { throw new SimulationException("Invalid script: " + e.getMessage()); } if (!(engine instanceof Invocable)) { throw new SimulationException("The scripting language '" + getLanguage() + "' does not implement the Invocable interface"); } return new ScriptingSimulationListener((Invocable) engine); } }