📄 argumentparser.java
字号:
/*_############################################################################ _## _## SNMP4J - ArgumentParser.java _## _## Copyright (C) 2003-2008 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 org.snmp4j.util.ArgumentParser.ArgumentFormat;import java.util.regex.Pattern;import java.util.regex.Matcher;/** * The <code>ArgumentParser</code> 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. * <p> * The format specification for options is: * <pre> * [-<option>\[<type>[\<<regex>\>]{<parameter>[=<default>]}\]] ... * </pre> * where * <ul> * <li>'-' indicates a mandatory option ('+' would indicate an optional * option)</li> * <li><option> is the name of the option, for example 'h' for 'help'</li> * <li><type> is one of 'i' (integer), 'l' (long), and 's' (string)</li> * </li><regex> is a regular expression pattern that describes valid * values</li> * </li><default> is a default value. If a default value is given, then * a mandatory option is in fact optional</li> * </ul> * </p> * <p> * The format specification for parameters is: * <pre> * [-<parameter>[<type>[<<regex>>]{[=<default>]}]]... [+<optionalParameter>[<type>[<<regex>>]{[=<default>]}]]... [<..>] * </pre> * where * <ul> * <li>'-' indicates a mandatory parameter whereas '+' would indicate an * optional parameter which must not be followed by a mandatory parameter</li> * <li><parameter> is the name of the parameter, for example 'port'</li> * <li><type> is one of 'i' (integer), 'l' (long), and 's' (string)</li> * </li><regex> is a regular expression pattern that describes valid * values</li> * <li><default> is a default value</li> * <li><..> (two consecutive dots after a space at the end of the pattern) * indicate that the last parameter may occur more than once * </ul> * </p> * * @author Frank Fock * @version 1.9 */public class ArgumentParser { public static final String[] TYPES = { "i", "l", "s" }; public static final int TYPE_INTEGER = 0; public static final int TYPE_LONG = 1; public static final int TYPE_STRING = 2; private Map optionFormat; private Map 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 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, ","); List params = new ArrayList(); for (int i=1; (pt.hasMoreTokens()); i++) { String param = pt.nextToken(); ArgumentParameter ap = new ArgumentParameter(); ap.name = ""+i; if (param.endsWith(">")) { int regexPos = param.indexOf('<'); ap.pattern = Pattern.compile(param.substring(regexPos+1, param.length()-1)); param = param.substring(0, regexPos); } if (param.endsWith("}")) { ap.type = getType(param.substring(0, param.indexOf("{"))); param = param.substring(param.indexOf('{')+1, param.length()-1); int posEqual = param.indexOf('='); if (posEqual >= 0) { ap.defaultValue = param.substring(posEqual+1); ap.name = param.substring(0, posEqual); } else { ap.name = param; } } else { ap.type = getType(param); } params.add(ap); } af.params = (ArgumentParameter[]) 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 int getType(String type) { return Arrays.binarySearch(TYPES, type); } /** * Parses the given command line and returns a map of parameter/option names * to a <code>List</code> of values. Each value may be of type * <code>Integer</code>, <code>Long</code>, and <code>String</code>. * @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. */ public Map parse(String[] args) throws ParseException { Map options = new LinkedHashMap(); Iterator params = parameterFormat.values().iterator(); ArgumentFormat lastFormat = null; for (int i=0; i<args.length; i++) { ArgumentFormat format; if (args[i].charAt(0) == '-') { String option = args[i].substring(1); format = (ArgumentFormat) optionFormat.get(option); if (format == null) { throw new ParseException("Unknown option "+option, i); } } else { format = params.hasNext() ? (ArgumentFormat) params.next() : ((lastFormat != null) && (lastFormat.isVariableLength())) ? lastFormat : null; if (format == null) { throw new ParseException("Unrecognized parameter at position "+i, i); } } if ((format.getParameters() != null) && (format.getParameters().length > 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 = (List)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 = (ArgumentFormat) params.next(); if (af.isMandatory()) { throw new ArgumentParseException(-1, null, af, af.getParameters()[0]); } } for (Iterator it = optionFormat.values().iterator(); it.hasNext();) { ArgumentFormat of = (ArgumentFormat) it.next(); 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(of.getParameters()[i].getDefaultValue()); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -