1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.xmlhammer.gui.util;
24
25 import java.io.File;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import org.apache.commons.io.filefilter.AbstractFileFilter;
30
31 /***
32 * Filters files using supplied wildcard(s).
33 * <p/>
34 * See org.apache.commons.io.find.FilenameUtils.wildcardMatch() for wildcard matching rules
35 * <p/>
36 *
37 * <p/>
38 * e.g.
39 * <pre>
40 * File dir = new File(".");
41 * FileFilter fileFilter = new WildcardFilter("*test*.java~*~");
42 * File[] files = dir.listFiles(fileFilter);
43 * for (int i = 0; i < files.length; i++) {
44 * System.out.println(files[i]);
45 * }
46 * </pre>
47 *
48 * @author Jason Anderson
49 * @version $Revision: 1.4 $ $Date: 2006/09/06 17:48:19 $
50 * @since Commons IO 1.1
51 */
52 public class WildcardFileFilter extends AbstractFileFilter {
53
54 /*** The patterns that will be used to match filenames */
55 private String[] patterns = null;
56
57 /***
58 * Construct a new wildcard filter for a single wildcard
59 *
60 * @param wildcard wildcard to match
61 * @throws IllegalArgumentException if the pattern is null
62 */
63 public WildcardFileFilter( String pattern) {
64 if (pattern == null) {
65 throw new java.lang.IllegalArgumentException();
66 }
67
68 patterns = new String[] { pattern };
69 }
70
71 /***
72 * Construct a new wildcard filter for an array of wildcards
73 *
74 * @param wildcards wildcards to match
75 * @throws IllegalArgumentException if the pattern array is null
76 */
77 public WildcardFileFilter(String[] pattern) {
78 if (pattern == null) {
79 throw new java.lang.IllegalArgumentException();
80 }
81
82 this.patterns = pattern;
83 }
84
85 /***
86 * Construct a new wildcard filter for a list of wildcards
87 *
88 * @param wildcards list of wildcards to match
89 * @throws IllegalArgumentException if the pattern list is null
90 * @throws ClassCastException if the list does not contain Strings
91 */
92 public WildcardFileFilter( List<String> patterns) {
93 if ( patterns == null) {
94 throw new java.lang.IllegalArgumentException();
95 }
96
97 this.patterns = patterns.toArray(new String[patterns.size()]);
98 }
99
100 /***
101 * Checks to see if the filename matches one of the wildcards.
102 *
103 * @param dir the file directory
104 * @param name the filename
105 * @return true if the filename matches one of the wildcards
106 */
107 public boolean accept(File dir, String name) {
108 if (dir != null && new File(dir, name).isDirectory()) {
109 return false;
110 }
111
112 for (int i = 0; i < patterns.length; i++) {
113 if ( WildcardFileFilter.wildcardMatch(name, patterns[i])) {
114 return true;
115 }
116 }
117
118 return false;
119 }
120
121 /***
122 * Checks to see if the filename matches one of the wildcards.
123 *
124 * @param file the file to check
125 * @return true if the filename matches one of the wildcards
126 */
127 public boolean accept(File file) {
128 if (file.isDirectory()) {
129 return false;
130 }
131
132 for (int i = 0; i < patterns.length; i++) {
133 if ( wildcardMatch(file.getName(), patterns[i])) {
134 return true;
135 }
136 }
137
138 return false;
139 }
140
141
142 /***
143 * Checks a filename to see if it matches the specified wildcard matcher.
144 * <p>
145 * The wildcard matcher uses the characters '?' and '*' to represent a
146 * single or multiple wildcard characters.
147 * This is the same as often found on Dos/Unix command lines.
148 * The extension check is case sensitive on Unix and case insensitive on Windows.
149 * <pre>
150 * wildcardMatch("c.txt", "*.txt") --> true
151 * wildcardMatch("c.txt", "*.jpg") --> false
152 * wildcardMatch("a/b/c.txt", "a/b/*") --> true
153 * wildcardMatch("c.txt", "*.???") --> true
154 * wildcardMatch("c.txt", "*.????") --> false
155 * </pre>
156 *
157 * @param filename the filename to match on
158 * @param wildcardMatcher the wildcard string to match against
159 * @return true if the filename matches the wilcard string
160 */
161 public static boolean wildcardMatch(String filename, String wildcardMatcher) {
162 if (filename == null && wildcardMatcher == null) {
163 return true;
164 }
165 if (filename == null || wildcardMatcher == null) {
166 return false;
167 }
168 if ( File.separatorChar == '//') {
169 filename = filename.toLowerCase();
170 wildcardMatcher = wildcardMatcher.toLowerCase();
171 }
172 String[] wcs = splitOnTokens(wildcardMatcher);
173 boolean anyChars = false;
174 int textIdx = 0;
175 int wcsIdx = 0;
176
177
178 while (wcsIdx < wcs.length && textIdx < filename.length()) {
179
180 if (wcs[wcsIdx].equals("?")) {
181
182 textIdx++;
183 anyChars = false;
184
185 } else if (wcs[wcsIdx].equals("*")) {
186
187 anyChars = true;
188
189 } else {
190
191 if (anyChars) {
192
193 textIdx = filename.indexOf(wcs[wcsIdx], textIdx);
194 if (textIdx == -1) {
195
196 return false;
197 }
198 } else {
199
200 if (!filename.startsWith(wcs[wcsIdx], textIdx)) {
201
202 return false;
203 }
204 }
205
206
207 textIdx += wcs[wcsIdx].length();
208 anyChars = false;
209 }
210
211 wcsIdx++;
212 }
213
214
215 if (wcsIdx < wcs.length) {
216
217 if (wcsIdx + 1 != wcs.length || !(wcs[wcsIdx].equals("*") || wcs[wcsIdx].equals("")) ) {
218 return false;
219 }
220 }
221
222
223 if (textIdx > filename.length()) {
224 return false;
225 }
226
227
228 if (textIdx < filename.length() && !anyChars) {
229 return false;
230 }
231
232 return true;
233 }
234
235
236
237 static String[] splitOnTokens(String text) {
238 if (text.indexOf("?") == -1 && text.indexOf("*") == -1) {
239 return new String[] { text };
240 }
241
242 char[] array = text.toCharArray();
243 ArrayList<String> list = new ArrayList<String>();
244 StringBuffer buffer = new StringBuffer();
245 for (int i = 0; i < array.length; i++) {
246 if (array[i] == '?' || array[i] == '*') {
247 if (buffer.length() != 0) {
248 list.add(buffer.toString());
249 buffer.setLength(0);
250 }
251 list.add(new String(new char[] { array[i] }));
252 } else {
253 buffer.append(array[i]);
254 }
255 }
256 if (buffer.length() != 0) {
257 list.add(buffer.toString());
258 }
259
260 return list.toArray(new String[0]);
261 }
262 }