001    /*
002     * Copyright 2003-2005 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.validation;
018    
019    import java.io.File;
020    import java.util.List;
021    import java.util.ListIterator;
022    
023    /**
024     * The <code>FileValidator</code> validates the string argument
025     * values are files.  If the value is a file, the string value in
026     * the {@link java.util.List} of values is replaced with the
027     * {@link java.io.File} instance.
028     *
029     * The following attributes can also be specified using the 
030     * appropriate settors:
031     * <ul>
032     *  <li>existing</li>
033     *  <li>is a file</li>
034     *  <li>is a directory</li>
035     * </ul>
036     *
037     * The following example shows how to limit the valid values
038     * for the config attribute to files that exist.
039     *
040     * <pre>
041     * ...
042     * ArgumentBuilder builder = new ArgumentBuilder();
043     * FileValidator validator = FileValidator.getExistingFileInstance();
044     * Argument age = 
045     *     builder.withName("config");
046     *            .withValidator(validator);
047     * </pre>
048     * 
049     * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
050     * @version 1.0.0
051     */
052    public class FileValidator implements Validator
053    {
054        /**
055         * Returns a <code>FileValidator</code> for existing files/directories.
056         *
057         * @return a <code>FileValidator</code> for existing files/directories.
058         */
059        public static FileValidator getExistingInstance() 
060        {
061            final FileValidator validator = new FileValidator();
062            validator.setExisting( true );
063            return validator;
064        }
065    
066        /**
067         * Returns a <code>FileValidator</code> for existing files.
068         *
069         * @return a <code>FileValidator</code> for existing files.
070         */
071        public static FileValidator getExistingFileInstance()
072        {
073            final FileValidator validator = new FileValidator();
074            validator.setExisting( true );
075            validator.setFile( true );
076            return validator;
077        }
078    
079        /**
080         * Returns a <code>FileValidator</code> for existing directories.
081         *
082         * @return a <code>FileValidator</code> for existing directories.
083         */
084        public static FileValidator getExistingDirectoryInstance()
085        {
086            final FileValidator validator = new FileValidator();
087            validator.setExisting( true );
088            validator.setDirectory( true );
089            return validator;
090        }
091    
092        /** whether the argument value exists */
093        private boolean m_existing = false;
094        
095        /** whether the argument value is a directory */
096        private boolean m_directory = false;
097        
098        /** whether the argument value is a file */
099        private boolean m_file = false;
100    
101       /**
102        * Validate the list of values against the list of permitted values.
103        * If a value is valid, replace the string in the <code>values</code>
104        * {@link java.util.List} with the {@link java.io.File} instance.
105        * 
106        * @param values the list of values to validate 
107        * @exception InvalidArgumentException if a value is invalid
108        * @see net.dpml.cli.validation.Validator#validate(java.util.List)
109        */
110        public void validate( final List values ) throws InvalidArgumentException 
111        {
112            for( final ListIterator i = values.listIterator(); i.hasNext();) 
113            {
114                final Object next = i.next();
115                if( next instanceof File )
116                {
117                    return;
118                }
119                final String name = (String) next;
120                final File f = new File( name );
121                if( ( m_existing && !f.exists() )
122                  || ( m_file && !f.isFile() )
123                  || ( m_directory && !f.isDirectory() ) )
124                {
125                    throw new InvalidArgumentException( name );
126                }
127                i.set( f );
128            }
129        }
130    
131        /**
132         * Returns whether the argument values must represent directories.
133         *
134         * @return whether the argument values must represent directories.
135         */
136        public boolean isDirectory()
137        {
138            return m_directory;
139        }
140    
141        /**
142         * Specifies whether the argument values must represent directories.
143         *
144         * @param directory specifies whether the argument values must 
145         * represent directories.
146         */
147        public void setDirectory( boolean directory )
148        {
149            m_directory = directory;
150        }
151    
152        /**
153         * Returns whether the argument values must represent existing 
154         * files/directories.
155         *
156         * @return whether the argument values must represent existing 
157         * files/directories.
158         */
159        public boolean isExisting()
160        {
161            return m_existing;
162        }
163    
164        /**
165         * Specifies whether the argument values must represent existing 
166         * files/directories.
167         *
168         * @param existing specifies whether the argument values must 
169         * represent existing files/directories.
170         */
171        public void setExisting( boolean existing )
172        {
173            m_existing = existing;
174        }
175    
176        /**
177         * Returns whether the argument values must represent directories.
178         *
179         * @return whether the argument values must represent directories.
180         */
181        public boolean isFile()
182        {
183            return m_file;
184        }
185    
186        /**
187         * Specifies whether the argument values must represent files.
188         *
189         * @param file specifies whether the argument values must 
190         * represent files.
191         */
192        public void setFile( boolean file )
193        {
194            m_file = file;
195        }
196    }