All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.testatoo.container.internal.cli.HelpFormatter Maven / Gradle / Ivy

The newest version!
/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.commons.cli;

import java.io.PrintWriter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

/** 
 * A formatter of help messages for the current command line options
 *
 * @author Slawek Zachcial
 * @author John Keyes (john at integralsource.com)
 **/
public class HelpFormatter {
    // --------------------------------------------------------------- Constants

    /** default number of characters per line */
    public static final int DEFAULT_WIDTH = 74;

    /** default padding to the left of each line */
    public static final int DEFAULT_LEFT_PAD = 1;

    /**
     * the number of characters of padding to be prefixed
     * to each description line
     */
    public static final int DEFAULT_DESC_PAD = 3;

    /** the string to display at the begining of the usage statement */
    public static final String DEFAULT_SYNTAX_PREFIX = "usage: ";

    /** default prefix for shortOpts */
    public static final String DEFAULT_OPT_PREFIX = "-";

    /** default prefix for long Option */
    public static final String DEFAULT_LONG_OPT_PREFIX = "--";

    /** default name for an argument */
    public static final String DEFAULT_ARG_NAME = "arg";

    // -------------------------------------------------------------- Attributes

    /**
     * number of characters per line
     *
     * @deprecated Scope will be made private for next major version
     * - use get/setWidth methods instead.
     */
    public int defaultWidth = DEFAULT_WIDTH;

    /**
     * amount of padding to the left of each line
     *
     * @deprecated Scope will be made private for next major version
     * - use get/setLeftPadding methods instead.
     */
    public int defaultLeftPad = DEFAULT_LEFT_PAD;

    /**
     * the number of characters of padding to be prefixed
     * to each description line
     *
     * @deprecated Scope will be made private for next major version
     * - use get/setDescPadding methods instead.
     */
    public int defaultDescPad = DEFAULT_DESC_PAD;

    /**
     * the string to display at the begining of the usage statement
     *
     * @deprecated Scope will be made private for next major version
     * - use get/setSyntaxPrefix methods instead.
     */
    public String defaultSyntaxPrefix = DEFAULT_SYNTAX_PREFIX;

    /**
     * the new line string
     *
     * @deprecated Scope will be made private for next major version
     * - use get/setNewLine methods instead.
     */
    public String defaultNewLine = System.getProperty("line.separator");

    /**
     * the shortOpt prefix
     *
     * @deprecated Scope will be made private for next major version
     * - use get/setOptPrefix methods instead.
     */
    public String defaultOptPrefix = DEFAULT_OPT_PREFIX;

    /**
     * the long Opt prefix
     *
     * @deprecated Scope will be made private for next major version
     * - use get/setLongOptPrefix methods instead.
     */
    public String defaultLongOptPrefix = DEFAULT_LONG_OPT_PREFIX;

    /**
     * the name of the argument
     *
     * @deprecated Scope will be made private for next major version
     * - use get/setArgName methods instead.
     */
    public String defaultArgName = DEFAULT_ARG_NAME;

    /**
     * Sets the 'width'.
     *
     * @param width the new value of 'width'
     */
    public void setWidth(int width)
    {
        this.defaultWidth = width;
    }

    /**
     * Returns the 'width'.
     *
     * @return the 'width'
     */
    public int getWidth()
    {
        return this.defaultWidth;
    }

    /**
     * Sets the 'leftPadding'.
     *
     * @param padding the new value of 'leftPadding'
     */
    public void setLeftPadding(int padding)
    {
        this.defaultLeftPad = padding;
    }

    /**
     * Returns the 'leftPadding'.
     *
     * @return the 'leftPadding'
     */
    public int getLeftPadding()
    {
        return this.defaultLeftPad;
    }

    /**
     * Sets the 'descPadding'.
     *
     * @param padding the new value of 'descPadding'
     */
    public void setDescPadding(int padding)
    {
        this.defaultDescPad = padding;
    }

    /**
     * Returns the 'descPadding'.
     *
     * @return the 'descPadding'
     */
    public int getDescPadding()
    {
        return this.defaultDescPad;
    }

    /**
     * Sets the 'syntaxPrefix'.
     *
     * @param prefix the new value of 'syntaxPrefix'
     */
    public void setSyntaxPrefix(String prefix)
    {
        this.defaultSyntaxPrefix = prefix;
    }

    /**
     * Returns the 'syntaxPrefix'.
     *
     * @return the 'syntaxPrefix'
     */
    public String getSyntaxPrefix()
    {
        return this.defaultSyntaxPrefix;
    }

    /**
     * Sets the 'newLine'.
     *
     * @param newline the new value of 'newLine'
     */
    public void setNewLine(String newline)
    {
        this.defaultNewLine = newline;
    }

    /**
     * Returns the 'newLine'.
     *
     * @return the 'newLine'
     */
    public String getNewLine()
    {
        return this.defaultNewLine;
    }

    /**
     * Sets the 'optPrefix'.
     *
     * @param prefix the new value of 'optPrefix'
     */
    public void setOptPrefix(String prefix)
    {
        this.defaultOptPrefix = prefix;
    }

    /**
     * Returns the 'optPrefix'.
     *
     * @return the 'optPrefix'
     */
    public String getOptPrefix()
    {
        return this.defaultOptPrefix;
    }

    /**
     * Sets the 'longOptPrefix'.
     *
     * @param prefix the new value of 'longOptPrefix'
     */
    public void setLongOptPrefix(String prefix)
    {
        this.defaultLongOptPrefix = prefix;
    }

    /**
     * Returns the 'longOptPrefix'.
     *
     * @return the 'longOptPrefix'
     */
    public String getLongOptPrefix()
    {
        return this.defaultLongOptPrefix;
    }

    /**
     * Sets the 'argName'.
     *
     * @param name the new value of 'argName'
     */
    public void setArgName(String name)
    {
        this.defaultArgName = name;
    }

    /**
     * Returns the 'argName'.
     *
     * @return the 'argName'
     */
    public String getArgName()
    {
        return this.defaultArgName;
    }


    // ------------------------------------------------------------------ Public

    /**
     * 

Print the help for options with the specified * command line syntax. This method prints help information to * System.out.

* * @param cmdLineSyntax the syntax for this application * @param options the Options instance */ public void printHelp(String cmdLineSyntax, Options options) { printHelp(defaultWidth, cmdLineSyntax, null, options, null, false); } /** *

Print the help for options with the specified * command line syntax. This method prints help information to * System.out.

* * @param cmdLineSyntax the syntax for this application * @param options the Options instance * @param autoUsage whether to print an automatically generated * usage statement */ public void printHelp(String cmdLineSyntax, Options options, boolean autoUsage) { printHelp(defaultWidth, cmdLineSyntax, null, options, null, autoUsage); } /** *

Print the help for options with the specified * command line syntax. This method prints help information to * System.out.

* * @param cmdLineSyntax the syntax for this application * @param header the banner to display at the begining of the help * @param options the Options instance * @param footer the banner to display at the end of the help */ public void printHelp(String cmdLineSyntax, String header, Options options, String footer) { printHelp(cmdLineSyntax, header, options, footer, false); } /** *

Print the help for options with the specified * command line syntax. This method prints help information to * System.out.

* * @param cmdLineSyntax the syntax for this application * @param header the banner to display at the begining of the help * @param options the Options instance * @param footer the banner to display at the end of the help * @param autoUsage whether to print an automatically generated * usage statement */ public void printHelp(String cmdLineSyntax, String header, Options options, String footer, boolean autoUsage) { printHelp(defaultWidth, cmdLineSyntax, header, options, footer, autoUsage); } /** *

Print the help for options with the specified * command line syntax. This method prints help information to * System.out.

* * @param width the number of characters to be displayed on each line * @param cmdLineSyntax the syntax for this application * @param header the banner to display at the begining of the help * @param options the Options instance * @param footer the banner to display at the end of the help */ public void printHelp(int width, String cmdLineSyntax, String header, Options options, String footer) { printHelp(width, cmdLineSyntax, header, options, footer, false); } /** *

Print the help for options with the specified * command line syntax. This method prints help information to * System.out.

* * @param width the number of characters to be displayed on each line * @param cmdLineSyntax the syntax for this application * @param header the banner to display at the begining of the help * @param options the Options instance * @param footer the banner to display at the end of the help * @param autoUsage whether to print an automatically generated * usage statement */ public void printHelp(int width, String cmdLineSyntax, String header, Options options, String footer, boolean autoUsage) { PrintWriter pw = new PrintWriter(System.out); printHelp(pw, width, cmdLineSyntax, header, options, defaultLeftPad, defaultDescPad, footer, autoUsage); pw.flush(); } /** *

Print the help for options with the specified * command line syntax.

* * @param pw the writer to which the help will be written * @param width the number of characters to be displayed on each line * @param cmdLineSyntax the syntax for this application * @param header the banner to display at the begining of the help * @param options the Options instance * @param leftPad the number of characters of padding to be prefixed * to each line * @param descPad the number of characters of padding to be prefixed * to each description line * @param footer the banner to display at the end of the help */ public void printHelp(PrintWriter pw, int width, String cmdLineSyntax, String header, Options options, int leftPad, int descPad, String footer) { printHelp(pw, width, cmdLineSyntax, header, options, leftPad, descPad, footer, false); } /** *

Print the help for options with the specified * command line syntax.

* * @param pw the writer to which the help will be written * @param width the number of characters to be displayed on each line * @param cmdLineSyntax the syntax for this application * @param header the banner to display at the begining of the help * @param options the Options instance * @param leftPad the number of characters of padding to be prefixed * to each line * @param descPad the number of characters of padding to be prefixed * to each description line * @param footer the banner to display at the end of the help * @param autoUsage whether to print an automatically generated * usage statement */ public void printHelp(PrintWriter pw, int width, String cmdLineSyntax, String header, Options options, int leftPad, int descPad, String footer, boolean autoUsage) { if ((cmdLineSyntax == null) || (cmdLineSyntax.length() == 0)) { throw new IllegalArgumentException("cmdLineSyntax not provided"); } if (autoUsage) { printUsage(pw, width, cmdLineSyntax, options); } else { printUsage(pw, width, cmdLineSyntax); } if ((header != null) && (header.trim().length() > 0)) { printWrapped(pw, width, header); } printOptions(pw, width, options, leftPad, descPad); if ((footer != null) && (footer.trim().length() > 0)) { printWrapped(pw, width, footer); } } /** *

Prints the usage statement for the specified application.

* * @param pw The PrintWriter to print the usage statement * @param width The number of characters to display per line * @param app The application name * @param options The command line Options * */ public void printUsage(PrintWriter pw, int width, String app, Options options) { // initialise the string buffer StringBuffer buff = new StringBuffer(defaultSyntaxPrefix).append(app) .append(" "); // create a list for processed option groups final Collection processedGroups = new ArrayList(); // temp variable Option option; List optList = new ArrayList(options.getOptions()); Collections.sort(optList, new OptionComparator()); // iterate over the options for (Iterator i = optList.iterator(); i.hasNext();) { // get the next Option option = (Option) i.next(); // check if the option is part of an OptionGroup OptionGroup group = options.getOptionGroup(option); // if the option is part of a group if (group != null) { // and if the group has not already been processed if (!processedGroups.contains(group)) { // add the group to the processed list processedGroups.add(group); // add the usage clause appendOptionGroup(buff, group); } // otherwise the option was displayed in the group // previously so ignore it. } // if the Option is not part of an OptionGroup else { appendOption(buff, option, option.isRequired()); } if (i.hasNext()) { buff.append(" "); } } // call printWrapped printWrapped(pw, width, buff.toString().indexOf(' ') + 1, buff.toString()); } /** * Appends the usage clause for an OptionGroup to a StringBuffer. * The clause is wrapped in square brackets if the group is required. * The display of the options is handled by appendOption * @param buff the StringBuffer to append to * @param group the group to append * @see #appendOption(StringBuffer,Option,boolean) */ private static void appendOptionGroup(final StringBuffer buff, final OptionGroup group) { if (!group.isRequired()) { buff.append("["); } List optList = new ArrayList(group.getOptions()); Collections.sort(optList, new OptionComparator()); // for each option in the OptionGroup for (Iterator i = optList.iterator(); i.hasNext();) { // whether the option is required or not is handled at group level appendOption(buff, (Option) i.next(), true); if (i.hasNext()) { buff.append(" | "); } } if (!group.isRequired()) { buff.append("]"); } } /** * Appends the usage clause for an Option to a StringBuffer. * * @param buff the StringBuffer to append to * @param option the Option to append * @param required whether the Option is required or not */ private static void appendOption(final StringBuffer buff, final Option option, final boolean required) { if (!required) { buff.append("["); } if (option.getOpt() != null) { buff.append("-").append(option.getOpt()); } else { buff.append("--").append(option.getLongOpt()); } // if the Option has a value if (option.hasArg() && (option.getArgName() != null)) { buff.append(" <").append(option.getArgName()).append(">"); } // if the Option is not a required option if (!required) { buff.append("]"); } } /** *

Print the cmdLineSyntax to the specified writer, using the * specified width.

* * @param pw The printWriter to write the help to * @param width The number of characters per line for the usage statement. * @param cmdLineSyntax The usage statement. */ public void printUsage(PrintWriter pw, int width, String cmdLineSyntax) { int argPos = cmdLineSyntax.indexOf(' ') + 1; printWrapped(pw, width, defaultSyntaxPrefix.length() + argPos, defaultSyntaxPrefix + cmdLineSyntax); } /** *

Print the help for the specified Options to the specified writer, * using the specified width, left padding and description padding.

* * @param pw The printWriter to write the help to * @param width The number of characters to display per line * @param options The command line Options * @param leftPad the number of characters of padding to be prefixed * to each line * @param descPad the number of characters of padding to be prefixed * to each description line */ public void printOptions(PrintWriter pw, int width, Options options, int leftPad, int descPad) { StringBuffer sb = new StringBuffer(); renderOptions(sb, width, options, leftPad, descPad); pw.println(sb.toString()); } /** *

Print the specified text to the specified PrintWriter.

* * @param pw The printWriter to write the help to * @param width The number of characters to display per line * @param text The text to be written to the PrintWriter */ public void printWrapped(PrintWriter pw, int width, String text) { printWrapped(pw, width, 0, text); } /** *

Print the specified text to the specified PrintWriter.

* * @param pw The printWriter to write the help to * @param width The number of characters to display per line * @param nextLineTabStop The position on the next line for the first tab. * @param text The text to be written to the PrintWriter */ public void printWrapped(PrintWriter pw, int width, int nextLineTabStop, String text) { StringBuffer sb = new StringBuffer(text.length()); renderWrappedText(sb, width, nextLineTabStop, text); pw.println(sb.toString()); } // --------------------------------------------------------------- Protected /** *

Render the specified Options and return the rendered Options * in a StringBuffer.

* * @param sb The StringBuffer to place the rendered Options into. * @param width The number of characters to display per line * @param options The command line Options * @param leftPad the number of characters of padding to be prefixed * to each line * @param descPad the number of characters of padding to be prefixed * to each description line * * @return the StringBuffer with the rendered Options contents. */ protected StringBuffer renderOptions(StringBuffer sb, int width, Options options, int leftPad, int descPad) { final String lpad = createPadding(leftPad); final String dpad = createPadding(descPad); // first create list containing only -a,--aaa where // -a is opt and --aaa is long opt; in parallel look for // the longest opt string this list will be then used to // sort options ascending int max = 0; StringBuffer optBuf; List prefixList = new ArrayList(); Option option; List optList = options.helpOptions(); Collections.sort(optList, new OptionComparator()); for (Iterator i = optList.iterator(); i.hasNext();) { option = (Option) i.next(); optBuf = new StringBuffer(8); if (option.getOpt() == null) { optBuf.append(lpad).append(" " + defaultLongOptPrefix) .append(option.getLongOpt()); } else { optBuf.append(lpad).append(defaultOptPrefix) .append(option.getOpt()); if (option.hasLongOpt()) { optBuf.append(',').append(defaultLongOptPrefix) .append(option.getLongOpt()); } } if (option.hasArg()) { if (option.hasArgName()) { optBuf.append(" <").append(option.getArgName()).append(">"); } else { optBuf.append(' '); } } prefixList.add(optBuf); max = (optBuf.length() > max) ? optBuf.length() : max; } int x = 0; for (Iterator i = optList.iterator(); i.hasNext();) { option = (Option) i.next(); optBuf = new StringBuffer(prefixList.get(x++).toString()); if (optBuf.length() < max) { optBuf.append(createPadding(max - optBuf.length())); } optBuf.append(dpad); int nextLineTabStop = max + descPad; if (option.getDescription() != null) { optBuf.append(option.getDescription()); } renderWrappedText(sb, width, nextLineTabStop, optBuf.toString()); if (i.hasNext()) { sb.append(defaultNewLine); } } return sb; } /** *

Render the specified text and return the rendered Options * in a StringBuffer.

* * @param sb The StringBuffer to place the rendered text into. * @param width The number of characters to display per line * @param nextLineTabStop The position on the next line for the first tab. * @param text The text to be rendered. * * @return the StringBuffer with the rendered Options contents. */ protected StringBuffer renderWrappedText(StringBuffer sb, int width, int nextLineTabStop, String text) { int pos = findWrapPos(text, width, 0); if (pos == -1) { sb.append(rtrim(text)); return sb; } sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine); // all following lines must be padded with nextLineTabStop space // characters final String padding = createPadding(nextLineTabStop); while (true) { text = padding + text.substring(pos).trim(); pos = findWrapPos(text, width, nextLineTabStop); if (pos == -1) { sb.append(text); return sb; } sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine); } } /** * Finds the next text wrap position after startPos for the * text in text with the column width width. * The wrap point is the last postion before startPos+width having a * whitespace character (space, \n, \r). * * @param text The text being searched for the wrap position * @param width width of the wrapped text * @param startPos position from which to start the lookup whitespace * character * @return postion on which the text must be wrapped or -1 if the wrap * position is at the end of the text */ protected int findWrapPos(String text, int width, int startPos) { int pos = -1; // the line ends before the max wrap pos or a new line char found if (((pos = text.indexOf('\n', startPos)) != -1 && pos <= width) || ((pos = text.indexOf('\t', startPos)) != -1 && pos <= width)) { return pos+1; } else if ((startPos + width) >= text.length()) { return -1; } // look for the last whitespace character before startPos+width pos = startPos + width; char c; while ((pos >= startPos) && ((c = text.charAt(pos)) != ' ') && (c != '\n') && (c != '\r')) { --pos; } // if we found it - just return if (pos > startPos) { return pos; } // must look for the first whitespace chearacter after startPos // + width pos = startPos + width; while ((pos <= text.length()) && ((c = text.charAt(pos)) != ' ') && (c != '\n') && (c != '\r')) { ++pos; } return (pos == text.length()) ? (-1) : pos; } /** *

Return a String of padding of length len.

* * @param len The length of the String of padding to create. * * @return The String of padding */ protected String createPadding(int len) { StringBuffer sb = new StringBuffer(len); for (int i = 0; i < len; ++i) { sb.append(' '); } return sb.toString(); } /** *

Remove the trailing whitespace from the specified String.

* * @param s The String to remove the trailing padding from. * * @return The String of without the trailing padding */ protected String rtrim(String s) { if ((s == null) || (s.length() == 0)) { return s; } int pos = s.length(); while ((pos > 0) && Character.isWhitespace(s.charAt(pos - 1))) { --pos; } return s.substring(0, pos); } // ------------------------------------------------------ Package protected // ---------------------------------------------------------------- Private // ---------------------------------------------------------- Inner classes /** *

This class implements the Comparator interface * for comparing Options.

*/ private static class OptionComparator implements Comparator { /** *

Compares its two arguments for order. Returns a negative * integer, zero, or a positive integer as the first argument * is less than, equal to, or greater than the second.

* * @param o1 The first Option to be compared. * @param o2 The second Option to be compared. * * @return a negative integer, zero, or a positive integer as * the first argument is less than, equal to, or greater than the * second. */ public int compare(Object o1, Object o2) { Option opt1 = (Option)o1; Option opt2 = (Option)o2; return opt1.getKey().compareToIgnoreCase(opt2.getKey()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy