com.thesett.common.util.CommandLineParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of junit-toolkit Show documentation
Show all versions of junit-toolkit Show documentation
JUnit Toolkit enhances JUnit with performance testing, asymptotic behaviour analysis, and concurrency testing.
/*
* Copyright The Sett Ltd, 2005 to 2014.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.thesett.common.util;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* CommandLineParser provides a utility for specifying the format of a command line and parsing command lines to ensure
* that they fit their specified format. A command line is made up of flags and options, both may be refered to as
* options. A flag is an option that does not take an argument (specifying it means it has the value 'true' and not
* specifying it means it has the value 'false'). Options must take arguments but they can be set up with defaults so
* that they take a default value when not set. Options may be mandatory in wich case it is an error not to specify them
* on the command line. Flags are never mandatory because they are implicitly set to false when not specified.
*
* Some examples command line are:
*
*
* - This one has two options that expect arguments:
*
*
* cruisecontrol -configfile cruisecontrol.xml -port 9000
*
* - This has one no-arg flag and two 'free' arguments:
*
*
* zip -r project.zip project/*
*
* - This one concatenates multiple flags into a single block with only one '-':
*
*
* jar -tvf mytar.tar
*
*
* The parsing rules are:
*
*
* - Flags may be combined after a single '-' because they never take arguments. Normally such flags are single letter
* flags but this is only a convention and not enforced. Flags of more than one letter are usually specified on their
* own.
*
- Options expecting arguments must always be on their own.
*
- The argument to an option may be seperated from it by whitespace or appended directly onto the option.
*
- The argument to an option may never begin with a '-' character.
*
- All other arguments not beginning with a '-' character are free arguments that do not belong to any option.
*
- The second or later of a set of duplicate or repeated flags override earlier ones.
*
- Options are matched up to the shortest matching option. This is because of the possibility of having no space
* between an option and its argument. This rules out the possibility of using two options where one is an opening
* substring of the other. For example, the options "foo" and "foobar" cannot be used on the same command line because
* it is not possible to distinguish the argument "-foobar" from being the "foobar" option or the "foo" option with the
* "bar" argument.
*
*
* By default, unknown options are simply ignored if specified on the command line. This behaviour may be changed so
* that the parser reports all unknowns as errors by using the {@link #setErrorsOnUnknowns} method.
*
*
CRC Card
* Responsibilities Collaborations
* Accept a command line specification.
* Parse a command line into properties, validating it against its specification.
* Report all errors between a command line and its specification.
* Provide a formatted usage string for a command line.
* Provide a formatted options in force string for a command line.
* Allow errors on unknowns behaviour to be turned on or off.
*
*
* @author Rupert Smith
*/
public class CommandLineParser
{
/**
* Holds a mapping from command line option names to detailed information about those options. Use of a tree map
* ensures that the options are easy to print in alphabetical order as a usage string. An alternative might be to
* use a LinkedHashMap to print them in the order they are specified.
*/
private final Map-
*
- The name of the option without the leading '-'. For example, "file". To specify the format of the 'free' * arguments use the option names "1", "2", ... and so on. *
- The option comment. A line of text describing the usage of the option. For example, "The file to be * processed." *
- The options argument. This is a very short description of the argument to the option, often a single word or * a reminder as to the arguments format. When this element is null the option is a flag and does not accept any * arguments. For example, "filename" or "(unix | windows)" or null. The actual text specified is only used to print * in the usage message to remind the user of the usage of the option. *
- The mandatory flag. When set to "true" an option must always be specified. Any other value, including null, * means that the option is mandatory. Flags are always mandatory (see class javadoc for explanation of why) so this * is ignored for flags. *
- A regular expression describing the format that the argument must take. Ignored if null. *
* CommandLineParser commandLine = new CommandLineParser( * new String[][] {{"file", "The file to be processed. ", "filename", "true"}, * {"dir", "Directory to store results in. Current dir used if not set.", "out dir"}, * {"os", "Operating system EOL format to use.", "(windows | unix)", null, "windows\|unix"}, * {"v", "Verbose mode. Prints information about the processing as it goes."}, * {"1", "The processing command to run.", "command", "true", "add\|remove\|list"}}); ** * @param config The configuration as an array of arrays of strings. */ public CommandLineParser(String[][] config) { // Loop through all the command line option specifications creating details for each in the options map. for (String[] nextOptionSpec : config) { addOption(nextOptionSpec[0], nextOptionSpec[1], (nextOptionSpec.length > 2) ? nextOptionSpec[2] : null, (nextOptionSpec.length > 3) && ("true".equals(nextOptionSpec[3])), (nextOptionSpec.length > 4) ? nextOptionSpec[4] : null); } } /** * Right pads a string with a given string to a given size. This method will repeat the padder string as many times * as is necessary until the exact specified size is reached. If the specified size is less than the size of the * original string then the original string is returned unchanged. * *
* Example1 - original string "cat", padder string "white", size 8 gives "catwhite". * Example2 - original string "cat", padder string "white", size 15 gives "catwhitewhitewh". * Example3 - original string "cat", padder string "white", size 2 gives "cat". ** * @param stringToPad The original string. * @param padder The string to pad onto the original string. * @param size The required size of the new string. * * @return The newly padded string. */ public static String rightPad(String stringToPad, String padder, int size) { if (padder.length() == 0) { return stringToPad; } StringBuffer strb = new StringBuffer(stringToPad); CharacterIterator sci = new StringCharacterIterator(padder); while (strb.length() < size) { for (char ch = sci.first(); ch != CharacterIterator.DONE; ch = sci.next()) { if (strb.length() < size) { strb.append(String.valueOf(ch)); } } } return strb.toString(); } /** * Lists all the parsing errors from the most recent parsing in a string. * * @return All the parsing errors from the most recent parsing. */ public String getErrors() { // Return the empty string if there are no errors. if (parsingErrors.isEmpty()) { return ""; } // Concatenate all the parsing errors together. String result = ""; for (String s : parsingErrors) { result += s; } return result; } /** * Lists the properties set from the most recent parsing or an empty string if no parsing has been done yet. * * @return The properties set from the most recent parsing or an empty string if no parsing has been done yet. */ public String getOptionsInForce() { // Check if there are no properties to report and return and empty string if so. if (parsedProperties == null) { return ""; } // List all the properties. String result = "Options in force:\n"; for (Map.Entry
© 2015 - 2024 Weber Informatics LLC | Privacy Policy