| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
| WildcardFileFilter |
|
| 0.0;0 |
| 1 | /* |
|
| 2 | * $Id: WildcardFileFilter.java,v 1.4 2006/09/06 17:48:19 edankert Exp $ |
|
| 3 | * |
|
| 4 | * The contents of this file are subject to the Mozilla Public License |
|
| 5 | * Version 1.1 (the "License"); you may not use this file except in |
|
| 6 | * compliance with the License. You may obtain a copy of the License at |
|
| 7 | * http://www.mozilla.org/MPL/ |
|
| 8 | * |
|
| 9 | * Software distributed under the License is distributed on an "AS IS" basis, |
|
| 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
|
| 11 | * for the specific language governing rights and limitations under the License. |
|
| 12 | * |
|
| 13 | * The Original Code is XML Hammer code. (org.xmlhammer.*) |
|
| 14 | * |
|
| 15 | * The Initial Developer of the Original Code is Edwin Dankert. Portions created |
|
| 16 | * by the Initial Developer are Copyright (C) 2002 - 2006 the Initial Developer. |
|
| 17 | * All Rights Reserved. |
|
| 18 | * |
|
| 19 | * Contributor(s): Edwin Dankert <edankert@gmail.com> |
|
| 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 | 44 | 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 | 44 | public WildcardFileFilter( String pattern) { |
| 64 | 44 | if (pattern == null) { |
| 65 | 0 | throw new java.lang.IllegalArgumentException(); |
| 66 | } |
|
| 67 | ||
| 68 | 44 | patterns = new String[] { pattern }; |
| 69 | 44 | } |
| 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 | 0 | public WildcardFileFilter(String[] pattern) { |
| 78 | 0 | if (pattern == null) { |
| 79 | 0 | throw new java.lang.IllegalArgumentException(); |
| 80 | } |
|
| 81 | ||
| 82 | 0 | this.patterns = pattern; |
| 83 | 0 | } |
| 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 | 0 | public WildcardFileFilter( List<String> patterns) { |
| 93 | 0 | if ( patterns == null) { |
| 94 | 0 | throw new java.lang.IllegalArgumentException(); |
| 95 | } |
|
| 96 | ||
| 97 | 0 | this.patterns = patterns.toArray(new String[patterns.size()]); |
| 98 | 0 | } |
| 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 | 0 | if (dir != null && new File(dir, name).isDirectory()) { |
| 109 | 0 | return false; |
| 110 | } |
|
| 111 | ||
| 112 | 0 | for (int i = 0; i < patterns.length; i++) { |
| 113 | 0 | if ( WildcardFileFilter.wildcardMatch(name, patterns[i])) { |
| 114 | 0 | return true; |
| 115 | } |
|
| 116 | } |
|
| 117 | ||
| 118 | 0 | 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 | 352 | if (file.isDirectory()) { |
| 129 | 132 | return false; |
| 130 | } |
|
| 131 | ||
| 132 | 308 | for (int i = 0; i < patterns.length; i++) { |
| 133 | 220 | if ( wildcardMatch(file.getName(), patterns[i])) { |
| 134 | 132 | return true; |
| 135 | } |
|
| 136 | } |
|
| 137 | ||
| 138 | 88 | 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 | 220 | if (filename == null && wildcardMatcher == null) { |
| 163 | 0 | return true; |
| 164 | } |
|
| 165 | 220 | if (filename == null || wildcardMatcher == null) { |
| 166 | 0 | return false; |
| 167 | } |
|
| 168 | 220 | if ( File.separatorChar == '\\') { |
| 169 | 220 | filename = filename.toLowerCase(); |
| 170 | 220 | wildcardMatcher = wildcardMatcher.toLowerCase(); |
| 171 | } |
|
| 172 | 220 | String[] wcs = splitOnTokens(wildcardMatcher); |
| 173 | 220 | boolean anyChars = false; |
| 174 | 220 | int textIdx = 0; |
| 175 | 220 | int wcsIdx = 0; |
| 176 | ||
| 177 | // loop whilst tokens and text left to process |
|
| 178 | 572 | while (wcsIdx < wcs.length && textIdx < filename.length()) { |
| 179 | ||
| 180 | 440 | if (wcs[wcsIdx].equals("?")) { |
| 181 | // ? so move to next text char |
|
| 182 | 0 | textIdx++; |
| 183 | 0 | anyChars = false; |
| 184 | ||
| 185 | 0 | } else if (wcs[wcsIdx].equals("*")) { |
| 186 | // set any chars status |
|
| 187 | 220 | anyChars = true; |
| 188 | ||
| 189 | 220 | } else { |
| 190 | // matching text token |
|
| 191 | 220 | if (anyChars) { |
| 192 | // any chars then try to locate text token |
|
| 193 | 220 | textIdx = filename.indexOf(wcs[wcsIdx], textIdx); |
| 194 | 220 | if (textIdx == -1) { |
| 195 | // token not found |
|
| 196 | 88 | return false; |
| 197 | } |
|
| 198 | } else { |
|
| 199 | // matching from current position |
|
| 200 | 0 | if (!filename.startsWith(wcs[wcsIdx], textIdx)) { |
| 201 | // couldnt match token |
|
| 202 | 0 | return false; |
| 203 | } |
|
| 204 | } |
|
| 205 | ||
| 206 | // matched text token, move text index to end of matched token |
|
| 207 | 132 | textIdx += wcs[wcsIdx].length(); |
| 208 | 132 | anyChars = false; |
| 209 | } |
|
| 210 | ||
| 211 | 352 | wcsIdx++; |
| 212 | 352 | } |
| 213 | ||
| 214 | // didnt match all wildcards |
|
| 215 | 132 | if (wcsIdx < wcs.length) { |
| 216 | // ok if one remaining and wildcard or empty |
|
| 217 | 0 | if (wcsIdx + 1 != wcs.length || !(wcs[wcsIdx].equals("*") || wcs[wcsIdx].equals("")) ) { |
| 218 | 0 | return false; |
| 219 | } |
|
| 220 | } |
|
| 221 | ||
| 222 | // ran out of text chars |
|
| 223 | 132 | if (textIdx > filename.length()) { |
| 224 | 0 | return false; |
| 225 | } |
|
| 226 | ||
| 227 | // didnt match all text chars, only ok if any chars set |
|
| 228 | 132 | if (textIdx < filename.length() && !anyChars) { |
| 229 | 0 | return false; |
| 230 | } |
|
| 231 | ||
| 232 | 132 | return true; |
| 233 | } |
|
| 234 | ||
| 235 | // used by wildcardMatch |
|
| 236 | // package level so a unit test may run on this |
|
| 237 | static String[] splitOnTokens(String text) { |
|
| 238 | 220 | if (text.indexOf("?") == -1 && text.indexOf("*") == -1) { |
| 239 | 0 | return new String[] { text }; |
| 240 | } |
|
| 241 | ||
| 242 | 220 | char[] array = text.toCharArray(); |
| 243 | 220 | ArrayList<String> list = new ArrayList<String>(); |
| 244 | 220 | StringBuffer buffer = new StringBuffer(); |
| 245 | 1320 | for (int i = 0; i < array.length; i++) { |
| 246 | 1100 | if (array[i] == '?' || array[i] == '*') { |
| 247 | 220 | if (buffer.length() != 0) { |
| 248 | 0 | list.add(buffer.toString()); |
| 249 | 0 | buffer.setLength(0); |
| 250 | } |
|
| 251 | 220 | list.add(new String(new char[] { array[i] })); |
| 252 | 220 | } else { |
| 253 | 880 | buffer.append(array[i]); |
| 254 | } |
|
| 255 | } |
|
| 256 | 220 | if (buffer.length() != 0) { |
| 257 | 220 | list.add(buffer.toString()); |
| 258 | } |
|
| 259 | ||
| 260 | 220 | return list.toArray(new String[0]); |
| 261 | } |
|
| 262 | } |