All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.antx.util.cli.PosixParser Maven / Gradle / Ivy

There is a newer version: 1.2
Show newest version
/*
 * Copyright (c) 2002-2012 Alibaba Group Holding Limited.
 * All rights reserved.
 *
 * 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 com.alibaba.antx.util.cli;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

/**
 * The class PosixParser provides an implementation of the
 * {@link Parser#flatten(Options, String[], boolean) flatten} method.
 *
 * @author John Keyes (john at integralsource.com)
 * @see Parser
 */
public class PosixParser extends Parser {
    /** holder for flattened tokens */
    private ArrayList tokens = new ArrayList();

    /** specifies if bursting should continue */
    private boolean eatTheRest;

    /** holder for the current option */
    private Option currentOption;

    /** the command line Options */
    private Options options;

    /**
     * 

* Resets the members to their original state i.e. remove all of * tokens entries, set eatTheRest to false and set * currentOption to null. *

*/ private void init() { eatTheRest = false; tokens.clear(); currentOption = null; } /** *

* An implementation of {@link Parser}'s abstract * {@link Parser#flatten(Options, String[], boolean) flatten} method. *

*

* The following are the rules used by this flatten method. *

    *
  1. if stopAtNonOption is true then do not burst * anymore of arguments entries, just add each successive entry * without further processing. Otherwise, ignore * stopAtNonOption.
  2. *
  3. if the current arguments entry is "--" just add * the entry to the list of processed tokens
  4. *
  5. if the current arguments entry is "-" just add * the entry to the list of processed tokens
  6. *
  7. if the current arguments entry is two characters in * length and the first character is "-" then check if this is a * valid {@link Option} id. If it is a valid id, then add the entry to the * list of processed tokens and set the current {@link Option} member. If it * is not a valid id and stopAtNonOption is true, then the * remaining entries are copied to the list of processed tokens. Otherwise, * the current entry is ignored.
  8. *
  9. if the current arguments entry is more than two * characters in length and the first character is "-" then we need * to burst the entry to determine its constituents. For more information on * the bursting algorithm see * {@link PosixParser#burstToken(String, boolean) burstToken}.
  10. *
  11. if the current arguments entry is not handled by any of * the previous rules, then the entry is added to the list of processed * tokens.
  12. *
*

* * @param options The command line {@link Options} * @param arguments The command line arguments to be parsed * @param stopAtNonOption Specifies whether to stop flattening when an non * option is found. * @return The flattened arguments String array. */ @Override protected String[] flatten(Options options, String[] arguments, boolean stopAtNonOption) { init(); this.options = options; // an iterator for the command line tokens Iterator iter = Arrays.asList(arguments).iterator(); String token = null; // process each command line token while (iter.hasNext()) { // get the next command line token token = (String) iter.next(); // handle SPECIAL TOKEN if (token.startsWith("--")) { if (token.indexOf('=') != -1) { tokens.add(token.substring(0, token.indexOf('='))); tokens.add(token.substring(token.indexOf('=') + 1, token.length())); } else { processOptionToken(token, stopAtNonOption); //tokens.add(token); } } // single hyphen else if ("-".equals(token)) { processSingleHyphen(token); } else if (token.startsWith("-")) { int tokenLength = token.length(); if (tokenLength == 2) { processOptionToken(token, stopAtNonOption); } // requires bursting else { burstToken(token, stopAtNonOption); } } else { if (stopAtNonOption) { process(token); } else { tokens.add(token); } } gobble(iter); } return (String[]) tokens.toArray(new String[] { }); } /** *

* Adds the remaining tokens to the processed tokens list. *

* * @param iter An iterator over the remaining tokens */ private void gobble(Iterator iter) { if (eatTheRest) { while (iter.hasNext()) { tokens.add(iter.next()); } } } /** *

* If there is a current option and it can have an argument value then add * the token to the processed tokens list and set the current option to * null. *

*

* If there is a current option and it can have argument values then add the * token to the processed tokens list. *

*

* If there is not a current option add the special token "--" and * the current value to the processed tokens list. The add all * the remaining argument values to the processed tokens list. *

* * @param value The current token */ private void process(String value) { if (currentOption != null && currentOption.hasArg()) { if (currentOption.hasArg()) { tokens.add(value); currentOption = null; } else if (currentOption.hasArgs()) { tokens.add(value); } } else { eatTheRest = true; tokens.add("--"); tokens.add(value); } } /** *

* If it is a hyphen then add the hyphen directly to the processed tokens * list. *

* * @param hyphen The hyphen token */ private void processSingleHyphen(String hyphen) { tokens.add(hyphen); } /** *

* If an {@link Option} exists for token then set the current * option and add the token to the processed list. *

*

* If an {@link Option} does not exist and stopAtNonOption is * set then ignore the current token and add the remaining tokens to the * processed tokens list directly. *

* * @param token The current option token * @param stopAtNonOption Specifies whether flattening should halt at the * first non option. */ private void processOptionToken(String token, boolean stopAtNonOption) { if (this.options.hasOption(token)) { currentOption = this.options.getOption(token); tokens.add(token); } else if (stopAtNonOption) { eatTheRest = true; tokens.add(token); } } /** *

* Breaks token into its constituent parts using the following * algorithm. *

    *
  • ignore the first character ("-" )
  • *
  • foreach remaining character check if an {@link Option} exists with * that id.
  • *
  • if an {@link Option} does exist then add that character prepended * with "-" to the list of processed tokens.
  • *
  • if the {@link Option} can have an argument value and there are * remaining characters in the token then add the remaining characters as a * token to the list of processed tokens.
  • *
  • if an {@link Option} does NOT exist AND * stopAtNonOptionIS set then add the special token * "--" followed by the remaining characters and also the remaining * tokens directly to the processed tokens list.
  • *
  • if an {@link Option} does NOT exist AND * stopAtNonOptionIS NOT set then add that character * prepended with "-".
  • *
*

*/ protected void burstToken(String token, boolean stopAtNonOption) { int tokenLength = token.length(); for (int i = 1; i < tokenLength; i++) { String ch = String.valueOf(token.charAt(i)); boolean hasOption = options.hasOption(ch); if (hasOption) { tokens.add("-" + ch); currentOption = options.getOption(ch); if (currentOption.hasArg() && token.length() != i + 1) { tokens.add(token.substring(i + 1)); break; } } else if (stopAtNonOption) { process(token.substring(i)); } else { tokens.add("-" + ch); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy