Java tutorial
/** * The MIT License (MIT) * * Copyright (c) 2014 Jason Dunkelberger (dirkraft) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.github.dirkraft.jash; import com.google.common.base.Charsets; import com.google.common.base.Strings; import com.google.common.io.CharStreams; import com.google.common.io.Resources; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; import org.kohsuke.args4j.spi.FileOptionHandler; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; public abstract class AbstractBundler implements JashCommand { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Command options @Argument(metaVar = "command name") public String commandName; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Daemon options @Option(name = "-h", aliases = "--daemon-host") public String daemonHost = "localhost"; @Option(name = "-p", aliases = "--daemon-port") public int daemonPort = 47474; // TODO use a respectable parser, e.g. 1h30m (1 hour 30 minutes); 90s (90 seconds), 1d (1 day) @Option(name = "-i", aliases = "--daemon-idle") public String daemonIdle = "1h"; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Build options @Option(name = "-o", aliases = "--output-dir", handler = FileOptionHandler.class) // This is a bit silly to have an extra dir, but in the case the user downloaded the jasher cli (rather // than use the gradle plugin), output to similar build directory path. public File outputDir = new File("build/jasher/"); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // internal build state protected File _renderedScriptFile; public List<String> validateAndInit() throws Exception { List<String> errors = new ArrayList<>(); if (outputDir.isFile()) { errors.add(outputDir.getAbsolutePath() + " exists and is a file. Cannot output here. " + "Should either be a directory or not exist (which would be automatically created)."); } return errors; } @Override public void run(Object cli) throws Exception { String renderedScript = namespaceScript(renderScript()); JashIO.outf("Rendered jash.bash script %n"); writeScript(renderedScript); JashIO.outf("Wrote rendered jash.bash script to %s%n", _renderedScriptFile.getAbsolutePath()); } @Override public String complete(Object cli) throws Exception { return ""; } String renderScript() { String script = readClasspathResource("jash.bash"); script = script.replaceFirst("_JASH_COMMAND_NAME=.*", "_JASH_COMMAND_NAME=" + commandName); final String resolvedBindAddr; try { URI uri = new URI(daemonHost); String scheme = uri.getScheme(); if (Strings.isNullOrEmpty(scheme)) { scheme = "http"; } String host = uri.getHost(); if (Strings.isNullOrEmpty(host)) { host = "localhost"; } int port = uri.getPort(); if (port == -1) { port = this.daemonPort; } resolvedBindAddr = new URI(scheme, null, host, port, null, null, null).toString(); } catch (URISyntaxException e) { throw new RuntimeException(e); } script = script.replaceFirst("_JASH_SERVER=.*", "_JASH_SERVER=" + resolvedBindAddr); return script; } void writeScript(String script) { boolean ignored = outputDir.mkdirs(); Path outputDirPath = outputDir.toPath(); if (!Files.isDirectory(outputDirPath) || !Files.isWritable(outputDirPath)) { throw new RuntimeException("Unable to prepare and write to " + outputDir.getAbsolutePath()); } Path scriptPath = outputDirPath.resolve(commandName + ".bash"); try { File scriptFile = scriptPath.toFile(); com.google.common.io.Files.write(script, scriptFile, Charsets.UTF_8); boolean setExecutable = scriptFile.setExecutable(true); if (!setExecutable) { JashIO.errf("Warning: Failed to set execute bit on %s%n", scriptFile.getAbsolutePath()); } this._renderedScriptFile = scriptFile; } catch (IOException e) { throw new RuntimeException(e); } } String namespaceScript(String commonBash) { String underscored = '_' + commandName.replace('-', '_'); // The leading _ indicates things that need namespacing. return commonBash.replace("_JASH", underscored.toUpperCase()).replace("_jash", underscored.toLowerCase()); } static String readClasspathResource(String classpathRes) { try { return CharStreams.toString( new InputStreamReader(Resources.getResource(classpathRes).openStream(), Charsets.UTF_8)); } catch (IOException e) { throw new RuntimeException(e); } } @Override public String toString() { return "commandName='" + commandName + '\'' + ", daemonHost='" + daemonHost + '\'' + ", daemonPort=" + daemonPort + ", daemonIdle='" + daemonIdle + '\'' + ", outputDir=" + outputDir; } }