package com.github.sbugat.ec2tools.service.options; import gnu.getopt.Getopt; import java.util.ArrayList; import java.util.List; import javax.inject.Singleton; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; import com.github.sbugat.ec2tools.EC2StartStopMain; /** * Service to load program arguments as valid options. * * @author Sylvain Bugat * */ @Singleton public class ProgramOptionsService { /*** SLF4J XLogger. */ private static final XLogger LOG = XLoggerFactory.getXLogger(ProgramOptionsService.class); /** Main usage line. */ private static final String USAGE = "Usage: [-l] [-e|-c|-p -s <section1> -s <section2> ... ]"; /** List option usage. */ private static final String USAGE_LIST = "[-l]: list configuration "; /** Execute option usage. */ private static final String USAGE_EXECUTE = "[-e]: execute sections orders"; /** Check option usage. */ private static final String USAGE_CHECK = "[-c]: check if sections orders can be done"; /** Post-check option usage. */ private static final String USAGE_POST_CHECK = "[-p]: check if sections orders has been done"; /** Sections option usage. */ private static final String USAGE_SECTIONS = "[-s <section1> -s <section2> ... ]: sections to process"; /** * Process all program arguments. * * @param programArgs program arguments * @return loaded program options */ public ProgramOptions processProgramArgs(final String[] programArgs) { // Arguments checking final Getopt getOpt = new Getopt(EC2StartStopMain.class.getSimpleName(), programArgs, ":lecps:"); getOpt.setOpterr(false); boolean list = false; boolean check = false; boolean execute = false; boolean postCheck = false; int exclusiveOptionsCount = 0; final List<String> sectionsToExecute = new ArrayList<String>(); int option = getOpt.getopt(); while (-1 != option) { switch (option) { case 'l': list = true; exclusiveOptionsCount++; break; case 'e': execute = true; exclusiveOptionsCount++; break; case 'c': check = true; exclusiveOptionsCount++; break; case 'p': postCheck = true; exclusiveOptionsCount++; break; case 's': sectionsToExecute.add(getOpt.getOptarg()); break; case '?': default: System.err.println(getUsage()); final IllegalArgumentException exception = new IllegalArgumentException("Unknow option:" + option); LOG.exit(exception); throw exception; } option = getOpt.getopt(); } // Missing a mandatory option if (0 == exclusiveOptionsCount) { System.err.println(getUsage()); final IllegalArgumentException exception = new IllegalArgumentException("One of list, execute, check and post-check options is mandatory "); LOG.exit(exception); throw exception; } // Multiple exclusive options else if (exclusiveOptionsCount > 1) { System.err.println(getUsage()); final IllegalArgumentException exception = new IllegalArgumentException("List, execute, check and post-check options are exclusive"); LOG.exit(exception); throw exception; } // Missing section option else if (sectionsToExecute.isEmpty() && !list) { System.err.println(getUsage()); final IllegalArgumentException exception = new IllegalArgumentException("Execute, check and post-check options need one or more section option"); LOG.exit(exception); throw exception; } // No getopt options else if (getOpt.getOptind() < programArgs.length) { System.err.println(getUsage()); final IllegalArgumentException exception = new IllegalArgumentException("Non-option argument detected, check the usage and all arguments"); LOG.exit(exception); throw exception; } // All check are OK final ProgramOptions programOptions = new ProgramOptions(execute, list, check, postCheck, sectionsToExecute); LOG.exit(programOptions); return programOptions; } /** * Return the usage multi-line String to display. * * @return usage multi-line String */ public String getUsage() { final StringBuilder usage = new StringBuilder(USAGE); usage.append(System.lineSeparator()); usage.append(USAGE_LIST); usage.append(System.lineSeparator()); usage.append(USAGE_EXECUTE); usage.append(System.lineSeparator()); usage.append(USAGE_CHECK); usage.append(System.lineSeparator()); usage.append(USAGE_POST_CHECK); usage.append(System.lineSeparator()); usage.append(USAGE_SECTIONS); return usage.toString(); } }