/* * Copyright (c) 2009-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.planet57.gshell.commands.script; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.net.URL; import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.inject.Inject; import javax.script.ScriptEngine; import com.planet57.gshell.command.Command; import com.planet57.gshell.command.CommandActionSupport; import com.planet57.gshell.command.CommandContext; import com.planet57.gshell.util.cli2.Argument; import com.planet57.gshell.util.cli2.Option; import com.planet57.gshell.util.pref.Preference; import com.planet57.gshell.util.pref.Preferences; import static com.google.common.base.Preconditions.checkState; /** * Execute a script. * * @since 3.0 */ @Command(name = "script", description = "Execute a script") @Preferences(path = "commands/script") public class ScriptAction extends CommandActionSupport { @Inject private ScriptManager scriptManager; @Preference @Option(name = "l", longName = "language", description = "Script language", token = "LANG", required = true) private String language; @Option(name = "f", longName = "file", description = "Script file", token = "FILE") @Nullable private File file; @Option(name = "u", longName = "url", description = "Script URL", token = "URL") @Nullable private URL url; @Option(name = "e", longName = "expression", description = "Script expression", token = "EXPR") @Nullable private String expression; @Argument(description = "Additional script arguments", token = "ARGS") @Nullable private List<String> args; @Override public Object execute(@Nonnull final CommandContext context) throws Exception { // validate only 1 source option has been specified int sources = 0; if (file != null) sources++; if (url != null) sources++; if (expression != null) sources++; checkState(sources == 1, "Only one of file, url or expression may be specified"); ScriptEngine engine = scriptManager.engineForLanguage(language); log.debug("Engine: {}", engine); ScriptContextImpl scriptContext = new ScriptContextImpl(engine, context.getIo()); scriptContext.set("context", context); scriptContext.set("log", log); scriptContext.set("args", args); try (Reader source = createSource()) { log.debug("Source: {}", source); Object result = engine.eval(source, scriptContext); log.debug("Result: {}", result); return result; } } private Reader createSource() throws Exception { if (file != null) { return new BufferedReader(new FileReader(file)); } else if (url != null) { return new BufferedReader(new InputStreamReader(url.openStream())); } else if (expression != null) { return new StringReader(expression); } // should never happen throw new Error(); } }