org.snmp4j.util.ArgumentParser Maven / Gradle / Ivy
/*_############################################################################
_##
_## SNMP4J 2 - ArgumentParser.java
_##
_## Copyright (C) 2003-2016 Frank Fock and Jochen Katz (SNMP4J.org)
_##
_## 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 org.snmp4j.util;
import java.text.*;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import org.snmp4j.smi.OctetString;
/**
* The ArgumentParser
parsers a command line array into Java
* objects and associates each object with the corresponding command line option
* according to predefined schemes for options and parameters.
*
* The format specification for options is:
*
* [-<option>\[<type>[\<<regex>\>]{<parameter>[=<default>]}\]] ...
*
* where
*
* - '-' indicates a mandatory option ('+' would indicate an optional
* option)
* - <option> is the name of the option, for example 'h' for 'help'
* - <type> is one of 'i' (integer), 'l' (long), 'o' (octet string),
* and 's' (string)
* <regex> is a regular expression pattern that describes valid
* values
* <default> is a default value. If a default value is given, then
* a mandatory option is in fact optional
*
*
*
* The format specification for parameters is:
*
* [-<parameter>[<type>[<<regex>>]{[=<default>]}]]... [+<optionalParameter>[<type>[<<regex>>]{[=<default>]}]]... [<..>]
*
* where
*
* - '-' indicates a mandatory parameter whereas '+' would indicate an
* optional parameter which must not be followed by a mandatory parameter
* - <parameter> is the name of the parameter, for example 'port'
* - <type> is one of 'i' (integer), 'l' (long), and 's' (string)
* <regex> is a regular expression pattern that describes valid
* values
* - <default> is a default value
* - <..> (two consecutive dots after a space at the end of the pattern)
* indicate that the last parameter may occur more than once
*
*
*
* @author Frank Fock
* @version 1.10
* @since 1.9
*/
public class ArgumentParser {
public static final String[] TYPES = { "i", "l", "s", "o" };
public static final int TYPE_INTEGER = 0;
public static final int TYPE_LONG = 1;
public static final int TYPE_STRING = 2;
public static final int TYPE_OCTET_STRING = 3;
private Map optionFormat;
private Map extends String, ? extends ArgumentFormat> parameterFormat;
/**
* Creates an argument parser with the specified option and parameter formats.
* @param optionFormat
* the option format pattern to parse (see {@link ArgumentParser}).
* @param parameterFormat
* the parameter format pattern to parse (see {@link ArgumentParser}).
*/
public ArgumentParser(String optionFormat, String parameterFormat) {
this.optionFormat = parseFormat(optionFormat, false);
this.parameterFormat = parseFormat(parameterFormat, true);
}
public Map getOptionFormat() {
return optionFormat;
}
public Map extends String, ? extends ArgumentFormat> getParameterFormat() {
return parameterFormat;
}
protected static Map parseFormat(String format, boolean parameterFormat) {
Map options = new LinkedHashMap();
ArgumentFormat last = null;
StringTokenizer st = new StringTokenizer(format, " ");
while (st.hasMoreTokens()) {
String token = st.nextToken();
if ("..".equals(token)) {
if (last != null) {
last.vararg = true;
break;
}
else {
throw new IllegalArgumentException("'..' without parameter definition");
}
}
ArgumentFormat af = new ArgumentFormat();
last = af;
af.parameter = parameterFormat;
af.mandatory = (token.charAt(0) != '+');
token = token.substring(1);
if (token.endsWith("]")) {
af.option = token.substring(0, token.indexOf('['));
token = token.substring(af.option.length()+1, token.length()-1);
StringTokenizer pt = new StringTokenizer(token, ",", true);
List params = new ArrayList();
String inRegex = null;
for (int i=1; (pt.hasMoreTokens()); i++) {
String param = pt.nextToken();
if (inRegex != null) {
inRegex += param;
param = inRegex;
}
else if (",".equals(param)) {
continue;
}
if (param.indexOf('<')>0 && param.indexOf('>') <0) {
inRegex = param;
}
ArgumentParameter ap = new ArgumentParameter();
ap.name = ""+i;
if (param.endsWith("}")) {
param = parseParameterFormat(param, ap);
}
if (param.endsWith(">")) {
inRegex = null;
int regexPos = param.indexOf('<');
ap.pattern =
Pattern.compile(param.substring(regexPos+1, param.length()-1));
param = param.substring(0, regexPos);
if (param.endsWith("}")) {
parseParameterFormat(param, ap);
}
else {
ap.type = getType(param);
}
}
else if (inRegex != null) {
continue;
}
else {
ap.type = getType(param);
}
params.add(ap);
}
af.params = params.toArray(new ArgumentParameter[params.size()]);
}
else {
af.option = token;
if (af.parameter) {
throw new IllegalArgumentException("Parameter "+token+" has no type");
}
}
options.put(af.option, af);
}
return options;
}
private static String parseParameterFormat(String param, ArgumentParameter ap) {
int posEnd = param.indexOf('<');
posEnd = posEnd>0 ? posEnd : param.indexOf("{");
ap.type = getType(param.substring(0, posEnd));
String defaultValue = param.substring(param.indexOf('{')+1, param.length()-1);
int posEqual = defaultValue.indexOf('=');
if (posEqual >= 0) {
ap.defaultValue = defaultValue.substring(posEqual+1);
ap.name = defaultValue.substring(0, posEqual);
}
else {
ap.name = defaultValue;
}
int posParamEnd = param.indexOf('>');
if (posParamEnd > 0) {
posEnd = posParamEnd+1;
}
param = param.substring(0, posEnd);
return param;
}
private static int getType(String type) {
return Arrays.binarySearch(TYPES, type);
}
/**
* Parses the given command line and returns a map of parameter/option names
* to a List
of values. Each value may be of type
* Integer
, Long
, and String
.
* @param args
* the command line argument list.
* @return Map
* a map that returns options and parameters in the order they have been
* parsed, where each map entry has the option/parameter name as key and
* the value as value.
* @throws ParseException
* if the command line does not match the patterns for options and
* parameters.
*/
@SuppressWarnings("unchecked")
public Map> parse(String[] args) throws ParseException {
Map> options = new LinkedHashMap>();
Iterator extends ArgumentFormat> params = parameterFormat.values().iterator();
ArgumentFormat lastFormat = null;
for (int i=0; i 0)) {
int diff = (format.isParameter()) ? 1 : 0;
List values = parseValues(args, i+(1-diff), format);
i += Math.max(values.size() - diff, 0);
if (format.isVariableLength() &&
options.containsKey(format.getOption())) {
List extValues = options.get(format.getOption());
extValues.addAll(values);
}
else {
addValues2Option(format.getOption(), values, options);
}
}
else {
addValues2Option(format.getOption(), null, options);
}
lastFormat = format;
}
while (params.hasNext()) {
ArgumentFormat af = params.next();
if (af.isMandatory()) {
if (af.getParameters() != null && af.getParameters().length > 0) {
List defaults = new ArrayList();
for (ArgumentParameter parameter : af.getParameters()) {
if (parameter.getDefaultValue() == null) {
throw new ArgumentParseException(-1, null, af, parameter);
}
else {
defaults.add(parseParameterValue(parameter,
parameter.getDefaultValue(),
af, defaults.size()));
}
}
addValues2Option(af.getOption(), defaults, options);
}
}
else {
throw new ArgumentParseException(-1, null, af, null);
}
}
for (ArgumentFormat of : optionFormat.values()) {
if (of.isMandatory() && !options.containsKey(of.getOption())) {
List defaults = new ArrayList();
for (int i = 0; i < of.getParameters().length; i++) {
if (of.getParameters()[i].getDefaultValue() != null) {
defaults.add(parseParameterValue(of.getParameters()[i],
of.getParameters()[i].getDefaultValue(),
of, i));
}
}
if (defaults.size() == 0) {
throw new ArgumentParseException(-1, null, of, of.getParameters()[0]);
} else {
addValues2Option(of.getOption(), defaults, options);
}
}
}
return options;
}
@SuppressWarnings("unchecked")
protected void addValues2Option(String option, List values, Map> options) {
List existingValues = options.get(option);
if ((existingValues != null) && (values != null)) {
existingValues.addAll(values);
}
else {
options.put(option, values);
}
}
protected List> parseValues(String[] args, int offset, ArgumentFormat format) throws ParseException {
int numParams = format.getParameters().length;
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy