git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@687768 13f79535-47bb-0310-9956-ffa450edef68master
@@ -1,4 +1,4 @@ | |||
Changes from Ant 1.7.x TO current SVN version | |||
eol-styleChanges from Ant 1.7.x TO current SVN version | |||
============================================= | |||
Changes that could break older environments: | |||
@@ -158,8 +158,6 @@ Fixed bugs: | |||
filter tokens | |||
Bugzilla Report 44226. | |||
* Enhance performance of Project.fireMessageLoggedEvent | |||
Bugzilla Report 45651. | |||
Other changes: | |||
-------------- | |||
@@ -274,6 +272,9 @@ Other changes: | |||
expression. | |||
Bugzilla Report 45284 | |||
* Enhanced performance of Project.fireMessageLoggedEvent and DirectoryScanner | |||
Bugzilla Report 45651 & 45665 | |||
* The package list location for offline links can now be specified as | |||
an URL. | |||
Bugzilla Report 28881 | |||
@@ -34,6 +34,7 @@ import org.apache.tools.ant.types.Resource; | |||
import org.apache.tools.ant.types.ResourceFactory; | |||
import org.apache.tools.ant.types.resources.FileResource; | |||
import org.apache.tools.ant.types.selectors.FileSelector; | |||
import org.apache.tools.ant.types.selectors.PathPattern; | |||
import org.apache.tools.ant.types.selectors.SelectorScanner; | |||
import org.apache.tools.ant.types.selectors.SelectorUtils; | |||
import org.apache.tools.ant.util.FileUtils; | |||
@@ -319,10 +320,8 @@ public class DirectoryScanner | |||
* <p>Gets lazily initialized on the first invocation of | |||
* isIncluded or isExcluded and cleared at the end of the scan | |||
* method (cleared in clearCaches, actually).</p> | |||
* | |||
* @since Ant 1.6.3 | |||
*/ | |||
private String[] includePatterns; | |||
private PathPattern[] includePatterns; | |||
/** | |||
* Array of all exclude patterns that contain wildcards. | |||
@@ -330,10 +329,8 @@ public class DirectoryScanner | |||
* <p>Gets lazily initialized on the first invocation of | |||
* isIncluded or isExcluded and cleared at the end of the scan | |||
* method (cleared in clearCaches, actually).</p> | |||
* | |||
* @since Ant 1.6.3 | |||
*/ | |||
private String[] excludePatterns; | |||
private PathPattern[] excludePatterns; | |||
/** | |||
* Have the non-pattern sets and pattern arrays for in- and | |||
@@ -1196,7 +1193,7 @@ public class DirectoryScanner | |||
return true; | |||
} | |||
for (int i = 0; i < includePatterns.length; i++) { | |||
if (matchPath(includePatterns[i], name, isCaseSensitive())) { | |||
if (includePatterns[i].matchPath(name, isCaseSensitive())) { | |||
return true; | |||
} | |||
} | |||
@@ -1296,7 +1293,7 @@ public class DirectoryScanner | |||
return true; | |||
} | |||
for (int i = 0; i < excludePatterns.length; i++) { | |||
if (matchPath(excludePatterns[i], name, isCaseSensitive())) { | |||
if (excludePatterns[i].matchPath(name, isCaseSensitive())) { | |||
return true; | |||
} | |||
} | |||
@@ -1696,18 +1693,17 @@ public class DirectoryScanner | |||
* @param patterns String[] of patterns. | |||
* @since Ant 1.6.3 | |||
*/ | |||
private String[] fillNonPatternSet(Set set, String[] patterns) { | |||
private PathPattern[] fillNonPatternSet(Set set, String[] patterns) { | |||
ArrayList al = new ArrayList(patterns.length); | |||
for (int i = 0; i < patterns.length; i++) { | |||
if (!SelectorUtils.hasWildcards(patterns[i])) { | |||
set.add(isCaseSensitive() ? patterns[i] | |||
: patterns[i].toUpperCase()); | |||
} else { | |||
al.add(patterns[i]); | |||
al.add(new PathPattern(patterns[i])); | |||
} | |||
} | |||
return set.size() == 0 ? patterns | |||
: (String[]) al.toArray(new String[al.size()]); | |||
return (PathPattern[]) al.toArray(new PathPattern[al.size()]); | |||
} | |||
} |
@@ -0,0 +1,82 @@ | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
* | |||
*/ | |||
package org.apache.tools.ant.types.selectors; | |||
/** | |||
* Provides reusable path pattern matching. PathPattern is preferable to equivalent | |||
* SelectorUtils methods if you need to execute multiple matching with the same pattern | |||
* because here the pattern itself will be parsed only once. | |||
* @see SelectorUtils#matchPath(String, String) | |||
* @see SelectorUtils#matchPath(String, String, boolean) | |||
* @since 1.8 | |||
*/ | |||
public class PathPattern { | |||
private final String pattern; | |||
private final String tokenizedPattern[]; | |||
/** | |||
* Initialize the PathPattern by parsing it. | |||
* @param pattern The pattern to match against. Must not be | |||
* <code>null</code>. | |||
*/ | |||
public PathPattern(String pattern) { | |||
this.pattern = pattern; | |||
this.tokenizedPattern = SelectorUtils.tokenizePathAsArray(pattern); | |||
} | |||
/** | |||
* Tests whether or not a given path matches a given pattern. | |||
* | |||
* @param str The path to match, as a String. Must not be | |||
* <code>null</code>. | |||
* | |||
* @return <code>true</code> if the pattern matches against the string, | |||
* or <code>false</code> otherwise. | |||
*/ | |||
public boolean matchPath(String str) { | |||
return SelectorUtils.matchPath(tokenizedPattern, str, true); | |||
} | |||
/** | |||
* Tests whether or not a given path matches a given pattern. | |||
* | |||
* @param str The path to match, as a String. Must not be | |||
* <code>null</code>. | |||
* @param isCaseSensitive Whether or not matching should be performed | |||
* case sensitively. | |||
* | |||
* @return <code>true</code> if the pattern matches against the string, | |||
* or <code>false</code> otherwise. | |||
*/ | |||
public boolean matchPath(String str, boolean isCaseSensitive) { | |||
return SelectorUtils.matchPath(tokenizedPattern, str, isCaseSensitive); | |||
} | |||
/** | |||
* @return The pattern String | |||
*/ | |||
public String toString() { | |||
return pattern; | |||
} | |||
public String getPattern() { | |||
return pattern; | |||
} | |||
} |
@@ -38,7 +38,7 @@ import org.apache.tools.ant.types.resources.FileResource; | |||
*/ | |||
public final class SelectorUtils { | |||
private static SelectorUtils instance = new SelectorUtils(); | |||
private static final SelectorUtils instance = new SelectorUtils(); | |||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||
/** | |||
@@ -144,6 +144,11 @@ public final class SelectorUtils { | |||
/** | |||
* Tests whether or not a given path matches a given pattern. | |||
* | |||
* If you need to call this method multiple times with the same | |||
* pattern you should rather use PathPattern | |||
* | |||
* @see PathPattern | |||
* | |||
* @param pattern The pattern to match against. Must not be | |||
* <code>null</code>. | |||
* @param str The path to match, as a String. Must not be | |||
@@ -153,12 +158,18 @@ public final class SelectorUtils { | |||
* or <code>false</code> otherwise. | |||
*/ | |||
public static boolean matchPath(String pattern, String str) { | |||
return matchPath(pattern, str, true); | |||
String[] patDirs = tokenizePathAsArray(pattern); | |||
return matchPath(patDirs, str, true); | |||
} | |||
/** | |||
* Tests whether or not a given path matches a given pattern. | |||
* | |||
* If you need to call this method multiple times with the same | |||
* pattern you should rather use PathPattern | |||
* | |||
* @see PathPattern | |||
* | |||
* @param pattern The pattern to match against. Must not be | |||
* <code>null</code>. | |||
* @param str The path to match, as a String. Must not be | |||
@@ -172,22 +183,28 @@ public final class SelectorUtils { | |||
public static boolean matchPath(String pattern, String str, | |||
boolean isCaseSensitive) { | |||
String[] patDirs = tokenizePathAsArray(pattern); | |||
return matchPath(patDirs, str, isCaseSensitive); | |||
} | |||
/** | |||
* Core implementation of matchPath. It is isolated so that it can be called from | |||
* PathPattern. | |||
*/ | |||
static boolean matchPath(String[] tokenizedPattern, String str, boolean isCaseSensitive) { | |||
String[] strDirs = tokenizePathAsArray(str); | |||
int patIdxStart = 0; | |||
int patIdxEnd = patDirs.length - 1; | |||
int patIdxEnd = tokenizedPattern.length - 1; | |||
int strIdxStart = 0; | |||
int strIdxEnd = strDirs.length - 1; | |||
// up to first '**' | |||
while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { | |||
String patDir = patDirs[patIdxStart]; | |||
String patDir = tokenizedPattern[patIdxStart]; | |||
if (patDir.equals("**")) { | |||
break; | |||
} | |||
if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) { | |||
patDirs = null; | |||
strDirs = null; | |||
return false; | |||
} | |||
patIdxStart++; | |||
@@ -196,9 +213,7 @@ public final class SelectorUtils { | |||
if (strIdxStart > strIdxEnd) { | |||
// String is exhausted | |||
for (int i = patIdxStart; i <= patIdxEnd; i++) { | |||
if (!patDirs[i].equals("**")) { | |||
patDirs = null; | |||
strDirs = null; | |||
if (!tokenizedPattern[i].equals("**")) { | |||
return false; | |||
} | |||
} | |||
@@ -206,21 +221,17 @@ public final class SelectorUtils { | |||
} else { | |||
if (patIdxStart > patIdxEnd) { | |||
// String not exhausted, but pattern is. Failure. | |||
patDirs = null; | |||
strDirs = null; | |||
return false; | |||
} | |||
} | |||
// up to last '**' | |||
while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { | |||
String patDir = patDirs[patIdxEnd]; | |||
String patDir = tokenizedPattern[patIdxEnd]; | |||
if (patDir.equals("**")) { | |||
break; | |||
} | |||
if (!match(patDir, strDirs[strIdxEnd], isCaseSensitive)) { | |||
patDirs = null; | |||
strDirs = null; | |||
return false; | |||
} | |||
patIdxEnd--; | |||
@@ -229,9 +240,7 @@ public final class SelectorUtils { | |||
if (strIdxStart > strIdxEnd) { | |||
// String is exhausted | |||
for (int i = patIdxStart; i <= patIdxEnd; i++) { | |||
if (!patDirs[i].equals("**")) { | |||
patDirs = null; | |||
strDirs = null; | |||
if (!tokenizedPattern[i].equals("**")) { | |||
return false; | |||
} | |||
} | |||
@@ -241,7 +250,7 @@ public final class SelectorUtils { | |||
while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) { | |||
int patIdxTmp = -1; | |||
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) { | |||
if (patDirs[i].equals("**")) { | |||
if (tokenizedPattern[i].equals("**")) { | |||
patIdxTmp = i; | |||
break; | |||
} | |||
@@ -259,7 +268,7 @@ public final class SelectorUtils { | |||
strLoop: | |||
for (int i = 0; i <= strLength - patLength; i++) { | |||
for (int j = 0; j < patLength; j++) { | |||
String subPat = patDirs[patIdxStart + j + 1]; | |||
String subPat = tokenizedPattern[patIdxStart + j + 1]; | |||
String subStr = strDirs[strIdxStart + i + j]; | |||
if (!match(subPat, subStr, isCaseSensitive)) { | |||
continue strLoop; | |||
@@ -271,8 +280,6 @@ public final class SelectorUtils { | |||
} | |||
if (foundIdx == -1) { | |||
patDirs = null; | |||
strDirs = null; | |||
return false; | |||
} | |||
@@ -281,9 +288,7 @@ public final class SelectorUtils { | |||
} | |||
for (int i = patIdxStart; i <= patIdxEnd; i++) { | |||
if (!patDirs[i].equals("**")) { | |||
patDirs = null; | |||
strDirs = null; | |||
if (!tokenizedPattern[i].equals("**")) { | |||
return false; | |||
} | |||
} | |||
@@ -507,7 +512,7 @@ public final class SelectorUtils { | |||
/** | |||
* Same as {@link #tokenizePath tokenizePath} but hopefully faster. | |||
*/ | |||
private static String[] tokenizePathAsArray(String path) { | |||
/*package*/ static String[] tokenizePathAsArray(String path) { | |||
String root = null; | |||
if (FileUtils.isAbsolutePath(path)) { | |||
String[] s = FILE_UTILS.dissect(path); | |||