package com.dbdeploy; import com.dbdeploy.database.LineEnding; import com.dbdeploy.exceptions.UsageException; import com.dbdeploy.database.DelimiterType; import org.apache.commons.cli.*; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.File; public class DbDeployCommandLineParser { private final UserInputReader userInputReader; public DbDeployCommandLineParser() { this(new UserInputReader()); } public DbDeployCommandLineParser(UserInputReader userInputReader) { this.userInputReader = userInputReader; } public void parse(String[] args, DbDeploy dbDeploy) throws UsageException { try { dbDeploy.setScriptdirectory(new File(".")); final CommandLine commandLine = new GnuParser().parse(getOptions(), args); copyValuesFromCommandLineToDbDeployBean(dbDeploy, commandLine); if (commandLine.hasOption("password") && commandLine.getOptionValue("password") == null) { dbDeploy.setPassword(userInputReader.read("Password")); } } catch (ParseException e) { throw new UsageException(e.getMessage(), e); } } private void copyValuesFromCommandLineToDbDeployBean(DbDeploy dbDeploy, CommandLine commandLine) { try { final BeanInfo info = Introspector.getBeanInfo(dbDeploy.getClass()); for (PropertyDescriptor p : info.getPropertyDescriptors()) { final String propertyName = p.getDisplayName(); if (commandLine.hasOption(propertyName)) { Object value = commandLine.getOptionValue(propertyName); if (p.getPropertyType().isAssignableFrom(File.class)) { value = new File((String) value); } p.getWriteMethod().invoke(dbDeploy, value); } } if (commandLine.hasOption("delimitertype")) { dbDeploy.setDelimiterType(DelimiterType.valueOf(commandLine.getOptionValue("delimitertype"))); } if (commandLine.hasOption("lineending")) { dbDeploy.setLineEnding(LineEnding.valueOf(commandLine.getOptionValue("lineending"))); } } catch (Exception e) { throw new RuntimeException(e); } } public void printUsage() { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("dbdeploy", getOptions()); } @SuppressWarnings({"AccessStaticViaInstance"}) private Options getOptions() { final Options options = new Options(); options.addOption(OptionBuilder .hasArg() .withDescription("database user id") .withLongOpt("userid") .create("U")); options.addOption(OptionBuilder .hasOptionalArg() .withDescription("database password (use -P without a argument value to be prompted)") .withLongOpt("password") .create("P")); options.addOption(OptionBuilder .hasArg() .withDescription("database driver class") .withLongOpt("driver") .create("D")); options.addOption(OptionBuilder .hasArg() .withDescription("database url") .withLongOpt("url") .create("u")); options.addOption(OptionBuilder .hasArg() .withDescription("directory containing change scripts (default: .)") .withLongOpt("scriptdirectory") .create("s")); options.addOption(OptionBuilder .hasArg() .withDescription("encoding for input and output files (default: UTF-8)") .withLongOpt("encoding") .create("e")); options.addOption(OptionBuilder .hasArg() .withDescription("output file") .withLongOpt("outputfile") .create("o")); options.addOption(OptionBuilder .hasArg() .withDescription("dbms type") .withLongOpt("dbms") .create("d")); options.addOption(OptionBuilder .hasArg() .withDescription("template directory") .withLongOpt("templatedir") .create()); options.addOption(OptionBuilder .hasArg() .withDescription("name of change log table to use (default: changelog)") .withLongOpt("changeLogTableName") .create("t")); options.addOption(OptionBuilder .hasArg() .withDescription("delimiter to separate sql statements") .withLongOpt("delimiter") .create()); options.addOption(OptionBuilder .hasArg() .withDescription("delimiter type to separate sql statements (row or normal)") .withLongOpt("delimitertype") .create()); options.addOption(OptionBuilder .hasArg() .withDescription("line ending to use when applying scripts direct to db (platform, cr, crlf, lf)") .withLongOpt("lineending") .create()); return options; } }