1 19 20 package org.netbeans.spi.project.support.ant; 21 22 import java.io.File ; 23 import java.util.Collections ; 24 import java.util.HashSet ; 25 import java.util.Iterator ; 26 import java.util.Set ; 27 import java.util.SortedSet ; 28 import java.util.StringTokenizer ; 29 import java.util.TreeSet ; 30 import java.util.regex.Matcher ; 31 import java.util.regex.Pattern ; 32 33 86 public final class PathMatcher { 87 88 private final String includes, excludes; 89 private final Pattern includePattern, excludePattern; 90 private final File base; 91 private final Set <String > knownIncludes; 92 93 101 public PathMatcher(String includes, String excludes, File base) { 102 this.includes = includes; 103 this.excludes = excludes; 104 includePattern = computePattern(includes); 105 excludePattern = computePattern(excludes); 106 this.base = base; 107 knownIncludes = computeKnownIncludes(); 108 } 109 110 private Pattern computePattern(String patterns) { 111 if (patterns == null) { 112 return null; 113 } 114 StringBuilder rx = new StringBuilder (); 115 StringTokenizer patternstok = new StringTokenizer (patterns, ", "); if (!patternstok.hasMoreTokens()) { 117 return Pattern.compile("<cannot match>"); } 119 while (patternstok.hasMoreTokens()) { 120 String pattern = patternstok.nextToken().replace('\\', '/'); 121 if (rx.length() > 0) { 122 rx.append('|'); 123 } 124 if (pattern.endsWith("/")) { pattern += "**"; } 127 if (pattern.equals("**")) { rx.append(".*"); break; 130 } 131 Matcher m = Pattern.compile("/\\*\\*/|/\\*\\*|\\*\\*/|\\*|/|[^*/]+").matcher(pattern); while (m.find()) { 133 String t = m.group(); 134 if (t.equals("/**")) { 135 rx.append("/.*"); 136 } else if (t.equals("**/")) { 137 rx.append("(.*/|)"); 138 } else if (t.equals("/**/")) { 139 rx.append("(/.*/|/)"); 140 } else if (t.equals("*")) { 141 rx.append("[^/]*"); 142 } else { 143 rx.append(Pattern.quote(t)); 144 } 145 } 146 } 147 String rxs = rx.toString(); 148 return Pattern.compile(rxs); 149 } 150 151 157 public boolean matches(String path, boolean useKnownIncludes) { 158 if (path == null) { 159 throw new NullPointerException (); 160 } 161 if (excludePattern != null && excludePattern.matcher(path).matches()) { 162 return false; 163 } 164 if (includePattern != null) { 165 if (includePattern.matcher(path).matches()) { 166 return true; 167 } 168 if (useKnownIncludes && (path.length() == 0 || path.endsWith("/"))) { 169 for (String incl : knownIncludes) { 170 if (incl.startsWith(path)) { 171 return true; 172 } 173 } 174 } 175 return false; 176 } else { 177 return true; 178 } 179 } 180 181 196 public Set <File > findIncludedRoots() throws IllegalArgumentException { 197 if (includes == null) { 198 return Collections.singleton(base); 199 } 200 Set <File > roots = new HashSet <File >(); 201 if (base != null) { 202 for (String incl : knownIncludes) { 203 roots.add(new File (base, incl.replace('/', File.separatorChar))); 204 } 205 } 206 return roots; 207 } 208 209 private Set <String > computeKnownIncludes() { 210 if (includes == null) { 211 return Collections.emptySet(); 212 } 213 SortedSet <String > roots = new TreeSet <String >(); 214 StringTokenizer patternstok = new StringTokenizer (includes, ", "); boolean search = false; 216 while (patternstok.hasMoreTokens()) { 217 String pattern = patternstok.nextToken().replace('\\', '/').replaceFirst("/\\*\\*$", "/"); if (pattern.equals("**")) { roots.add(""); } else if (pattern.indexOf('*') == -1 && pattern.endsWith("/")) { if (excludePattern == null || !excludePattern.matcher(pattern).matches()) { 223 String parent = pattern.substring(0, pattern.lastIndexOf('/', pattern.length() - 2) + 1); 224 if (!includePattern.matcher(parent).matches()) { 225 roots.add(pattern); 226 } 227 } 228 } else if (base != null) { 229 search = true; 231 } 232 } 233 if (base != null && base.isDirectory()) { 235 Iterator <String > it = roots.iterator(); 236 while (it.hasNext()) { 237 if (!new File (base, it.next().replace('/', File.separatorChar)).isDirectory()) { 238 it.remove(); 239 } 240 } 241 } 242 if (search) { 243 findMatches(base, "", roots); 247 } 248 return roots; 249 } 250 251 private void findMatches(File dir, String prefix, Set <String > roots) { 252 assert prefix.length() == 0 || prefix.endsWith("/"); 253 assert includes != null; 254 String [] childnames = dir.list(); 255 if (childnames == null) { 256 return; 257 } 258 for (String childname : childnames) { 259 File child = new File (dir, childname); 260 boolean isdir = child.isDirectory(); 261 String path = prefix + childname; 262 if (isdir) { 263 path += "/"; } 265 if (excludePattern != null && excludePattern.matcher(path).matches()) { 266 continue; } 268 if (includePattern.matcher(path).matches()) { 269 if (isdir) { 270 roots.add(path); 271 } else { 272 roots.add(prefix); 273 } 274 } else if (isdir) { 275 findMatches(child, path, roots); 276 } 277 } 278 } 279 280 @Override 281 public String toString() { 282 return "PathMatcher[includes=" + includes + ",excludes=" + excludes + "]"; } 284 285 } 286 | Popular Tags |