<commit_before>/*
 * The MIT License
 *
 * Copyright (c) 2009 The Broad Institute
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package net.sf.picard.cmdline;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

import net.sf.picard.util.CollectionUtil.MultiMap;
import net.sf.samtools.util.StringUtil;
import net.sf.samtools.util.CloserUtil;
import net.sf.picard.PicardException;

/**
 * Annotation-driven utility for parsing command-line arguments, checking for errors, and producing usage message.
 *
 * This class supports options of the form KEY=VALUE, plus positional arguments.  Positional arguments must not contain
 * an equal sign lest they be mistaken for a KEY=VALUE pair.
 *
 * The caller must supply an object that both defines the command line and has the parsed options set into it.
 * For each possible KEY=VALUE option, there must be a public data member annotated with @Option.  The KEY name is
 * the name of the data member.  An abbreviated name may also be specified with the shortName attribute of @Option.
 * If the data member is a List<T>, then the option may be specified multiple times.  The type of the data member,
 * or the type of the List element must either have a ctor T(String), or must be an Enum.  List options must
 * be initialized by the caller with some kind of list.  Any other option that is non-null is assumed to have the given
 * value as a default.  If an option has no default value, and does not have the optional attribute of @Option set,
 * is required.  For List options, minimum and maximum number of elements may be specified in the @Option annotation.
 *
 * A single List data member may be annotated with the @PositionalArguments.  This behaves similarly to a Option
 * with List data member: the caller must initialize the data member, the type must be constructable from String, and
 * min and max number of elements may be specified.  If no @PositionalArguments annotation appears in the object,
 * then it is an error for the command line to contain positional arguments.
 *
 * A single String public data member may be annotated with @Usage.  This string, if present, is used to
 * construct the usage message.  Details about the possible options are automatically appended to this string.
 * If @Usage does not appear, a boilerplate usage message is used.
 */
public class CommandLineParser {
    // For formatting option section of usage message.
    private static final int OPTION_COLUMN_WIDTH = 30;
    private static final int DESCRIPTION_COLUMN_WIDTH = 90;

    private static final Boolean[] TRUE_FALSE_VALUES = {Boolean.TRUE, Boolean.FALSE};

    private static final String[] PACKAGES_WITH_WEB_DOCUMENTATION = {"net.sf.picard"};

    // Use these if no @Usage annotation
    private static final String defaultUsagePreamble = "Usage: program [options...]\n";
    private static final String defaultUsagePreambleWithPositionalArguments =
            "Usage: program [options...] [positional-arguments...]\n";
    private static final String OPTIONS_FILE = "OPTIONS_FILE";

    private static final String PRECEDENCE_SYMBOL = "++";

    /** name, shortName, description for options built in to framework */
    private static final String[][] FRAMEWORK_OPTION_DOC = {
            {"--help", "-h", "Displays options specific to this tool."},
            {"--stdhelp", "-H", "Displays options specific to this tool AND " +
                    "options common to all Picard command line tools."},
            {"--version", null, "Displays program version."}
    };

    private final Set<String> optionsThatCannotBeOverridden = new HashSet<String>();

    /**
     * A typical command line program will call this to get the beginning of the usage message,
     * and then append a description of the program, like this:
     *
     * \@Usage
     * public String USAGE = CommandLineParser.getStandardUsagePreamble(getClass()) + "Frobnicates the freebozzle."
     */
    public static String getStandardUsagePreamble(final Class mainClass) {
        return "USAGE: " + mainClass.getSimpleName() + " [options]\n\n" +
                (hasWebDocumentation(mainClass) ?
                        "Documentation: http://picard.sourceforge.net/command-line-overview.shtml#" +
                                mainClass.getSimpleName() + "\n\n"
                        : "");
    }

    /***
     * Determines if a class has web documentation based on its package name
     * @param clazz
     * @return
     */
    public static boolean hasWebDocumentation(final Class clazz) {
        for(final String pkg : PACKAGES_WITH_WEB_DOCUMENTATION) {
            if (clazz.getPackage().getName().startsWith(pkg)) {
                return true;
            }
        }
        return false;
    }

