1 9 package com.vladium.util; 10 11 15 public 16 abstract class WCMatcher 17 { 18 20 21 public static WCMatcher compile (final String pattern) 22 { 23 if (pattern == null) throw new IllegalArgumentException ("null input: pattern"); 24 25 final char [] chars = pattern.toCharArray (); final int charsLength = chars.length; 27 28 if (charsLength == 0) 29 return EMPTY_MATCHER; else 31 { 32 int patternLength = 0, starCount = 0, questionCount = 0; 33 boolean star = false; 34 35 for (int c = 0; c < charsLength; ++ c) 36 { 37 final char ch = chars [c]; 38 if (ch == '*') 39 { 40 if (! star) 41 { 42 star = true; 43 ++ starCount; 44 chars [patternLength ++] = '*'; 45 } 46 } 47 else 48 { 49 star = false; 50 if (ch == '?') ++ questionCount; 51 chars [patternLength ++] = ch; 52 } 53 } 54 55 57 if ((starCount == 1) && (questionCount == 0)) 58 { 59 if (patternLength == 1) 60 return ALL_MATCHER; 61 else if (chars [0] == '*') 62 return new EndsWithMatcher (chars, patternLength); 63 else if (chars [patternLength - 1] == '*') 64 return new StartsWithMatcher (chars, patternLength); 65 } 66 67 return new PatternMatcher (chars, patternLength); 68 } 69 } 70 71 public abstract boolean matches (String s); 72 public abstract boolean matches (char [] chars); 73 74 75 104 105 106 108 110 111 WCMatcher () {} 112 113 115 116 private static final class AllMatcher extends WCMatcher 117 { 118 public final boolean matches (final String s) 119 { 120 if (s == null) throw new IllegalArgumentException ("null input: s"); 121 122 return true; 123 } 124 125 public final boolean matches (final char [] chars) 126 { 127 if (chars == null) throw new IllegalArgumentException ("null input: chars"); 128 129 return true; 130 } 131 132 } 134 135 private static final class EmptyMatcher extends WCMatcher 136 { 137 public final boolean matches (final String s) 138 { 139 if (s == null) throw new IllegalArgumentException ("null input: s"); 140 141 return false; 142 } 143 144 public final boolean matches (final char [] chars) 145 { 146 if (chars == null) throw new IllegalArgumentException ("null input: chars"); 147 148 return chars.length == 0; 149 } 150 151 } 153 154 private static final class StartsWithMatcher extends WCMatcher 155 { 156 public final boolean matches (final String s) 157 { 158 if (s == null) throw new IllegalArgumentException ("null input: s"); 159 160 return s.startsWith (m_prefix); 161 } 162 163 public final boolean matches (final char [] chars) 164 { 165 if (chars == null) throw new IllegalArgumentException ("null input: chars"); 166 167 final char [] prefixChars = m_prefixChars; 168 final int prefixLength = prefixChars.length - 1; 169 170 if (chars.length < prefixLength) return false; 171 172 for (int c = 0; c < prefixLength; ++ c) 173 { 174 if (chars [c] != prefixChars [c]) return false; 175 } 176 177 return true; 178 } 179 180 StartsWithMatcher (final char [] pattern, final int patternLength) 181 { 182 m_prefixChars = pattern; 183 m_prefix = new String (pattern, 0, patternLength - 1); 184 } 185 186 private final char [] m_prefixChars; 187 private final String m_prefix; 188 189 } 191 192 private static final class EndsWithMatcher extends WCMatcher 193 { 194 public final boolean matches (final String s) 195 { 196 if (s == null) throw new IllegalArgumentException ("null input: s"); 197 198 return s.endsWith (m_suffix); 199 } 200 201 public final boolean matches (final char [] chars) 202 { 203 if (chars == null) throw new IllegalArgumentException ("null input: chars"); 204 205 final char [] suffixChars = m_suffixChars; 206 final int suffixLength = suffixChars.length - 1; 207 final int charsLength = chars.length; 208 209 if (charsLength < suffixLength) return false; 210 211 for (int c = 0; c < suffixLength; ++ c) 212 { 213 if (chars [charsLength - 1 - c] != suffixChars [suffixLength - c]) return false; 214 } 215 216 return true; 217 } 218 219 EndsWithMatcher (final char [] pattern, final int patternLength) 220 { 221 m_suffixChars = pattern; 222 m_suffix = new String (pattern, 1, patternLength - 1); 223 } 224 225 private final char [] m_suffixChars; 226 private final String m_suffix; 227 228 } 230 231 private static final class PatternMatcher extends WCMatcher 232 { 233 public final boolean matches (final String s) 234 { 235 if (s == null) throw new IllegalArgumentException ("null input: s"); 236 237 final char [] string = s.toCharArray (); final int stringLength = string.length; 239 240 final char [] pattern = m_pattern; 241 final int patternLength = m_patternLength; 242 243 245 int si = 0, pi = 0; 246 boolean star = false; 247 248 249 next: while (true) 250 { 251 253 int i = 0; 254 for ( ; pi + i < patternLength; ++ i) 255 { 256 final char patternChar = pattern [pi + i]; 257 258 if (patternChar == '*') 259 { 260 si += i; 261 pi += (i + 1); 262 263 star = true; 264 continue next; 265 } 266 267 final int si_i = si + i; 268 269 if (si_i == stringLength) return false; 270 271 if (patternChar != string [si_i]) 272 { 273 if (patternChar == '?') continue; 274 275 if (! star) return false; 276 ++ si; 277 278 continue next; 279 } 280 281 } 283 if (si + i == stringLength) return true; 284 285 if (! star) return false; 286 ++ si; 287 288 } 290 } 291 292 293 public final boolean matches (final char [] string) 294 { 295 if (string == null) throw new IllegalArgumentException ("null input: string"); 296 297 final int stringLength = string.length; 298 299 final char [] pattern = m_pattern; 300 final int patternLength = m_patternLength; 301 302 304 int si = 0, pi = 0; 305 boolean star = false; 306 307 308 next: while (true) 309 { 310 312 int i = 0; 313 for ( ; pi + i < patternLength; ++ i) 314 { 315 final char patternChar = pattern [pi + i]; 316 317 if (patternChar == '*') 318 { 319 si += i; 320 pi += (i + 1); 321 322 star = true; 323 continue next; 324 } 325 326 final int si_i = si + i; 327 328 if (si_i == stringLength) return false; 329 330 if (patternChar != string [si_i]) 331 { 332 if (patternChar == '?') continue; 333 334 if (! star) return false; 335 ++ si; 336 337 continue next; 338 } 339 340 } 342 if (si + i == stringLength) return true; 343 344 if (! star) return false; 345 ++ si; 346 347 } 349 } 350 351 PatternMatcher (final char [] pattern, final int patternLength) 352 { 353 m_pattern = pattern; 354 m_patternLength = patternLength; 355 } 356 357 358 private final char [] m_pattern; 359 private final int m_patternLength; 360 361 } 363 364 private static final WCMatcher ALL_MATCHER = new AllMatcher (); 365 private static final WCMatcher EMPTY_MATCHER = new EmptyMatcher (); 366 367 } | Popular Tags |