package CLInterface;
import java.io.*;
import java.util.Properties;
import org.apache.commons.cli.*;
import org.apache.commons.io.FilenameUtils;
import LONI.tree.workflow.Pipeline;
import LONI.visitor.*;
import Specification.*;
import Taverna.Visitor.TavernaToLoniConverter;
/**
* PipelineConverter main class. Contains main method for converter program.
*
* Help is provided by supplying the -h or --help options.
*
* @author Chris Tandiono
*/
public class PipelineConverter {
public static void main(String[] args) throws IOException {
Options options = makeOptions();
CommandLineParser parser = new PosixParser();
CommandLine cmd = null;
try {
cmd = parser.parse(options, args);
} catch (ParseException e) {
printHelp(options);
System.exit(0);
}
configureMisc(cmd);
configureInput(cmd);
configureOutput(cmd);
Printer.log("Done processing command-line arguments");
if (ConverterConfig.OUTPUT == null
&& ConverterConfig.OUTPUT_PATH != null) {
File output = new File(ConverterConfig.OUTPUT_PATH);
output.createNewFile();
try {
ConverterConfig.OUTPUT = new FileOutputStream(output);
} catch (FileNotFoundException e) {
/* how would this have happened...? */
Printer.log("Got a weird error: " + e.getMessage());
}
}
String outputString = null;
switch (ConverterConfig.INPUT_FORMAT) {
case GALAXY: {
Galaxy.Tree.Workflow.Workflow g = null;
try {
g = GalaxySpecification.getJSONParser().parse(
new File(ConverterConfig.INPUT_PATH));
} catch (FileNotFoundException e) {
Printer.log("What, FileNotFoundException not caught by configureInput?");
}
switch (ConverterConfig.OUTPUT_FORMAT) {
case GALAXY:
outputString = GalaxySpecification.getJSONGenerator().generate(
g);
break;
case LONI:
Pipeline p;
// don't import; use fully-qualified name to avoid collision
// with local converter
Galaxy.Visitor.Webservice.GalaxyToLoniWorkflowConverter foo = new Galaxy.Visitor.Webservice.GalaxyToLoniWorkflowConverter();
Printer.log("Using Webservice Galaxy Converter");
p = (Pipeline) foo.visit(g);
outputString = LoniSpecification.getXMLGenerator().generate(p);
break;
default:
cantConvert();
}
break;
}
case TAVERNA: {
Taverna.Tree.Workflow t = null;
try {
t = TavernaSpecification.getXMLParser().parse(
new File(ConverterConfig.INPUT_PATH));
} catch (FileNotFoundException e) {
Printer.log("What, FileNotFoundException not caught by configureInput?");
}
switch (ConverterConfig.OUTPUT_FORMAT) {
case TAVERNA:
outputString = TavernaSpecification.getXMLGenerator().generate(
t);
break;
case LONI:
TavernaToLoniConverter foo = new TavernaToLoniConverter();
Pipeline p = (Pipeline) foo.visit(t);
outputString = LoniSpecification.getXMLGenerator().generate(p);
break;
default:
cantConvert();
}
break;
}
case LONI: {
Pipeline p = null;
try {
p = LoniSpecification.getXMLParser().parse(
new File(ConverterConfig.INPUT_PATH));
} catch (FileNotFoundException e) {
Printer.log("What, FileNotFoundException not caught by configureInput?");
}
switch (ConverterConfig.OUTPUT_FORMAT) {
case GALAXY:
LoniToGalaxyConverter ltgc = new LoniToGalaxyConverter();
Galaxy.Tree.Workflow.Workflow gtww = (Galaxy.Tree.Workflow.Workflow) ltgc
.visit(p);
outputString = GalaxySpecification.getJSONGenerator().generate(
gtww);
GalaxySpecification.getDatabase().dumpDatabase();
break;
case TAVERNA:
LoniToTavernaConverter lttc = new LoniToTavernaConverter();
Taverna.Tree.Workflow ttw = (Taverna.Tree.Workflow) lttc
.visit(p);
outputString = TavernaSpecification.getXMLGenerator().generate(
ttw);
break;
case LONI:
outputString = LoniSpecification.getXMLGenerator().generate(p);
break;
default:
cantConvert();
}
break;
}
default:
cantUnderstand();
}
if (outputString == null) {
Printer.log("Didn't get any output from converter");
}
Printer.output(outputString);
if (ConverterConfig.OUTPUT != null) {
ConverterConfig.OUTPUT.flush();
ConverterConfig.OUTPUT.close();
}
}
/**
* Checks and configures verbosity, force, and location of config file
*
* @param cmd
* The CommandLine object that's been parsed already
*/
static void configureMisc(CommandLine cmd) {
if (cmd.hasOption('v')) {
ConverterConfig.DEBUG = System.err;
Printer.log("OK, going to be very verbose...");
}
if (cmd.hasOption('f')) {
ConverterConfig.FORCE = true;
Printer.log("OK, forcing conversion...");
}
Properties prop = new Properties();
String configFile = cmd.getOptionValue('C', "pc.conf");
File f = new File(configFile);
FileReader fr = null;
try {
fr = new FileReader(f);
try {
prop.load(fr);
} catch (IOException e) {
throw new InvalidInputException(
"Some weird error happened: couldn't load properties from: "
+ configFile);
}
} catch (FileNotFoundException e) {
throw new InvalidInputException("Couldn't find config file: "
+ configFile);
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
Printer.log("Couldn't close file (?!?): " + configFile);
}
}
}
ConverterConfig.PYTHON_BIN = prop.getProperty("PYTHON_BIN", null);
ConverterConfig.BASH_BIN = prop.getProperty("BASH_BIN", null);
ConverterConfig.PERL_BIN = prop.getProperty("PERL_BIN", null);
ConverterConfig.GALAXY_URL = prop.getProperty("GALAXY_URL", null);
ConverterConfig.GALAXY_SCRIPT_DIR = prop.getProperty(
"GALAXY_SCRIPT_DIR", null);
ConverterConfig.GALAXY_API_KEY = prop.getProperty("GALAXY_API_KEY",
null);
ConverterConfig.GALAXY_COOKIE = prop.getProperty("GALAXY_COOKIE", null);
}
/**
* Checks and configures input
*
* @param cmd
* The CommandLine object that's been parsed already
*/
static void configureInput(CommandLine cmd) {
String inputFileName = cmd.getOptionValue('i');
String inputExt = FilenameUtils.getExtension(inputFileName);
ConverterConfig.INPUT_FORMAT = Format.extToFormat(inputExt);
ConverterConfig.INPUT_PATH = inputFileName;
Printer.log("Input format detected as: "
+ ConverterConfig.INPUT_FORMAT.toString());
if (ConverterConfig.INPUT_FORMAT == Format.GALAXY) {
if (!cmd.hasOption("galaxy-app-dir")) {
throw new InvalidInputException(
"Input format Galaxy requires option --galaxy-app-dir");
} else {
ConverterConfig.GALAXY_INPUT_DIR = cmd
.getOptionValue("galaxy-app-dir");
}
if (!ConverterConfig.GALAXY_INPUT_DIR.endsWith("/")) {
ConverterConfig.GALAXY_INPUT_DIR = ConverterConfig.GALAXY_INPUT_DIR
.concat("/");
}
}
File inputFile = new File(inputFileName);
if (!inputFile.exists()) {
throw new InvalidInputException("No such file: "
+ ConverterConfig.INPUT_PATH);
}
if (inputFile.isDirectory()) {
throw new InvalidInputException(
"Don't specify directory, specify a file");
}
}
/**
* Checks and configures output
*
* @param cmd
* The CommandLine object that's been parsed already
* @throws IOException
*/
static void configureOutput(CommandLine cmd) {
String outputFileName = null;
if (cmd.hasOption('c') && cmd.hasOption('o')) {
throw new InvalidInputException(
"Can't use mutually exclusive options -c and -o");
}
if (cmd.hasOption('o')) {
outputFileName = cmd.getOptionValue('o');
ConverterConfig.OUTPUT_FORMAT = Format.extToFormat(FilenameUtils
.getExtension(outputFileName));
ConverterConfig.OUTPUT_PATH = outputFileName;
} else if (cmd.hasOption("output-format")) {
String outputExt = cmd.getOptionValue("output-format");
ConverterConfig.OUTPUT_FORMAT = Format.extToFormat(outputExt);
String fileNameWithoutExt = FilenameUtils.removeExtension(cmd
.getOptionValue('i'));
outputFileName = fileNameWithoutExt + "." + outputExt;
if (cmd.hasOption('c')) {
ConverterConfig.OUTPUT = System.out;
} else {
ConverterConfig.OUTPUT_PATH = outputFileName;
}
}
if (cmd.hasOption('o')
&& cmd.hasOption("output-format")
&& !FilenameUtils.getExtension(cmd.getOptionValue('o')).equals(
cmd.getOptionValue("output-format"))) {
throw new InvalidInputException(
"Selected output format doesn't match output file name");
}
Printer.log("Output format detected as: "
+ ConverterConfig.OUTPUT_FORMAT);
if (ConverterConfig.OUTPUT_FORMAT == Format.GALAXY) {
if (!cmd.hasOption("galaxy-output-app-dir")) {
throw new InvalidInputException(
"Output format Galaxy requires option --galaxy-output-app-dir");
} else {
ConverterConfig.GALAXY_OUTPUT_DIR = cmd
.getOptionValue("galaxy-output-app-dir");
}
if (!ConverterConfig.GALAXY_OUTPUT_DIR.endsWith("/")) {
ConverterConfig.GALAXY_OUTPUT_DIR = ConverterConfig.GALAXY_OUTPUT_DIR
.concat("/");
}
}
if ((ConverterConfig.OUTPUT == null && ConverterConfig.OUTPUT_PATH == null)
|| ConverterConfig.OUTPUT_FORMAT == null) {
throw new InvalidInputException(
"You didn't specify an output path and/or format");
}
if (ConverterConfig.INPUT_PATH.equals(ConverterConfig.OUTPUT_PATH)
|| (ConverterConfig.INPUT_FORMAT == Format.GALAXY
&& ConverterConfig.OUTPUT_FORMAT == Format.GALAXY && ConverterConfig.GALAXY_INPUT_DIR
.equals(ConverterConfig.GALAXY_OUTPUT_DIR))) {
throw new InvalidInputException(
"I won't let you overwrite your input file(s)");
}
if (ConverterConfig.INPUT_FORMAT == ConverterConfig.OUTPUT_FORMAT) {
String sameFormatErrorString = "Input and output formats are the same";
if (ConverterConfig.FORCE) {
Printer.log(sameFormatErrorString);
} else {
throw new InvalidInputException(sameFormatErrorString);
}
}
if (ConverterConfig.OUTPUT_PATH != null
&& (new File(ConverterConfig.OUTPUT_PATH)).exists()) {
String outputExistsErrorString = "Output file already exists";
if (ConverterConfig.FORCE) {
Printer.log(outputExistsErrorString);
} else {
throw new InvalidInputException(outputExistsErrorString); /*
* also
* detects
* directories
* by
* the
* same
* name,
* which
* is ok
* in
* Windows
* but
* not
* in
* Unix
*/
}
}
}
/**
* Set up the options for this program.
*
* @return Options object with valid command-line arguments.
*/
static Options makeOptions() {
Options options = new Options();
Option toStdout = new Option("c", false,
"print output to stdout instead of to file (requires --output-format)");
Option configFile = new Option("C", true,
"specify config file (if necessary); defaults to pc.conf");
configFile.setArgs(1);
Option force = new Option("f", "force", false,
"force (attempt to ignore errors)");
Option input = new Option("i", "input", true, "input file");
input.setArgs(1);
input.setRequired(true);
Option output = new Option("o", "output", true,
"output file (if -c and --output-format not specified)");
output.setArgs(1);
Option outputFormat = new Option("p", "output-format", false,
"output file format (if --output not specified or -c specified)");
outputFormat.setArgs(1);
Option galaxyDir = new Option("g", "galaxy-app-dir", true,
"input directory for Galaxy .xml files");
galaxyDir.setArgs(1);
Option galaxyOutputDir = new Option("j", "galaxy-output-app-dir", true,
"output directory for Galaxy .xml files");
galaxyOutputDir.setArgs(1);
Option verbose = new Option("v", "verbose", false,
"be verbose (print debug messages to stderr)");
/*
* help option is actually ignored, because other options are
* required--missing a required option results in printing help
*/
Option help = new Option("h", "help", false, "print this help");
options.addOption(toStdout);
options.addOption(configFile);
options.addOption(force);
options.addOption(input);
options.addOption(output);
options.addOption(outputFormat);
options.addOption(galaxyDir);
options.addOption(galaxyOutputDir);
options.addOption(verbose);
options.addOption(help);
return options;
}
/**
* Convenience method for printing help.
*
* @param options
* Options object to print.
*/
static void printHelp(Options options) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("java " + PipelineConverter.class.getSimpleName(),
options, true);
}
/**
* Simply prints out that the input couldn't be converted.
*/
private static void cantConvert() {
Printer.log("Well, I tried, but I don't know how to make that kind of a file");
}
/**
* Simply prints out that the input couldn't be understood.
*/
private static void cantUnderstand() {
throw new InvalidInputException(
"Well, I tried, but I can't understand your input");
}
}