    001/*
    002  Licensed to the Apache Software Foundation (ASF) under one or more
    003  contributor license agreements.  See the NOTICE file distributed with
    004  this work for additional information regarding copyright ownership.
    005  The ASF licenses this file to You under the Apache License, Version 2.0
    006  (the "License"); you may not use this file except in compliance with
    007  the License.  You may obtain a copy of the License at
    008
    009      https://www.apache.org/licenses/LICENSE-2.0
    010
    011  Unless required by applicable law or agreed to in writing, software
    012  distributed under the License is distributed on an "AS IS" BASIS,
    013  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014  See the License for the specific language governing permissions and
    015  limitations under the License.
    016 */
    017
    018package org.apache.commons.cli;
    019
    020import java.util.ArrayList;
    021import java.util.List;
    022
    023import org.apache.commons.cli.help.OptionFormatter;
    024
    025/**
    026 * The class GnuParser provides an implementation of the {@link Parser#flatten(Options, String[], boolean) flatten}
    027 * method.
    028 *
    029 * @deprecated Since 1.3, use the {@link DefaultParser} instead.
    030 */
    031@Deprecated
    032public class GnuParser extends Parser {
    033
    034    /**
    035     * Constructs a new instance.
    036     */
    037    public GnuParser() {
    038        // empty
    039    }
    040
    041    /**
    042     * This flatten method does so using the following rules:
    043     * <ol>
    044     * <li>If an {@link Option} exists for the first character of the {@code arguments} entry <strong>AND</strong> an
    045     * {@link Option} does not exist for the whole {@code argument} then add the first character as an option to the
    046     * processed tokens list for example "-D" and add the rest of the entry to the also.</li>
    047     * <li>Otherwise just add the token to the processed tokens list.</li>
    048     * </ol>
    049     *
    050     * @param options The Options to parse the arguments by.
    051     * @param arguments The arguments that have to be flattened.
    052     * @param stopAtNonOption specifies whether to stop flattening when a non option has been encountered.
    053     * @return a String array of the flattened arguments.
    054     */
    055    @Override
    056    protected String[] flatten(final Options options, final String[] arguments, final boolean stopAtNonOption) {
    057        final List<String> tokens = new ArrayList<>();
    058        boolean eatTheRest = false;
    059        for (int i = 0; i < arguments.length; i++) {
    060            final String arg = arguments[i];
    061            if (arg != null) {
    062                if (OptionFormatter.DEFAULT_LONG_OPT_PREFIX.equals(arg)) {
    063                    eatTheRest = true;
    064                    tokens.add(OptionFormatter.DEFAULT_LONG_OPT_PREFIX);
    065                } else if (OptionFormatter.DEFAULT_OPT_PREFIX.equals(arg)) {
    066                    tokens.add(OptionFormatter.DEFAULT_OPT_PREFIX);
    067                } else if (arg.startsWith(OptionFormatter.DEFAULT_OPT_PREFIX)) {
    068                    final String opt = Util.stripLeadingHyphens(arg);
    069                    if (options.hasOption(opt)) {
    070                        tokens.add(arg);
    071                    } else {
    072                        final int equalPos = DefaultParser.indexOfEqual(opt);
    073                        if (equalPos != -1 && options.hasOption(opt.substring(0, equalPos))) {
    074                            // the format is --foo=value or -foo=value
    075                            tokens.add(arg.substring(0, arg.indexOf(Char.EQUAL))); // --foo
    076                            tokens.add(arg.substring(arg.indexOf(Char.EQUAL) + 1)); // value
    077                        } else if (options.hasOption(arg.substring(0, 2))) {
    078                            // the format is a special properties option (-Dproperty=value)
    079                            tokens.add(arg.substring(0, 2)); // -D
    080                            tokens.add(arg.substring(2)); // property=value
    081                        } else {
    082                            eatTheRest = stopAtNonOption;
    083                            tokens.add(arg);
    084                        }
    085                    }
    086                } else {
    087                    tokens.add(arg);
    088                }
    089                if (eatTheRest) {
    090                    for (i++; i < arguments.length; i++) { // NOPMD
    091                        tokens.add(arguments[i]);
    092                    }
    093                }
    094            }
    095        }
    096        return tokens.toArray(Util.EMPTY_STRING_ARRAY);
    097    }
    098}