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    package org.apache.commons.cli2.option;
018    
019    import java.util.Collections;
020    import java.util.Comparator;
021    import java.util.List;
022    import java.util.ListIterator;
023    import java.util.Set;
024    
025    import org.apache.commons.cli2.DisplaySetting;
026    import org.apache.commons.cli2.HelpLine;
027    import org.apache.commons.cli2.OptionException;
028    import org.apache.commons.cli2.WriteableCommandLine;
029    import org.apache.commons.cli2.resource.ResourceConstants;
030    
031    /**
032     * Handles the java style "-Dprop=value" opions
033     */
034    public 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    }