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.commandline;
018    
019    import java.util.ArrayList;
020    import java.util.Collections;
021    import java.util.HashSet;
022    import java.util.Iterator;
023    import java.util.List;
024    import java.util.Properties;
025    import java.util.Set;
026    import java.util.StringTokenizer;
027    
028    import org.apache.commons.cli2.Option;
029    import org.apache.commons.cli2.option.PropertyOption;
030    
031    /**
032     * A CommandLine implementation using a java Properties instance, useful for
033     * constructing a complex DefaultingCommandLine
034     *
035     * Options are keyed from their property name and presence in the Properties
036     * instance is taken as presence in the CommandLine.  Argument values are taken
037     * from the property value and are optionally separated using the separator
038     * char, defined at construction time.  Switch values can be specified using a
039     * simple value of <code>true</code> or <code>false</code>; obviously this means
040     * that Switches with Arguments are not supported by this implementation.
041     *
042     * @see java.util.Properties
043     * @see org.apache.commons.cli2.commandline.DefaultingCommandLine
044     * @see org.apache.commons.cli2.Option#getPreferredName()
045     */
046    public class PropertiesCommandLine extends CommandLineImpl {
047    
048        private static final char NUL = '\0';
049        private final Properties properties;
050        private final Option root;
051        private final char separator;
052    
053        /**
054         * Creates a new PropertiesCommandLine using the specified root Option,
055         * Properties instance.  The character 0 is used as the value separator.
056         *
057         * @param root the CommandLine's root Option
058         * @param properties the Properties instance to get values from
059         */
060        public PropertiesCommandLine(final Option root, final Properties properties){
061            this(root,properties,NUL);
062        }
063    
064        /**
065         * Creates a new PropertiesCommandLine using the specified root Option,
066         * Properties instance and value separator.
067         *
068         * @param root the CommandLine's root Option
069         * @param properties the Properties instance to get values from
070         * @param separator the character to split argument values
071         */
072        public PropertiesCommandLine(final Option root, final Properties properties, final char separator){
073            this.root = root;
074            this.properties = properties;
075            this.separator = separator;
076        }
077    
078    
079        public boolean hasOption(Option option) {
080            if(option==null){
081                return false;
082            }
083            else{
084                return properties.containsKey(option.getPreferredName());
085            }
086        }
087    
088        public Option getOption(String trigger) {
089            return root.findOption(trigger);
090        }
091    
092        public List getValues(final Option option, final List defaultValues) {
093            final String value = properties.getProperty(option.getPreferredName());
094    
095            if(value==null){
096                return defaultValues;
097            }
098            else if(separator>NUL){
099                final List values = new ArrayList();
100                final StringTokenizer tokens = new StringTokenizer(value,String.valueOf(separator));
101    
102                while(tokens.hasMoreTokens()){
103                    values.add(tokens.nextToken());
104                }
105    
106                return values;
107            }
108            else{
109                return Collections.singletonList(value);
110            }
111        }
112    
113        public Boolean getSwitch(final Option option, final Boolean defaultValue) {
114            final String value = properties.getProperty(option.getPreferredName());
115            if("true".equals(value)){
116                return Boolean.TRUE;
117            }
118            else if("false".equals(value)){
119                return Boolean.FALSE;
120            }
121            else{
122                return defaultValue;
123            }
124        }
125    
126        public String getProperty(final String property) {
127            return getProperty(new PropertyOption(), property);
128        }
129    
130        public String getProperty(final Option option, final String property, final String defaultValue) {
131            return properties.getProperty(property,defaultValue);
132        }
133    
134            public Set getProperties(final Option option) {
135            return properties.keySet();
136        }
137    
138        public Set getProperties() {
139            return getProperties(new PropertyOption());
140        }
141    
142        public List getOptions() {
143            final List options = new ArrayList();
144            final Iterator keys = properties.keySet().iterator();
145            while(keys.hasNext()){
146                final String trigger = (String)keys.next();
147                final Option option = root.findOption(trigger);
148                if(option!=null){
149                    options.add(option);
150                }
151            }
152            return Collections.unmodifiableList(options);
153        }
154    
155        public Set getOptionTriggers() {
156            final Set triggers = new HashSet();
157            final Iterator options = getOptions().iterator();
158            while(options.hasNext()){
159                final Option option = (Option)options.next();
160                triggers.addAll(option.getTriggers());
161            }
162            return Collections.unmodifiableSet(triggers);
163        }
164    }