/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * See LICENSE.txt included in this distribution for the specific * language governing permissions and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at LICENSE.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Portions Copyright (c) 2017, Steven Haehn. * Portions Copyright (c) 2019, Chris Fraire . */ package org.opengrok.indexer.util; import java.io.PrintWriter; import java.io.StringWriter; import java.io.PrintStream; import java.text.ParseException; import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * OptionParser is a class for command-line option analysis. * * Now that Java 8 has the crucial Lambda and Consumer interfaces, we can * implement a more powerful program option parsing mechanism, ala ruby * OptionParser style. * * Features * o An option can have multiple short names (-x) and multiple long * names (--xyz). Thus, an option that displays a programs usage * may be available as -h, -?, --help, --usage, and --about. * * o An option may be specified as having no argument, an optional * argument, or a required argument. Arguments may be validated * against a regular expression pattern or a list of valid values. * * o The argument specification and the code to handle it are * written in the same place. The argument description may consist * of one or more lines to be used when displaying usage summary. * * o The option summary is produced without maintaining strings * in a separate setting. * * o Users are allowed to enter initial substrings for long option * names as long as there is no ambiguity. * * o Supports the ability to coerce command line arguments into objects. * This class readily supports Boolean (yes/no,true/false,on/off), * Float, Double, Integer, and String[] (strings separated by comma) * objects. The programmer may define additional coercions of their own. * * @author Steven Haehn */ public class OptionParser { // Used to hold data type converters private static final Map, DataParser> converters = new HashMap<>(); static class DataParser { Class dataType; Function converter; DataParser(Class cls, Function converter) { this.dataType = cls; this.converter = converter; } } // Supported internal data type converters. static { accept(Integer.class, Integer::parseInt); accept(Boolean.class, OptionParser::parseVerity); accept(Float.class, Float::parseFloat); accept(Double.class, Double::parseDouble); accept(String[].class, s -> s.split(",")); } // Option object referenced by its name(s) private final Map options; // List of options in order of declaration private final List