diff --git a/CHANGES.txt b/CHANGES.txt index 71f10949674..7ca79be1edf 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -81,6 +81,9 @@ Trunk (unreleased changes) HADOOP-7175. Add isEnabled() to Trash. (Daryn Sharp via szetszwo) + HADOOP-7180. Better support on CommandFormat on the API and exceptions. + (Daryn Sharp via szetszwo) + OPTIMIZATIONS BUG FIXES diff --git a/src/java/org/apache/hadoop/fs/shell/CommandFormat.java b/src/java/org/apache/hadoop/fs/shell/CommandFormat.java index c1d84d3670c..36eed94921b 100644 --- a/src/java/org/apache/hadoop/fs/shell/CommandFormat.java +++ b/src/java/org/apache/hadoop/fs/shell/CommandFormat.java @@ -18,9 +18,12 @@ package org.apache.hadoop.fs.shell; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** * Parse the args of a command and check the format of args. @@ -40,29 +43,47 @@ public class CommandFormat { } /** Parse parameters starting from the given position + * Consider using the variant that directly takes a List * * @param args an array of input arguments * @param pos the position at which starts to parse * @return a list of parameters */ public List parse(String[] args, int pos) { - List parameters = new ArrayList(); - for(; pos < args.length; pos++) { - if (args[pos].charAt(0) == '-' && args[pos].length() > 1) { - String opt = args[pos].substring(1); - if (options.containsKey(opt)) - options.put(opt, Boolean.TRUE); - else - throw new IllegalArgumentException("Illegal option " + args[pos]); - } - else - parameters.add(args[pos]); - } - int psize = parameters.size(); - if (psize < minPar || psize > maxPar) - throw new IllegalArgumentException("Illegal number of arguments"); + List parameters = new ArrayList(Arrays.asList(args)); + parameters.subList(0, pos).clear(); + parse(parameters); return parameters; } + + /** Parse parameters from the given list of args. The list is + * destructively modified to remove the options. + * + * @param args as a list of input arguments + */ + public void parse(List args) { + int pos = 0; + while (pos < args.size()) { + String arg = args.get(pos); + if (arg.startsWith("-") && arg.length() > 1) { + String opt = arg.substring(1); + if (!options.containsKey(opt)) { + throw new UnknownOptionException(arg); + } + args.remove(pos); + options.put(opt, Boolean.TRUE); + } else { + pos++; + } + } + int psize = args.size(); + if (psize < minPar) { + throw new NotEnoughArgumentsException(minPar, psize); + } + if (psize > maxPar) { + throw new TooManyArgumentsException(maxPar, psize); + } + } /** Return if the option is set or not * @@ -70,6 +91,84 @@ public class CommandFormat { * @return true is the option is set; false otherwise */ public boolean getOpt(String option) { - return options.get(option); + return options.containsKey(option) ? options.get(option) : false; + } + + /** Returns all the options that are set + * + * @return Set of the enabled options + */ + public Set getOpts() { + Set optSet = new HashSet(); + for (Map.Entry entry : options.entrySet()) { + if (entry.getValue()) { + optSet.add(entry.getKey()); + } + } + return optSet; + } + + /** Used when the arguments exceed their bounds + */ + public static abstract class IllegalNumberOfArgumentsException + extends IllegalArgumentException { + private static final long serialVersionUID = 0L; + protected int expected; + protected int actual; + + protected IllegalNumberOfArgumentsException(int want, int got) { + expected = want; + actual = got; + } + + public String getMessage() { + return "expected " + expected + " but got " + actual; + } + } + + /** Used when too many arguments are supplied to a command + */ + public static class TooManyArgumentsException + extends IllegalNumberOfArgumentsException { + private static final long serialVersionUID = 0L; + + public TooManyArgumentsException(int expected, int actual) { + super(expected, actual); + } + + public String getMessage() { + return "Too many arguments: " + super.getMessage(); + } + } + + /** Used when too few arguments are supplied to a command + */ + public static class NotEnoughArgumentsException + extends IllegalNumberOfArgumentsException { + private static final long serialVersionUID = 0L; + + public NotEnoughArgumentsException(int expected, int actual) { + super(expected, actual); + } + + public String getMessage() { + return "Not enough arguments: " + super.getMessage(); + } + } + + /** Used when an unsupported option is supplied to a command + */ + public static class UnknownOptionException extends IllegalArgumentException { + private static final long serialVersionUID = 0L; + protected String option = null; + + public UnknownOptionException(String unknownOption) { + super("Illegal option " + unknownOption); + option = unknownOption; + } + + public String getOption() { + return option; + } } }