1 4 package org.oddjob.io; 5 6 import java.io.File ; 7 import java.io.FileFilter ; 8 import java.util.Arrays ; 9 import java.util.HashSet ; 10 import java.util.LinkedList ; 11 import java.util.Set ; 12 13 import org.apache.commons.io.FilenameUtils; 14 15 17 public class WildcardSpec { 18 19 private File file; 20 21 public WildcardSpec(String spec) { 22 this(new File (spec)); 23 } 24 25 public WildcardSpec(File file) { 26 this.file = file; 27 } 28 29 public File [] findFiles() { 30 DirectorySplit split = new DirectorySplit(file); 31 return findFiles(split); 32 } 33 34 public File [] findFiles(final DirectorySplit split) { 35 Set results = new HashSet (); 36 if (split.getParentFile() == null) { 37 results.add(new File (split.getName())); 39 } 40 else { 41 File [] matching = split.getParentFile().listFiles(new FileFilter () { 42 public boolean accept(File pathname) { 43 return FilenameUtils.wildcardMatchOnSystem(pathname.getName(), split.getName()); 44 } 45 }); 46 for (int i = 0; matching != null && i < matching.length; ++i) { 47 if (!split.isBottom()) { 48 if (matching[i].isDirectory()) { 49 File [] more = findFiles(split.next(matching[i].getName())); 50 results.addAll(Arrays.asList(more)); 51 } 52 } 53 else { 54 results.add(matching[i]); 55 } 56 } 57 } 58 return (File []) results.toArray(new File [0]); 59 } 60 61 static class DirectorySplit { 62 LinkedList split = new LinkedList (); 63 64 private DirectorySplit() { } 65 66 DirectorySplit(File file) { 67 for (AboveAndBelow ab = new AboveAndBelow(file); 68 true; ab = new AboveAndBelow(ab)) { 69 split.add(ab); 70 if (ab.top) { 71 break; 72 } 73 if (ab.parent.getPath().indexOf('*') < 0 && 74 ab.parent.getPath().indexOf('?') < 0) { 75 break; 76 } 77 } 78 } 79 80 File getParentFile() { 81 File parent = ((AboveAndBelow) split.getLast()).parent; 82 return parent; 83 } 84 85 String getName() { 86 return ((AboveAndBelow) split.getLast()).name; 87 } 88 89 boolean isBottom() { 90 return ((AboveAndBelow) split.getLast()).below == null; 91 } 92 93 int getSize() { 94 return split.size(); 95 } 96 97 DirectorySplit next(String name) { 98 if (split.size() == 1) { 99 return null; 100 } 101 102 DirectorySplit next = new DirectorySplit(); 103 next.split = new LinkedList (split); 104 next.split.removeLast(); 105 ((AboveAndBelow) next.split.getLast()).parent = new File (getParentFile(), name); 106 return next; 107 } 108 } 109 110 static class AboveAndBelow { 111 File parent; 112 String name; 113 File below; 114 boolean top; 115 116 AboveAndBelow(AboveAndBelow previous) { 117 if (previous.top) { 118 throw new IllegalStateException ("Previous was top."); 119 } 120 if (previous.parent == null) { 121 throw new IllegalStateException ("Previous should have been top."); 122 } 123 124 parent = previous.parent.getParentFile(); 125 if (parent == null) { 126 if (previous.parent.isAbsolute()) { 127 throw new IllegalStateException ("Previous should have been top."); 128 } 129 parent = previous.parent.getAbsoluteFile().getParentFile(); 130 top = true; 131 } 132 else { 133 if (parent.getAbsoluteFile().getParentFile() == null) { 134 top = true; 136 } 137 } 138 139 name = previous.parent.getName(); 140 141 if (previous.below == null) { 142 below = new File (previous.name); 143 } 144 else { 145 below = new File (previous.name, previous.below.getPath()); 146 } 147 } 148 149 AboveAndBelow(File first) { 150 parent = first.getParentFile(); 151 if (parent == null) { 152 parent = first.getAbsoluteFile().getParentFile(); 154 top = true; 155 } 156 name = first.getName(); 157 below = null; 158 } 159 } 160 161 163 180 public static boolean match(String pattern, String str, 181 boolean isCaseSensitive) { 182 char[] patArr = pattern.toCharArray(); 183 char[] strArr = str.toCharArray(); 184 int patIdxStart = 0; 185 int patIdxEnd = patArr.length - 1; 186 int strIdxStart = 0; 187 int strIdxEnd = strArr.length - 1; 188 char ch; 189 190 boolean containsStar = false; 191 for (int i = 0; i < patArr.length; i++) { 192 if (patArr[i] == '*') { 193 containsStar = true; 194 break; 195 } 196 } 197 198 if (!containsStar) { 199 if (patIdxEnd != strIdxEnd) { 201 return false; } 203 for (int i = 0; i <= patIdxEnd; i++) { 204 ch = patArr[i]; 205 if (ch != '?') { 206 if (isCaseSensitive && ch != strArr[i]) { 207 return false; } 209 if (!isCaseSensitive && Character.toUpperCase(ch) 210 != Character.toUpperCase(strArr[i])) { 211 return false; } 213 } 214 } 215 return true; } 217 218 if (patIdxEnd == 0) { 219 return true; } 221 222 while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) { 224 if (ch != '?') { 225 if (isCaseSensitive && ch != strArr[strIdxStart]) { 226 return false; } 228 if (!isCaseSensitive && Character.toUpperCase(ch) 229 != Character.toUpperCase(strArr[strIdxStart])) { 230 return false; } 232 } 233 patIdxStart++; 234 strIdxStart++; 235 } 236 if (strIdxStart > strIdxEnd) { 237 for (int i = patIdxStart; i <= patIdxEnd; i++) { 240 if (patArr[i] != '*') { 241 return false; 242 } 243 } 244 return true; 245 } 246 247 while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) { 249 if (ch != '?') { 250 if (isCaseSensitive && ch != strArr[strIdxEnd]) { 251 return false; } 253 if (!isCaseSensitive && Character.toUpperCase(ch) 254 != Character.toUpperCase(strArr[strIdxEnd])) { 255 return false; } 257 } 258 patIdxEnd--; 259 strIdxEnd--; 260 } 261 if (strIdxStart > strIdxEnd) { 262 for (int i = patIdxStart; i <= patIdxEnd; i++) { 265 if (patArr[i] != '*') { 266 return false; 267 } 268 } 269 return true; 270 } 271 272 while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) { 275 int patIdxTmp = -1; 276 for (int i = patIdxStart + 1; i <= patIdxEnd; i++) { 277 if (patArr[i] == '*') { 278 patIdxTmp = i; 279 break; 280 } 281 } 282 if (patIdxTmp == patIdxStart + 1) { 283 patIdxStart++; 285 continue; 286 } 287 int patLength = (patIdxTmp - patIdxStart - 1); 290 int strLength = (strIdxEnd - strIdxStart + 1); 291 int foundIdx = -1; 292 strLoop: 293 for (int i = 0; i <= strLength - patLength; i++) { 294 for (int j = 0; j < patLength; j++) { 295 ch = patArr[patIdxStart + j + 1]; 296 if (ch != '?') { 297 if (isCaseSensitive && ch != strArr[strIdxStart + i 298 + j]) { 299 continue strLoop; 300 } 301 if (!isCaseSensitive 302 && Character.toUpperCase(ch) 303 != Character.toUpperCase(strArr[strIdxStart + i + j])) { 304 continue strLoop; 305 } 306 } 307 } 308 309 foundIdx = strIdxStart + i; 310 break; 311 } 312 313 if (foundIdx == -1) { 314 return false; 315 } 316 317 patIdxStart = patIdxTmp; 318 strIdxStart = foundIdx + patLength; 319 } 320 321 for (int i = patIdxStart; i <= patIdxEnd; i++) { 324 if (patArr[i] != '*') { 325 return false; 326 } 327 } 328 return true; 329 } 330 331 } 332 | Popular Tags |