    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     *     http://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
    018    package org.apache.commons.cli;
    019
    020    import java.util.ArrayList;
    021    import java.util.List;
    022
    023    /**
    024     * The class GnuParser provides an implementation of the
    025     * {@link Parser#flatten(Options, String[], boolean) flatten} method.
    026     *
    027     * @author John Keyes (john at integralsource.com)
    028     * @version $Revision: 680644 $, $Date: 2008-07-29 01:13:48 -0700 (Tue, 29 Jul 2008) $
    029     */
    030    public class GnuParser extends Parser
    031    {
    032        /**
    033         * This flatten method does so using the following rules:
    034         * <ol>
    035         *   <li>If an {@link Option} exists for the first character of
    036         *   the <code>arguments</code> entry <b>AND</b> an {@link Option}
    037         *   does not exist for the whole <code>argument</code> then
    038         *   add the first character as an option to the processed tokens
    039         *   list e.g. "-D" and add the rest of the entry to the also.</li>
    040         *   <li>Otherwise just add the token to the processed tokens list.</li>
    041         * </ol>
    042         *
    043         * @param options         The Options to parse the arguments by.
    044         * @param arguments       The arguments that have to be flattened.
    045         * @param stopAtNonOption specifies whether to stop flattening when
    046         *                        a non option has been encountered
    047         * @return a String array of the flattened arguments
    048         */
    049        protected String[] flatten(Options options, String[] arguments, boolean stopAtNonOption)
    050        {
    051            List tokens = new ArrayList();
    052
    053            boolean eatTheRest = false;
    054
    055            for (int i = 0; i < arguments.length; i++)
    056            {
    057                String arg = arguments[i];
    058
    059                if ("--".equals(arg))
    060                {
    061                    eatTheRest = true;
    062                    tokens.add("--");
    063                }
    064                else if ("-".equals(arg))
    065                {
    066                    tokens.add("-");
    067                }
    068                else if (arg.startsWith("-"))
    069                {
    070                    String opt = Util.stripLeadingHyphens(arg);
    071
    072                    if (options.hasOption(opt))
    073                    {
    074                        tokens.add(arg);
    075                    }
    076                    else
    077                    {
    078                        if (opt.indexOf('=') != -1 && options.hasOption(opt.substring(0, opt.indexOf('='))))
    079                        {
    080                            // the format is --foo=value or -foo=value
    081                            tokens.add(arg.substring(0, arg.indexOf('='))); // --foo
    082                            tokens.add(arg.substring(arg.indexOf('=') + 1)); // value
    083                        }
    084                        else if (options.hasOption(arg.substring(0, 2)))
    085                        {
    086                            // the format is a special properties option (-Dproperty=value)
    087                            tokens.add(arg.substring(0, 2)); // -D
    088                            tokens.add(arg.substring(2)); // property=value
    089                        }
    090                        else
    091                        {
    092                            eatTheRest = stopAtNonOption;
    093                            tokens.add(arg);
    094                        }
    095                    }
    096                }
    097                else
    098                {
    099                    tokens.add(arg);
    100                }
    101
    102                if (eatTheRest)
    103                {
    104                    for (i++; i < arguments.length; i++)
    105                    {
    106                        tokens.add(arguments[i]);
    107                    }
    108                }
    109            }
    110
    111            return (String[]) tokens.toArray(new String[tokens.size()]);
    112        }
    113    }