001    /**
002     * Copyright 2004 The Apache Software Foundation
003     * Copyright 2005 Stephen McConnell
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * 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 net.dpml.cli.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.Set;
025    
026    import net.dpml.cli.CommandLine;
027    import net.dpml.cli.Option;
028    
029    /**
030     * Manages a queue of default CommandLines. This CommandLine implementation is
031     * backed by a queue of CommandLine instances which are queried in turn until a
032     * suitable result is found.
033     * 
034     * CommandLine instances can either be added to the back of the queue or can be
035     * pushed in at a specific position.
036     * 
037     * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
038     * @version 1.0.0
039     * @see #appendCommandLine(CommandLine)
040     * @see #insertCommandLine(int, CommandLine)
041     */
042    public class DefaultingCommandLine extends CommandLineImpl
043    {
044        /**
045         * The list of default CommandLine instances
046         */
047        private final List m_commandLines = new ArrayList();
048    
049        /**
050         * Adds a CommandLine instance to the back of the queue. The supplied
051         * CommandLine will be used as defaults when all other CommandLines produce
052         * no result
053         * 
054         * @param commandLine the default values to use if all CommandLines
055         */
056        public void appendCommandLine( final CommandLine commandLine )
057        {
058            m_commandLines.add( commandLine );
059        }
060        
061        /**
062         * Adds a CommandLine instance to a specified position in the queue.
063         * 
064         * @param index ths position at which to insert
065         * @param commandLine the CommandLine to insert
066         */
067        public void insertCommandLine(
068            final int index,
069            final CommandLine commandLine )
070        {
071            m_commandLines.add( index, commandLine );
072        }
073        
074        /**
075         * Builds an iterator over the build in CommandLines.
076         * 
077         * @return an unmodifiable iterator
078         */
079        public Iterator commandLines()
080        {
081            return Collections.unmodifiableList( m_commandLines ).iterator();
082        }
083    
084        /**
085         * Finds the Option with the specified trigger
086         * 
087         * @param trigger the name of the option to retrieve
088         * @return the Option matching the trigger or null if none exists
089         */
090        public Option getOption( String trigger )
091        {
092            for( final Iterator i = m_commandLines.iterator(); i.hasNext();)
093            {
094                final CommandLine commandLine = (CommandLine) i.next();
095                final Option actual = commandLine.getOption( trigger );
096                if( actual != null )
097                {
098                    return actual;
099                }
100            }
101            return null;
102        }
103    
104        /**
105         * Retrieves a list of all Options found in this CommandLine
106         * 
107         * @return a none null list of Options
108         */
109        public List getOptions()
110        {
111            final List options = new ArrayList();
112            final List temp = new ArrayList();
113            for( final Iterator i = m_commandLines.iterator(); i.hasNext();)
114            {
115                final CommandLine commandLine = (CommandLine) i.next();
116                temp.clear();
117                temp.addAll( commandLine.getOptions() );
118                temp.removeAll( options );
119                options.addAll( temp );
120            }
121            return Collections.unmodifiableList( options );
122        }
123    
124        /**
125         * Retrieves a list of all Option triggers found in this CommandLine
126         * 
127         * @return a none null list of Option triggers
128         */
129        public Set getOptionTriggers()
130        {
131            final Set all = new HashSet();
132            for( final Iterator i = m_commandLines.iterator(); i.hasNext();)
133            {
134                final CommandLine commandLine = (CommandLine) i.next();
135                all.addAll( commandLine.getOptionTriggers() );
136            }
137            return Collections.unmodifiableSet( all );
138        }
139    
140        /**
141         * Detects the presence of an option in this CommandLine.
142         * 
143         * @param option the Option to search for
144         * @return true iff the option is present
145         */
146        public boolean hasOption( Option option )
147        {
148            for( final Iterator i = m_commandLines.iterator(); i.hasNext();)
149            {
150                final CommandLine commandLine = (CommandLine) i.next();
151                if( commandLine.hasOption( option ) )
152                {
153                    return true;
154                }
155            }
156            return false;
157        }
158    
159        /**
160         * Retrieves the Argument values associated with the specified Option
161         * 
162         * @param option the Option associated with the values
163         * @param defaultValues the result to return if no values are found
164         * @return a list of values or defaultValues if none are found
165         */
166        public List getValues( Option option, List defaultValues )
167        {
168            for( final Iterator i = m_commandLines.iterator(); i.hasNext();)
169            {
170                final CommandLine commandLine = (CommandLine) i.next();
171                final List actual = commandLine.getValues( option );
172                if( actual != null && !actual.isEmpty() )
173                {
174                    return actual;
175                }
176            }
177            if( defaultValues == null )
178            {
179                return Collections.EMPTY_LIST;
180            }
181            else
182            {
183                return defaultValues;
184            }
185        }
186    
187        /**
188         * Retrieves the Boolean value associated with the specified Switch
189         * 
190         * @param option the Option associated with the value
191         * @param defaultValue the Boolean to use if none match
192         * @return the Boolean associated with option or defaultValue if none exists
193         */
194        public Boolean getSwitch( Option option, Boolean defaultValue )
195        {
196            for( final Iterator i = m_commandLines.iterator(); i.hasNext();)
197            {
198                final CommandLine commandLine = (CommandLine) i.next();
199                final Boolean actual = commandLine.getSwitch( option );
200                if( actual != null )
201                {
202                    return actual;
203                }
204            }
205            return defaultValue;
206        }
207    
208        /**
209         * Retrieves the value associated with the specified property 
210         * 
211         * @param property the property name to lookup
212         * @param defaultValue the value to use if no other is found
213         * @return the value of the property or defaultValue
214         */
215        public String getProperty( String property, String defaultValue )
216        {
217            for( final Iterator i = m_commandLines.iterator(); i.hasNext();)
218            {
219                final CommandLine commandLine = (CommandLine) i.next();
220                final String actual = commandLine.getProperty( property );
221                if( actual != null )
222                {
223                    return actual;
224                }
225            }
226            return defaultValue;
227        }
228    
229        /**
230         * Retrieves the set of all property names associated with this CommandLine
231         * 
232         * @return a none null set of property names 
233         */
234        public Set getProperties() 
235        {
236            final Set all = new HashSet();
237            for( final Iterator i = m_commandLines.iterator(); i.hasNext();)
238            {
239                final CommandLine commandLine = (CommandLine) i.next();
240                all.addAll( commandLine.getProperties() );
241            }
242            return Collections.unmodifiableSet( all );
243        }
244    }