com.github.mrstampy.poisonivy.PoisonIvy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of PoisonIvy Show documentation
Show all versions of PoisonIvy Show documentation
Poison Ivy - Java Library Dependency Resolver and Application Launcher
/*
* Poison Ivy - Java Library Dependency Resolver and Application Launcher
*
* Copyright (C) 2014 Burton Alexander
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
package com.github.mrstampy.poisonivy;
import static java.lang.System.exit;
import static java.lang.System.out;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.Parser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class PoisonIvy is designed to be used in one of three ways:
*
*
* 1. As a separate application.
* 2. As an integrated class.
* 3. As a main class superclass.
*
*
* Parameters can be specified on the command line or specified in a file called
* {@value #POISONIVY_CONFIG}.
*/
public class PoisonIvy {
private static final Logger log = LoggerFactory.getLogger(PoisonIvy.class);
/** The Constant MAIN_JAR_PARM -{@value #MAIN_JAR_PARM}. */
public static final String MAIN_JAR_PARM = "mj";
/** The Constant MAIN_JAR_PARM -{@value #MAIN_CLASS_PARM}. */
public static final String MAIN_CLASS_PARM = "mc";
/** The Constant FORCE_PARM -{@value #FORCE_PARM}. */
public static final String FORCE_PARM = "f";
/** The Constant HELP_PARM -{@value #HELP_PARM}. */
public static final String HELP_PARM = "h";
/** The Constant LIB_DIR_PARM -{@value #LIB_DIR_PARM}. */
public static final String LIB_DIR_PARM = "libdir";
/** The Constant IVY_SETTINGS_PARM -{@value #IVY_SETTINGS_PARM}. */
public static final String IVY_SETTINGS_PARM = "ivysettings";
/** The Constant IVY_PARM -{@value #IVY_PARM}. */
public static final String IVY_PARM = "ivy";
/** The Constant RESOLVE_PATTERN_PARM -{@value #RESOLVE_PATTERN_PARM}. */
public static final String RESOLVE_PATTERN_PARM = "rp";
/** The Constant NO_CLEAN_PARM -{@value #NO_CLEAN_PARM}. */
public static final String NO_CLEAN_PARM = "nc";
/** The Constant POISONIVY_CONFIG {@value #POISONIVY_CONFIG}. */
public static final String POISONIVY_CONFIG = "poisonivy.config";
private String[] args;
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(String[] args) {
try {
new PoisonIvy(args).execute();
} catch (Exception e) {
e.printStackTrace();
log.error("Unexpected exception", e);
}
}
/**
* Instantiates a new poison ivy.
*
* @param args
* the args
*/
public PoisonIvy(String... args) {
this.args = args;
}
/**
* Execute.
*
* @return true, if successful
* @throws Exception
* the exception
*/
public boolean execute() {
try {
return executeImpl();
} catch (Exception e) {
log.error("Could not execute", e);
out.println(stackTraceToString(e));
printHelpMessage();
}
return false;
}
protected boolean executeImpl() throws Exception {
String[] poisonArgs = getArgs();
logArgs(poisonArgs);
Parser parser = new BasicParser();
CommandLine cli = parser.parse(getOptions(), poisonArgs);
if (cli.hasOption(HELP_PARM)) {
printHelpMessage();
return true;
}
if (executeLibraryRetrieval(cli)) {
if (cli.hasOption(MAIN_JAR_PARM) || cli.hasOption(MAIN_CLASS_PARM)) executeMain(cli);
return true;
}
log.error("Could not retrieve libraries via ivy");
return false;
}
private String stackTraceToString(Exception e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
return writer.toString();
}
protected void logArgs(String[] args) {
if (!log.isDebugEnabled()) return;
log.debug("Executing with the following command parameters:");
for (String s : args) {
log.debug("**** Command parameter: {}", s);
}
}
/**
* Gets the args.
*
* @return the args
* @throws IOException
* Signals that an I/O exception has occurred.
*/
protected String[] getArgs() throws IOException {
File poisonIvyConfig = new File(POISONIVY_CONFIG);
if ((args == null || args.length == 0) && !poisonIvyConfig.exists()) {
printHelpMessage();
exit(-1);
}
return args.length > 0 ? args : parsePoisonIvyConfig(poisonIvyConfig);
}
/**
* Poison ivy config exists.
*
* @return true, if successful
*/
public boolean poisonIvyConfigExists() {
return new File(POISONIVY_CONFIG).exists();
}
/**
* Parses the poison ivy config, reading the first line of the file as if it
* was passed on the command line.
*
* @param poisonIvyConfig
* the poison ivy config
* @return the string[] arguments
* @throws IOException
* Signals that an I/O exception has occurred.
*/
protected String[] parsePoisonIvyConfig(File poisonIvyConfig) throws IOException {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(poisonIvyConfig));
String cmdline = reader.readLine();
return cmdline.split(" ");
} finally {
if (reader != null) reader.close();
}
}
/**
* Prints the help message to System.out.
*/
protected void printHelpMessage() {
out.println("Poison Ivy - Java Library Dependency Resolver and Application Launcher");
out.println();
out.println("Licence: GPL 2.0");
out.println("Copyright Burton Alexander 2014");
out.println();
out.println("Usage: ");
out.println();
Options opts = getOptions();
for (Object op : opts.getOptions()) {
Option o = (Option) op;
out.println("-" + o.getOpt() + (o.hasArg() ? " [ARG]" : "") + " - " + o.getDescription());
}
out.println();
out.println("The required options can be put into a file named '" + POISONIVY_CONFIG + "'");
out.println();
printExamples();
out.println();
out.println("See http://mrstampy.github.io/PoisonIvy/ for more information");
}
private void printExamples() {
out.println("Examples:");
out.println("");
out.println("-mj MyApplication.jar");
out.println("");
out.println("-mj MyApplication.jar -X mx1000m -X ms500m");
out.println("");
out.println("-mc com.my.MainClass -X mx1000m -X ms500m -D my.settings.file=/some/path/and/file");
out.println("");
out.println("-ivy /path/to/ivy.xml -ivysettings /path/to/ivysettings.xml -libdir /path/to/ivylib -f -nc");
}
/**
* Execute the main jar Java application or main class using the command
* options specified.
*
* @param cli
* the cli
* @throws IOException
* Signals that an I/O exception has occurred.
*
* @see #MAIN_CLASS_PARM
* @see #MAIN_JAR_PARM
* @see #JAVA_OPTS_PARM
*/
protected void executeMain(CommandLine cli) throws IOException {
Runtime.getRuntime().exec(getCommand(cli));
}
/**
* Gets the command used to execute the main jar, if requested.
*
* @param cli
* the cli
* @return the command
*
* @see #MAIN_CLASS_PARM
* @see #MAIN_JAR_PARM
* @see #JAVA_OPTS_PARM
*/
protected String[] getCommand(CommandLine cli) {
List command = new ArrayList();
command.add("java");
command.add("-cp");
command.add(IvyLibraryRetriever.getClasspath());
addDOptions(cli, command);
addXOptions(cli, command);
if (cli.hasOption(MAIN_JAR_PARM)) {
command.add("-jar");
command.add(cli.getOptionValue(MAIN_JAR_PARM));
} else if (cli.hasOption(MAIN_CLASS_PARM)) {
command.add(cli.getOptionValue(MAIN_CLASS_PARM));
}
return command.toArray(new String[] {});
}
private void addXOptions(CommandLine cli, List command) {
String[] xs = cli.getOptionValues("X");
if(xs == null || xs.length == 0) return;
for(String x : xs) {
command.add("-X" + x);
}
}
private void addDOptions(CommandLine cli, List command) {
Properties props = cli.getOptionProperties("D");
if(props == null || props.isEmpty()) return;
for(Entry