Clover coverage report - Dependency Finder
Coverage timestamp: Mon Nov 29 2010 15:00:50 PST
file stats: LOC: 325   Methods: 39
NCLOC: 198   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CommandLine.java 81.8% 94.5% 87.2% 90.8%
coverage coverage
 1    /*
 2    * Copyright (c) 2001-2009, Jean Tessier
 3    * All rights reserved.
 4    *
 5    * Redistribution and use in source and binary forms, with or without
 6    * modification, are permitted provided that the following conditions
 7    * are met:
 8    *
 9    * * Redistributions of source code must retain the above copyright
 10    * notice, this list of conditions and the following disclaimer.
 11    *
 12    * * Redistributions in binary form must reproduce the above copyright
 13    * notice, this list of conditions and the following disclaimer in the
 14    * documentation and/or other materials provided with the distribution.
 15    *
 16    * * Neither the name of Jean Tessier nor the names of his contributors
 17    * may be used to endorse or promote products derived from this software
 18    * without specific prior written permission.
 19    *
 20    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 21    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 22    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 23    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 24    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 25    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 26    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 27    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 28    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 29    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 30    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 31    */
 32   
 33    package com.jeantessier.commandline;
 34   
 35    import java.util.*;
 36   
 37    /**
 38    * Command-line parser.
 39    */
 40    public class CommandLine implements Visitable {
 41    private static final boolean DEFAULT_STRICT = true;
 42   
 43    private boolean strict;
 44    private ParameterStrategy parameterStrategy;
 45   
 46    private Map<String, CommandLineSwitch> map = new TreeMap<String, CommandLineSwitch>();
 47   
 48  8 public CommandLine() {
 49  8 this(DEFAULT_STRICT, new CollectingParameterStrategy());
 50    }
 51   
 52  12 public CommandLine(boolean strict) {
 53  12 this(strict, new CollectingParameterStrategy());
 54    }
 55   
 56  141 public CommandLine(ParameterStrategy parameterStrategy) {
 57  141 this(DEFAULT_STRICT, parameterStrategy);
 58    }
 59   
 60  161 public CommandLine(boolean strict, ParameterStrategy parameterStrategy) {
 61  161 setStrict(strict);
 62  161 setParameterStrategy(parameterStrategy);
 63    }
 64   
 65  658 public boolean isStrict() {
 66  658 return strict;
 67    }
 68   
 69  161 public void setStrict(boolean strict) {
 70  161 this.strict = strict;
 71    }
 72   
 73  57 public ParameterStrategy getParameterStrategy() {
 74  57 return parameterStrategy;
 75    }
 76   
 77  161 public void setParameterStrategy(ParameterStrategy parameterStrategy) {
 78  161 this.parameterStrategy = parameterStrategy;
 79    }
 80   
 81  1516 public ToggleSwitch addToggleSwitch(String name) {
 82  1516 return addSwitch(new ToggleSwitch(name));
 83    }
 84   
 85  0 public ToggleSwitch addToggleSwitch(String name, boolean defaultValue) {
 86  0 return addSwitch(new ToggleSwitch(name, defaultValue));
 87    }
 88   
 89  249 public SingleValueSwitch addSingleValueSwitch(String name) {
 90  249 return addSwitch(new SingleValueSwitch(name));
 91    }
 92   
 93  28 public SingleValueSwitch addSingleValueSwitch(String name, boolean mandatory) {
 94  28 return addSwitch(new SingleValueSwitch(name, mandatory));
 95    }
 96   
 97  317 public SingleValueSwitch addSingleValueSwitch(String name, String defaultValue) {
 98  317 return addSwitch(new SingleValueSwitch(name, defaultValue));
 99    }
 100   
 101  0 public SingleValueSwitch addSingleValueSwitch(String name, String defaultValue, boolean mandatory) {
 102  0 return addSwitch(new SingleValueSwitch(name, defaultValue, mandatory));
 103    }
 104   
 105  16 public OptionalValueSwitch addOptionalValueSwitch(String name) {
 106  16 return addSwitch(new OptionalValueSwitch(name));
 107    }
 108   
 109  0 public OptionalValueSwitch addOptionalValueSwitch(String name, boolean mandatory) {
 110  0 return addSwitch(new OptionalValueSwitch(name, mandatory));
 111    }
 112   
 113  140 public OptionalValueSwitch addOptionalValueSwitch(String name, String defaultValue) {
 114  140 return addSwitch(new OptionalValueSwitch(name, defaultValue));
 115    }
 116   
 117  0 public OptionalValueSwitch addOptionalValueSwitch(String name, String defaultValue, boolean mandatory) {
 118  0 return addSwitch(new OptionalValueSwitch(name, defaultValue, mandatory));
 119    }
 120   
 121  980 public MultipleValuesSwitch addMultipleValuesSwitch(String name) {
 122  980 return addSwitch(new MultipleValuesSwitch(name));
 123    }
 124   
 125  32 public MultipleValuesSwitch addMultipleValuesSwitch(String name, boolean mandatory) {
 126  32 return addSwitch(new MultipleValuesSwitch(name, mandatory));
 127    }
 128   
 129  109 public MultipleValuesSwitch addMultipleValuesSwitch(String name, String defaultValue) {
 130  109 return addSwitch(new MultipleValuesSwitch(name, defaultValue));
 131    }
 132   
 133  0 public MultipleValuesSwitch addMultipleValuesSwitch(String name, String defaultValue, boolean mandatory) {
 134  0 return addSwitch(new MultipleValuesSwitch(name, defaultValue, mandatory));
 135    }
 136   
 137    /**
 138    * Returns an {@link AliasSwitch} mapping name to switchNames.
 139    *
 140    * @param name the name of the new alias.
 141    * @param switchNames the switches that the alias maps to.
 142    * @return an AliasSwitch for the new alias.
 143    * @throws IllegalArgumentException if any switch name is unknown.
 144    *
 145    * @see AliasSwitch
 146    */
 147  345 public AliasSwitch addAliasSwitch(String name, String ... switchNames) {
 148  345 CommandLineSwitch[] switches = new CommandLineSwitch[switchNames.length];
 149  345 for (int i = 0; i < switchNames.length; i++) {
 150  889 switches[i] = getSwitch(switchNames[i], true);
 151    }
 152   
 153  344 return addSwitch(new AliasSwitch(name, switches));
 154    }
 155   
 156  3733 private <T extends CommandLineSwitch> T addSwitch(T cls) {
 157  3733 map.put(cls.getName(), cls);
 158  3733 return cls;
 159    }
 160   
 161    /**
 162    * Returns a {@link CommandLineSwitch} matching name, if any.
 163    *
 164    * @param name the name of the switch to lookup.
 165    * @return a switch matching name.
 166    * @throws IllegalArgumentException if this CommandLine is strict and name is unknown.
 167    *
 168    * @see CommandLineSwitch
 169    */
 170  658 public CommandLineSwitch getSwitch(String name) {
 171  658 return getSwitch(name, isStrict());
 172    }
 173   
 174    /**
 175    * Returns a {@link CommandLineSwitch} matching name, if any.
 176    *
 177    * @param name the name of the CommandLineSwitch to lookup.
 178    * @param strict if true, will throw an exception if name is unknown.
 179    * @return a CommandLineSwitch matching name.
 180    * @throws IllegalArgumentException if strict is true and name is unknown.
 181    */
 182  1547 public CommandLineSwitch getSwitch(String name, boolean strict) {
 183  1547 CommandLineSwitch cls = map.get(name);
 184   
 185  1547 if (cls == null) {
 186  3 if (strict) {
 187  1 throw new IllegalArgumentException("Unknown switch \"" + name + "\"");
 188    } else {
 189  2 cls = new OptionalValueSwitch(name);
 190  2 addSwitch(cls);
 191    }
 192    }
 193   
 194  1546 return cls;
 195    }
 196   
 197  376 public boolean getToggleSwitch(String name) {
 198  376 boolean result = false;
 199   
 200  376 CommandLineSwitch cls = map.get(name);
 201  376 if (cls != null) {
 202  376 result = (Boolean) cls.getValue();
 203    }
 204   
 205  376 return result;
 206    }
 207   
 208  16 public String getSingleSwitch(String name) {
 209  16 return getStringSwitch(name);
 210    }
 211   
 212  1 public String getOptionalSwitch(String name) {
 213  1 return getStringSwitch(name);
 214    }
 215   
 216  55 public List<String> getMultipleSwitch(String name) {
 217  55 return getListSwitch(name);
 218    }
 219   
 220  17 private String getStringSwitch(String name) {
 221  17 String result = null;
 222   
 223  17 CommandLineSwitch cls = map.get(name);
 224  17 if (cls != null) {
 225  17 result = cls.getValue().toString();
 226    }
 227   
 228  17 return result;
 229    }
 230   
 231  55 private List<String> getListSwitch(String name) {
 232  55 List<String> result = null;
 233   
 234  55 CommandLineSwitch cls = map.get(name);
 235  55 if (cls != null && cls.getValue() instanceof List) {
 236  55 result = (List<String>) cls.getValue();
 237    }
 238   
 239  55 return result;
 240    }
 241   
 242  265 public boolean isPresent(String name) {
 243  265 boolean result = false;
 244   
 245  265 CommandLineSwitch cls = map.get(name);
 246  265 if (cls != null) {
 247  265 result = cls.isPresent();
 248    }
 249   
 250  265 return result;
 251    }
 252   
 253  158 public Set<String> getKnownSwitches() {
 254  158 return map.keySet();
 255    }
 256   
 257  16 public Collection<CommandLineSwitch> getSwitches() {
 258  16 return map.values();
 259    }
 260   
 261  140 public Set<String> getPresentSwitches() {
 262  140 Set<String> result = new TreeSet<String>();
 263   
 264  140 for (String name : getKnownSwitches()) {
 265  5527 CommandLineSwitch cls = map.get(name);
 266   
 267  5527 if (cls.isPresent()) {
 268  387 result.add(name);
 269    }
 270    }
 271   
 272  140 return result;
 273    }
 274   
 275  1 public List<String> getParameters() {
 276  1 return parameterStrategy.getParameters();
 277    }
 278   
 279  141 public Collection<CommandLineException> parse(String args[]) {
 280  141 Collection<CommandLineException> exceptions = new ArrayList<CommandLineException>();
 281   
 282  141 int i=0;
 283  141 while (i < args.length) {
 284  206 try {
 285  206 if (args[i].startsWith("-")) {
 286  163 String name = args[i].substring(1);
 287  163 String value = null;
 288   
 289  163 if (i+1 < args.length && !map.containsKey(args[i+1].substring(1))) {
 290  66 value = args[i+1];
 291    }
 292   
 293  163 i += getSwitch(name).parse(value);
 294    } else {
 295  43 i += parameterStrategy.accept(args[i]);
 296    }
 297    } catch (CommandLineException e) {
 298  1 exceptions.add(e);
 299  1 i++;
 300    }
 301    }
 302   
 303    // Checking that all manadatory switches are present
 304  141 for (CommandLineSwitch cls : map.values()) {
 305  3397 try {
 306  3397 cls.validate();
 307    } catch (CommandLineException e) {
 308  28 exceptions.add(e);
 309    }
 310    }
 311   
 312    // Checking that all mandatory parameters are present
 313  141 try {
 314  141 parameterStrategy.validate();
 315    } catch (CommandLineException e) {
 316  4 exceptions.add(e);
 317    }
 318   
 319  141 return exceptions;
 320    }
 321   
 322  56 public void accept(Visitor visitor) {
 323  56 visitor.visitCommandLine(this);
 324    }
 325    }