/* * Strongback * Copyright 2015, Strongback and individual contributors by the @authors tag. * See the COPYRIGHT.txt in the distribution for a full listing of individual * contributors. * * Licensed under the MIT License; you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://opensource.org/licenses/MIT * 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.strongback.tools.utils; import java.security.InvalidParameterException; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * Zero setup argument parser. * @author Zach Anderson * */ public class Parser { /** * String based argument parser, syntax information and arguments that require a parameter are specified as strings. * Does not handle any usage or help information, that should be printed elsewhere. Parses an array of GNU style command * line arguments and populates a {@link Map}. Arguments without a parameter (flags) are mapped to null. Arguments * that do have a parameter are mapped to that parameter. * @param args arguments to parse * @param params a String list of arguments that require parameters {@code "abc"} means arguments a, b, and c all require parameters * @param syntax a String representing the syntax of the arguments. Each possible set of required arguments should be listed * separated by a {@code |}. Any arguments required to not be present should be preceded by a {@code !}. Any * arguments not mentioned are assumed to always be valid. If the argument list does not meet this syntax, an * {@link InvalidParameterException} is thrown. * Example: {@code "abc|d!e|e!d|fgh"} - a, b, and c are required, or d is required and e cannot be present, and so on. * @return a {@link Map} mapping <{@link String}s to {@link String}s representing all of the command line arguments. */ public static Map<String, String> parse(String[] args, String params, String syntax) { Map<String, String> map = new HashMap<>(); String lastArg = ""; for(String arg : args) { if(arg.length()>0) { if(arg.startsWith("-")) { if(arg.startsWith("--")) { // Hook for handling long options } else { for(char c : arg.toCharArray()) { lastArg = String.valueOf(c); map.put(lastArg, null); } } } else { map.put(lastArg, arg); } } } // Verify arguments have required parameters for(char key : params.toCharArray()) { if(map.containsKey(String.valueOf(key)) && map.get(String.valueOf(key))==null) throw new InvalidParameterException("Missing parameter for argument: -"+key); } // Test syntax (pipe is a regex character) for(String req : syntax.split("\\|")) { boolean failed = false; for(int i = 0; i < req.length(); i++) { if(req.charAt(i)=='!') { // Failure if map contains the next character if(map.containsKey(String.valueOf(req.charAt(++i)))) failed = true; } else { // Failure if map doesn't contain this character if(!map.containsKey(String.valueOf(req.charAt(i)))) failed = true; } } if(!failed) return Collections.unmodifiableMap(map); } throw new InvalidParameterException("Bad syntax"); } }