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

com.alibaba.antx.util.cli.HelpFormatter Maven / Gradle / Ivy

There is a newer version: 1.2
Show newest version
/*
 * Copyright (c) 2002-2012 Alibaba Group Holding Limited.
 * All rights reserved.
 *
 * 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.alibaba.antx.util.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
    public static final int    DEFAULT_WIDTH           = 74;
    public static final int    DEFAULT_LEFT_PAD        = 1;
    public static final int    DEFAULT_DESC_PAD        = 3;
    public static final String DEFAULT_SYNTAX_PREFIX   = "usage: ";
    public static final String DEFAULT_OPT_PREFIX      = "-";
    public static final String DEFAULT_LONG_OPT_PREFIX = "--";
    public static final String DEFAULT_ARG_NAME        = "arg";

    // ------------------------------------------------------------------ Static
    // -------------------------------------------------------------- Attributes
    public int    defaultWidth;
    public int    defaultLeftPad;
    public int    defaultDescPad;
    public String defaultSyntaxPrefix;
    public String defaultNewLine;
    public String defaultOptPrefix;
    public String defaultLongOptPrefix;
    public String defaultArgName;

    // ------------------------------------------------------------ Constructors
    public HelpFormatter() {
        defaultWidth = DEFAULT_WIDTH;
        defaultLeftPad = DEFAULT_LEFT_PAD;
        defaultDescPad = DEFAULT_DESC_PAD;
        defaultSyntaxPrefix = DEFAULT_SYNTAX_PREFIX;
        defaultNewLine = System.getProperty("line.separator");
        defaultOptPrefix = DEFAULT_OPT_PREFIX;
        defaultLongOptPrefix = DEFAULT_LONG_OPT_PREFIX;
        defaultArgName = DEFAULT_ARG_NAME;
    }

    // ------------------------------------------------------------------ Public
    public void printHelp(String cmdLineSyntax, Options options) {
        printHelp(defaultWidth, cmdLineSyntax, null, options, null, false);
    }

    public void printHelp(String cmdLineSyntax, Options options, boolean autoUsage) {
        printHelp(defaultWidth, cmdLineSyntax, null, options, null, autoUsage);
    }

    public void printHelp(String cmdLineSyntax, String header, Options options, String footer) {
        printHelp(cmdLineSyntax, header, options, footer, false);
    }

    public void printHelp(String cmdLineSyntax, String header, Options options, String footer, boolean autoUsage) {
        printHelp(defaultWidth, cmdLineSyntax, header, options, footer, autoUsage);
    }

    public void printHelp(int width, String cmdLineSyntax, String header, Options options, String footer) {
        printHelp(width, cmdLineSyntax, header, options, footer, false);
    }

    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();
    }

    public void printHelp(PrintWriter pw, int width, String cmdLineSyntax, String header, Options options, int leftPad,
                          int descPad, String footer) throws IllegalArgumentException {
        printHelp(pw, width, cmdLineSyntax, header, options, leftPad, descPad, footer, false);
    }

    public void printHelp(PrintWriter pw, int width, String cmdLineSyntax, String header, Options options, int leftPad,
                          int descPad, String footer, boolean autoUsage) throws IllegalArgumentException {
        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 ?? * @param appName 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 ArrayList list = new ArrayList(); // temp variable Option option; // iterate over the options for (Iterator i = options.getOptions().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 and the group has not already // been processed if (group != null && !list.contains(group)) { // add the group to the processed list list.add(group); // get the names of the options from the OptionGroup Collection names = group.getNames(); buff.append("["); // for each option in the OptionGroup for (Iterator iter = names.iterator(); iter.hasNext(); ) { buff.append(iter.next()); if (iter.hasNext()) { buff.append(" | "); } } buff.append("]"); } // if the Option is not part of an OptionGroup else { // if the Option is not a required option if (!option.isRequired()) { buff.append("["); } if (!" ".equals(option.getOpt())) { buff.append("-").append(option.getOpt()); } else { buff.append("--").append(option.getLongOpt()); } if (option.hasArg()) { buff.append(" "); } // if the Option has a value if (option.hasArg()) { buff.append(option.getArgName()); } // if the Option is not a required option if (!option.isRequired()) { buff.append("]"); } buff.append(" "); } } // call printWrapped printWrapped(pw, width, buff.toString().indexOf(' ') + 1, buff.toString()); } public void printUsage(PrintWriter pw, int width, String cmdLineSyntax) { int argPos = cmdLineSyntax.indexOf(' ') + 1; printWrapped(pw, width, defaultSyntaxPrefix.length() + argPos, defaultSyntaxPrefix + cmdLineSyntax); } 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()); } public void printWrapped(PrintWriter pw, int width, String text) { printWrapped(pw, width, 0, text); } 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 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().equals(" ")) { 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; renderWrappedText(sb, width, nextLineTabStop, optBuf.append(option.getDescription()).toString()); if (i.hasNext()) { sb.append(defaultNewLine); } } return sb; } 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; } else { 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 sb with the column width width. The * wrap point is the last postion before startPos+width having a whitespace * character (space, \n, \r). * * @param sb text to be analyzed * @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; } 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; } else { //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; } } protected String createPadding(int len) { StringBuffer sb = new StringBuffer(len); for (int i = 0; i < len; ++i) { sb.append(' '); } return sb.toString(); } 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 private static class OptionComparator implements Comparator { public int compare(Object o1, Object o2) { Option opt1 = (Option) o1; Option opt2 = (Option) o2; return opt1.getOpt().toLowerCase().compareTo(opt2.getOpt().toLowerCase()); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy