1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.cli2.validation;
18
19 import java.io.File;
20 import java.util.List;
21 import java.util.ListIterator;
22
23 /**
24 * The <code>FileValidator</code> validates the string argument
25 * values are files. If the value is a file, the string value in
26 * the {@link java.util.List} of values is replaced with the
27 * {@link java.io.File} instance.
28 *
29 * The following attributes can also be specified using the
30 * appropriate settors:
31 * <ul>
32 * <li>writable</li>
33 * <li>readable</li>
34 * <li>hidden</li>
35 * <li>existing</li>
36 * <li>is a file</li>
37 * <li>is a directory</li>
38 * </ul>
39 *
40 * The following example shows how to limit the valid values
41 * for the config attribute to files that are readable, writeable,
42 * and that already existing.
43 *
44 * <pre>
45 * ...
46 * ArgumentBuilder builder = new ArgumentBuilder();
47 * FileValidator validator = FileValidator.getExistingFileInstance();
48 * validator.setReadable(true);
49 * validator.setWritable(true);
50 *
51 * Argument age =
52 * builder.withName("config");
53 * .withValidator(validator);
54 * </pre>
55 *
56 * @author Rob Oxspring
57 * @author John Keyes
58 */
59 public class FileValidator implements Validator {
60
61 /**
62 * Returns a <code>FileValidator</code> for existing files/directories.
63 *
64 * @return a <code>FileValidator</code> for existing files/directories.
65 */
66 public static FileValidator getExistingInstance() {
67 final FileValidator validator = new FileValidator();
68 validator.setExisting(true);
69 return validator;
70 }
71
72 /**
73 * Returns a <code>FileValidator</code> for existing files.
74 *
75 * @return a <code>FileValidator</code> for existing files.
76 */
77 public static FileValidator getExistingFileInstance() {
78 final FileValidator validator = new FileValidator();
79 validator.setExisting(true);
80 validator.setFile(true);
81 return validator;
82 }
83
84 /**
85 * Returns a <code>FileValidator</code> for existing directories.
86 *
87 * @return a <code>FileValidator</code> for existing directories.
88 */
89 public static FileValidator getExistingDirectoryInstance() {
90 final FileValidator validator = new FileValidator();
91 validator.setExisting(true);
92 validator.setDirectory(true);
93 return validator;
94 }
95
96 /** whether the argument value is readable */
97 private boolean readable = false;
98
99 /** whether the argument value is writable */
100 private boolean writable = false;
101
102 /** whether the argument value exists */
103 private boolean existing = false;
104
105 /** whether the argument value is a directory */
106 private boolean directory = false;
107
108 /** whether the argument value is a file */
109 private boolean file = false;
110
111 /** whether the argument value is a hidden file or directory */
112 private boolean hidden = false;
113
114 /**
115 * Validate the list of values against the list of permitted values.
116 * If a value is valid, replace the string in the <code>values</code>
117 * {@link java.util.List} with the {@link java.io.File} instance.
118 *
119 * @see org.apache.commons.cli2.validation.Validator#validate(java.util.List)
120 */
121 public void validate(final List values) throws InvalidArgumentException {
122 for (final ListIterator i = values.listIterator(); i.hasNext();) {
123 final String name = (String)i.next();
124 final File f = new File(name);
125
126 if ((existing && !f.exists())
127 || (file && !f.isFile())
128 || (directory && !f.isDirectory())
129 || (hidden && !f.isHidden())
130 || (readable && !f.canRead())
131 || (writable && !f.canWrite())) {
132
133 throw new InvalidArgumentException(name);
134 }
135
136 i.set(f);
137 }
138 }
139
140 /**
141 * Returns whether the argument values must represent directories.
142 *
143 * @return whether the argument values must represent directories.
144 */
145 public boolean isDirectory() {
146 return directory;
147 }
148
149 /**
150 * Specifies whether the argument values must represent directories.
151 *
152 * @param directory specifies whether the argument values must
153 * represent directories.
154 */
155 public void setDirectory(boolean directory) {
156 this.directory = directory;
157 }
158
159 /**
160 * Returns whether the argument values must represent existing
161 * files/directories.
162 *
163 * @return whether the argument values must represent existing
164 * files/directories.
165 */
166 public boolean isExisting() {
167 return existing;
168 }
169
170 /**
171 * Specifies whether the argument values must represent existing
172 * files/directories.
173 *
174 * @param existing specifies whether the argument values must
175 * represent existing files/directories.
176 */
177 public void setExisting(boolean existing) {
178 this.existing = existing;
179 }
180
181 /**
182 * Returns whether the argument values must represent directories.
183 *
184 * @return whether the argument values must represent directories.
185 */
186 public boolean isFile() {
187 return file;
188 }
189
190 /**
191 * Specifies whether the argument values must represent files.
192 *
193 * @param file specifies whether the argument values must
194 * represent files.
195 */
196 public void setFile(boolean file) {
197 this.file = file;
198 }
199
200 /**
201 * Returns whether the argument values must represent hidden
202 * files/directories.
203 *
204 * @return whether the argument values must represent hidden
205 * files/directories.
206 */
207 public boolean isHidden() {
208 return hidden;
209 }
210
211 /**
212 * Specifies whether the argument values must represent hidden
213 * files/directories.
214 *
215 * @param hidden specifies whether the argument values must
216 * represent hidden files/directories.
217 */
218 public void setHidden(boolean hidden) {
219 this.hidden = hidden;
220 }
221
222 /**
223 * Returns whether the argument values must represent readable
224 * files/directories.
225 *
226 * @return whether the argument values must represent readable
227 * files/directories.
228 */
229 public boolean isReadable() {
230 return readable;
231 }
232
233 /**
234 * Specifies whether the argument values must represent readable
235 * files/directories.
236 *
237 * @param readable specifies whether the argument values must
238 * represent readable files/directories.
239 */
240 public void setReadable(boolean readable) {
241 this.readable = readable;
242 }
243
244 /**
245 * Returns whether the argument values must represent writable
246 * files/directories.
247 *
248 * @return whether the argument values must represent writable
249 * files/directories.
250 */
251 public boolean isWritable() {
252 return writable;
253 }
254
255 /**
256 * Specifies whether the argument values must represent writable
257 * files/directories.
258 *
259 * @param writable specifies whether the argument values must
260 * represent writable files/directories.
261 */
262 public void setWritable(boolean writable) {
263 this.writable = writable;
264 }
265 }