    /***
     * Returns the link to a FAQ
     * @return
     */
    public static String getFaqLink() {
        return "FAQ:  http://sourceforge.net/apps/mediawiki/picard/index.php?title=Main_Page";
    }
<commit_msg>Change URL printed on error to point to new Getting Help section on project web.<commit_after>/*
 * The MIT License
 *
 * Copyright (c) 2009 The Broad Institute
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package net.sf.picard.cmdline;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

import net.sf.picard.util.CollectionUtil.MultiMap;
import net.sf.samtools.util.StringUtil;
import net.sf.samtools.util.CloserUtil;
import net.sf.picard.PicardException;

/**
 * Annotation-driven utility for parsing command-line arguments, checking for errors, and producing usage message.
 *
 * This class supports options of the form KEY=VALUE, plus positional arguments.  Positional arguments must not contain
 * an equal sign lest they be mistaken for a KEY=VALUE pair.
 *
 * The caller must supply an object that both defines the command line and has the parsed options set into it.
 * For each possible KEY=VALUE option, there must be a public data member annotated with @Option.  The KEY name is
 * the name of the data member.  An abbreviated name may also be specified with the shortName attribute of @Option.
 * If the data member is a List<T>, then the option may be specified multiple times.  The type of the data member,
 * or the type of the List element must either have a ctor T(String), or must be an Enum.  List options must
 * be initialized by the caller with some kind of list.  Any other option that is non-null is assumed to have the given
 * value as a default.  If an option has no default value, and does not have the optional attribute of @Option set,
 * is required.  For List options, minimum and maximum number of elements may be specified in the @Option annotation.
 *
 * A single List data member may be annotated with the @PositionalArguments.  This behaves similarly to a Option
 * with List data member: the caller must initialize the data member, the type must be constructable from String, and
 * min and max number of elements may be specified.  If no @PositionalArguments annotation appears in the object,
 * then it is an error for the command line to contain positional arguments.
 *
 * A single String public data member may be annotated with @Usage.  This string, if present, is used to
 * construct the usage message.  Details about the possible options are automatically appended to this string.
 * If @Usage does not appear, a boilerplate usage message is used.
 */
public class CommandLineParser {
    // For formatting option section of usage message.
    private static final int OPTION_COLUMN_WIDTH = 30;
    private static final int DESCRIPTION_COLUMN_WIDTH = 90;

    private static final Boolean[] TRUE_FALSE_VALUES = {Boolean.TRUE, Boolean.FALSE};

    private static final String[] PACKAGES_WITH_WEB_DOCUMENTATION = {"net.sf.picard"};

    // Use these if no @Usage annotation
    private static final String defaultUsagePreamble = "Usage: program [options...]\n";
    private static final String defaultUsagePreambleWithPositionalArguments =
            "Usage: program [options...] [positional-arguments...]\n";
    private static final String OPTIONS_FILE = "OPTIONS_FILE";

    private static final String PRECEDENCE_SYMBOL = "++";

    /** name, shortName, description for options built in to framework */
    private static final String[][] FRAMEWORK_OPTION_DOC = {
            {"--help", "-h", "Displays options specific to this tool."},
            {"--stdhelp", "-H", "Displays options specific to this tool AND " +
                    "options common to all Picard command line tools."},
            {"--version", null, "Displays program version."}
    };

    private final Set<String> optionsThatCannotBeOverridden = new HashSet<String>();

    /**
     * A typical command line program will call this to get the beginning of the usage message,
     * and then append a description of the program, like this:
     *
     * \@Usage
     * public String USAGE = CommandLineParser.getStandardUsagePreamble(getClass()) + "Frobnicates the freebozzle."
     */
    public static String getStandardUsagePreamble(final Class mainClass) {
        return "USAGE: " + mainClass.getSimpleName() + " [options]\n\n" +
                (hasWebDocumentation(mainClass) ?
                        "Documentation: http://picard.sourceforge.net/command-line-overview.shtml#" +
                                mainClass.getSimpleName() + "\n\n"
                        : "");
    }

    /***
     * Determines if a class has web documentation based on its package name
     * @param clazz
     * @return
     */
    public static boolean hasWebDocumentation(final Class clazz) {
        for(final String pkg : PACKAGES_WITH_WEB_DOCUMENTATION) {
            if (clazz.getPackage().getName().startsWith(pkg)) {
                return true;
            }
        }
        return false;
    }

    /***
     * Returns the link to a FAQ
     * @return
     */
    public static String getFaqLink() {
        return "To get help, see http://picard.sourceforge.net/index.shtml#GettingHelp";
    }

{'fraction_non_alphanumeric': 0.07549295774647888, 'fraction_numerical': 0.0012877263581488935, 'mean_word_length': 3.311589174184594, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1687978', 'n_tokens_mistral': 3260, 'n_tokens_neox': 3104, 'n_words': 1457}