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 */
017package org.apache.commons.cli2.option;
018
019import java.util.Collections;
020import java.util.Comparator;
021import java.util.List;
022import java.util.ListIterator;
023import java.util.Set;
024
025import org.apache.commons.cli2.DisplaySetting;
026import org.apache.commons.cli2.HelpLine;
027import org.apache.commons.cli2.OptionException;
028import org.apache.commons.cli2.WriteableCommandLine;
029import org.apache.commons.cli2.resource.ResourceConstants;
030
031/**
032 * Handles the java style "-Dprop=value" opions
033 */
034public class PropertyOption
035    extends OptionImpl {
036    public static final String DEFAULT_OPTION_STRING = "-D";
037    public static final String DEFAULT_DESCRIPTION =
038        "Passes properties and values to the application";
039
040    /**
041     * A default PropertyOption instance
042     */
043    public static final PropertyOption INSTANCE = new PropertyOption();
044    private final String optionString;
045    private final String description;
046    private final Set prefixes;
047
048    /**
049     * Creates a new PropertyOption using the default settings of a "-D" trigger
050     * and an id of 'D'
051     */
052    public PropertyOption() {
053        this(DEFAULT_OPTION_STRING, DEFAULT_DESCRIPTION, 'D');
054    }
055
056    /**
057     * Creates a new PropertyOption using the specified parameters
058     * @param optionString the trigger for the Option
059     * @param description the description of the Option
060     * @param id the id of the Option
061     */
062    public PropertyOption(final String optionString,
063                          final String description,
064                          final int id) {
065        super(id, false);
066        this.optionString = optionString;
067        this.description = description;
068        this.prefixes = Collections.singleton(optionString);
069    }
070
071    public boolean canProcess(final WriteableCommandLine commandLine,
072                              final String argument) {
073        return (argument != null) && argument.startsWith(optionString) &&
074               (argument.length() > optionString.length());
075    }
076
077    public Set getPrefixes() {
078        return prefixes;
079    }
080
081    public void process(final WriteableCommandLine commandLine,
082                        final ListIterator arguments)
083        throws OptionException {
084        final String arg = (String) arguments.next();
085
086        if (!canProcess(commandLine, arg)) {
087            throw new OptionException(this, ResourceConstants.UNEXPECTED_TOKEN, arg);
088        }
089
090        final int propertyStart = optionString.length();
091        final int equalsIndex = arg.indexOf('=', propertyStart);
092        final String property;
093        final String value;
094
095        if (equalsIndex < 0) {
096            property = arg.substring(propertyStart);
097            value = "true";
098        } else {
099            property = arg.substring(propertyStart, equalsIndex);
100            value = arg.substring(equalsIndex + 1);
101        }
102
103        commandLine.addProperty(this, property, value);
104    }
105
106    public Set getTriggers() {
107        return Collections.singleton(optionString);
108    }
109
110    public void validate(WriteableCommandLine commandLine) {
111        // PropertyOption needs no validation
112    }
113
114    public void appendUsage(final StringBuffer buffer,
115                            final Set helpSettings,
116                            final Comparator comp) {
117        final boolean display = helpSettings.contains(DisplaySetting.DISPLAY_PROPERTY_OPTION);
118
119        final boolean bracketed = helpSettings.contains(DisplaySetting.DISPLAY_ARGUMENT_BRACKETED);
120
121        if (display) {
122            buffer.append(optionString);
123
124            if (bracketed) {
125                buffer.append('<');
126            }
127
128            buffer.append("property");
129
130            if (bracketed) {
131                buffer.append('>');
132            }
133
134            buffer.append("=");
135
136            if (bracketed) {
137                buffer.append('<');
138            }
139
140            buffer.append("value");
141
142            if (bracketed) {
143                buffer.append('>');
144            }
145        }
146    }
147
148    public String getPreferredName() {
149        return optionString;
150    }
151
152    public String getDescription() {
153        return description;
154    }
155
156    public List helpLines(final int depth,
157                          final Set helpSettings,
158                          final Comparator comp) {
159        if (helpSettings.contains(DisplaySetting.DISPLAY_PROPERTY_OPTION)) {
160            final HelpLine helpLine = new HelpLineImpl(this, depth);
161
162            return Collections.singletonList(helpLine);
163        } else {
164            return Collections.EMPTY_LIST;
165        }
166    }
167}