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 */
017package net.dpml.cli.commandline;
018
019import java.util.ArrayList;
020import java.util.Collections;
021import java.util.HashSet;
022import java.util.Iterator;
023import java.util.List;
024import java.util.Set;
025
026import net.dpml.cli.CommandLine;
027import 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="@PUBLISHER-URL@">@PUBLISHER-NAME@</a>
038 * @version @PROJECT-VERSION@
039 * @see #appendCommandLine(CommandLine)
040 * @see #insertCommandLine(int, CommandLine)
041 */
042public 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}