From: Eric Barboni Date: Mon, 17 Feb 2020 20:02:03 +0000 (+0100) Subject: Use nio Filesystem getPathMatcher X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=eb813618c533f29ff207ad184d9d3d8bb6d0f185;p=archiva.git Use nio Filesystem getPathMatcher --- diff --git a/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/FileTypes.java b/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/FileTypes.java index 23ffb9361..2415f7119 100644 --- a/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/FileTypes.java +++ b/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/FileTypes.java @@ -21,12 +21,8 @@ package org.apache.archiva.configuration; import org.apache.archiva.common.FileTypeUtils; import org.apache.archiva.configuration.functors.FiletypeSelectionPredicate; -import org.apache.archiva.configuration.io.registry.ConfigurationRegistryReader; -import org.apache.archiva.configuration.util.PathMatcher; import org.apache.archiva.components.registry.Registry; -import org.apache.archiva.components.registry.RegistryException; import org.apache.archiva.components.registry.RegistryListener; -import org.apache.archiva.components.registry.commons.CommonsConfigurationRegistry; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.IterableUtils; import org.apache.commons.collections4.Predicate; @@ -35,7 +31,8 @@ import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; -import java.lang.reflect.Field; +import java.nio.file.FileSystems; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -136,7 +133,7 @@ public class FileTypes for ( String pattern : artifactPatterns ) { - if ( PathMatcher.matchPath( pattern, relativePath, false ) ) + if ( FileSystems.getDefault().getPathMatcher( "glob:" + pattern).matches( Paths.get( relativePath ) ) ) { // Found match return true; @@ -154,7 +151,7 @@ public class FileTypes for ( String pattern : DEFAULT_EXCLUSIONS ) { - if ( PathMatcher.matchPath( pattern, relativePath, false ) ) + if ( FileSystems.getDefault().getPathMatcher( "glob:" + pattern).matches( Paths.get( relativePath ) ) ) { // Found match return true; diff --git a/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/util/PathMatcher.java b/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/util/PathMatcher.java deleted file mode 100644 index 11e5ed519..000000000 --- a/archiva-modules/archiva-base/archiva-configuration/src/main/java/org/apache/archiva/configuration/util/PathMatcher.java +++ /dev/null @@ -1,421 +0,0 @@ -package org.apache.archiva.configuration.util; - -/* - * 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. - */ - -import java.io.File; -import java.nio.file.InvalidPathException; -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * - * This provides a path matcher like in the SelectorUtils of the ant project. - * - * Using code from apache ant org.apache.tools.ant.types.selectors.SelectorUtils to remove the ant dependency for code - * compilation. - * See https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java - * - * @author Martin Stockhammer - * - * - */ -public class PathMatcher -{ - - private static final String DEEP_TREE_MATCH = "**"; - - - /** - * Tests whether or not a string matches against a pattern. - * The pattern may contain two special characters:
- * '*' means zero or more characters
- * '?' means one and only one character - * - * @param pattern The pattern to match against. - * Must not be null. - * @param str The string which must be matched against the pattern. - * Must not be null. - * - * @return true if the string matches against the pattern, - * or false otherwise. - */ - public static boolean match(String pattern, String str) { - return match(pattern, str, true); - } - - - /** - * Tests whether or not a string matches against a pattern. - * The pattern may contain two special characters:
- * '*' means zero or more characters
- * '?' means one and only one character - * - * @param pattern The pattern to match against. - * Must not be null. - * @param str The string which must be matched against the pattern. - * Must not be null. - * @param caseSensitive Whether or not matching should be performed - * case sensitively. - * - * - * @return true if the string matches against the pattern, - * or false otherwise. - */ - public static boolean match(String pattern, String str, - boolean caseSensitive) { - char[] patArr = pattern.toCharArray(); - char[] strArr = str.toCharArray(); - int patIdxStart = 0; - int patIdxEnd = patArr.length - 1; - int strIdxStart = 0; - int strIdxEnd = strArr.length - 1; - - boolean containsStar = false; - for (char ch : patArr) { - if (ch == '*') { - containsStar = true; - break; - } - } - - if (!containsStar) { - // No '*'s, so we make a shortcut - if (patIdxEnd != strIdxEnd) { - return false; // Pattern and string do not have the same size - } - for (int i = 0; i <= patIdxEnd; i++) { - char ch = patArr[i]; - if (ch != '?' && different(caseSensitive, ch, strArr[i])) { - return false; // Character mismatch - } - } - return true; // String matches against pattern - } - - if (patIdxEnd == 0) { - return true; // Pattern contains only '*', which matches anything - } - - // Process characters before first star - while (true) { - char ch = patArr[patIdxStart]; - if (ch == '*' || strIdxStart > strIdxEnd) { - break; - } - if (ch != '?' - && different(caseSensitive, ch, strArr[strIdxStart])) { - return false; // Character mismatch - } - patIdxStart++; - strIdxStart++; - } - if (strIdxStart > strIdxEnd) { - // All characters in the string are used. Check if only '*'s are - // left in the pattern. If so, we succeeded. Otherwise failure. - return allStars(patArr, patIdxStart, patIdxEnd); - } - - // Process characters after last star - while (true) { - char ch = patArr[patIdxEnd]; - if (ch == '*' || strIdxStart > strIdxEnd) { - break; - } - if (ch != '?' && different(caseSensitive, ch, strArr[strIdxEnd])) { - return false; // Character mismatch - } - patIdxEnd--; - strIdxEnd--; - } - if (strIdxStart > strIdxEnd) { - // All characters in the string are used. Check if only '*'s are - // left in the pattern. If so, we succeeded. Otherwise failure. - return allStars(patArr, patIdxStart, patIdxEnd); - } - - // process pattern between stars. padIdxStart and patIdxEnd point - // always to a '*'. - while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) { - int patIdxTmp = -1; - for (int i = patIdxStart + 1; i <= patIdxEnd; i++) { - if (patArr[i] == '*') { - patIdxTmp = i; - break; - } - } - if (patIdxTmp == patIdxStart + 1) { - // Two stars next to each other, skip the first one. - patIdxStart++; - continue; - } - // Find the pattern between padIdxStart & padIdxTmp in str between - // strIdxStart & strIdxEnd - int patLength = (patIdxTmp - patIdxStart - 1); - int strLength = (strIdxEnd - strIdxStart + 1); - int foundIdx = -1; - strLoop: - for (int i = 0; i <= strLength - patLength; i++) { - for (int j = 0; j < patLength; j++) { - char ch = patArr[patIdxStart + j + 1]; - if (ch != '?' && different(caseSensitive, ch, - strArr[strIdxStart + i + j])) { - continue strLoop; - } - } - foundIdx = strIdxStart + i; - break; - } - - if (foundIdx == -1) { - return false; - } - patIdxStart = patIdxTmp; - strIdxStart = foundIdx + patLength; - } - - // All characters in the string are used. Check if only '*'s are left - // in the pattern. If so, we succeeded. Otherwise failure. - return allStars(patArr, patIdxStart, patIdxEnd); - } - - private static boolean allStars(char[] chars, int start, int end) { - for (int i = start; i <= end; ++i) { - if (chars[i] != '*') { - return false; - } - } - return true; - } - - private static boolean different( - boolean caseSensitive, char ch, char other) { - return caseSensitive - ? ch != other - : Character.toUpperCase(ch) != Character.toUpperCase(other); - } - - /** - * 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 TokenizedPath - * - * - * @param pattern The pattern to match against. Must not be - * null. - * @param str The path to match, as a String. Must not be - * null. - * - * @return true if the pattern matches against the string, - * or false otherwise. - */ - public static boolean matchPath(String pattern, String str) { - String[] patDirs = tokenizePathAsArray( pattern, false ); - return matchPath(patDirs, tokenizePathAsArray( str, true ), 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 TokenizedPattern - * - * @param pattern The pattern to match against. Must not be - * null. - * @param str The path to match, as a String. Must not be - * null. - * @param isCaseSensitive Whether or not matching should be performed - * case sensitively. - * - * @return true if the pattern matches against the string, - * or false otherwise. - */ - public static boolean matchPath(String pattern, String str, - boolean isCaseSensitive) { - String[] patDirs = tokenizePathAsArray( pattern, false ); - return matchPath(patDirs, tokenizePathAsArray( str, false ), isCaseSensitive); - } - - /** - * - * @param path - * @param osspecific - * @return - */ - static String[] tokenizePathAsArray(String path, boolean osSpecific) { - Path root = null; - try - { - Path fsPath = Paths.get( path ); - if ( fsPath.isAbsolute() ) { - root = fsPath.getRoot(); - path = root.relativize( fsPath ).toString(); - } - } catch (InvalidPathException ipe ) - { - // invalid path, windauze hate **/* - } - char sep = osSpecific ? File.separatorChar : '/'; - int start = 0; - int len = path.length(); - int count = 0; - for (int pos = 0; pos < len; pos++) { - if (path.charAt(pos) == sep) { - if (pos != start) { - count++; - } - start = pos + 1; - } - } - if (len != start) { - count++; - } - String[] l = new String[count + ((root == null) ? 0 : 1)]; - - if (root != null) { - l[0] = root.toString(); - count = 1; - } else { - count = 0; - } - start = 0; - for (int pos = 0; pos < len; pos++) { - if (path.charAt(pos) == sep) { - if (pos != start) { - String tok = path.substring(start, pos); - l[count++] = tok; - } - start = pos + 1; - } - } - if (len != start) { - String tok = path.substring(start); - l[count/*++*/] = tok; - } - return l; - } - - /** - * Core implementation of matchPath. It is isolated so that it - * can be called from TokenizedPattern. - */ - public static boolean matchPath( String[] tokenizedPattern, String[] strDirs, - boolean isCaseSensitive ) { - int patIdxStart = 0; - int patIdxEnd = tokenizedPattern.length - 1; - int strIdxStart = 0; - int strIdxEnd = strDirs.length - 1; - - // up to first '**' - while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { - String patDir = tokenizedPattern[patIdxStart]; - if (patDir.equals(DEEP_TREE_MATCH)) { - break; - } - if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) { - return false; - } - patIdxStart++; - strIdxStart++; - } - if (strIdxStart > strIdxEnd) { - // String is exhausted - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) { - return false; - } - } - return true; - } - if (patIdxStart > patIdxEnd) { - // String not exhausted, but pattern is. Failure. - return false; - } - - // up to last '**' - while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) { - String patDir = tokenizedPattern[patIdxEnd]; - if (patDir.equals(DEEP_TREE_MATCH)) { - break; - } - if (!match(patDir, strDirs[strIdxEnd], isCaseSensitive)) { - return false; - } - patIdxEnd--; - strIdxEnd--; - } - if (strIdxStart > strIdxEnd) { - // String is exhausted - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) { - return false; - } - } - return true; - } - - while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) { - int patIdxTmp = -1; - for (int i = patIdxStart + 1; i <= patIdxEnd; i++) { - if (tokenizedPattern[i].equals(DEEP_TREE_MATCH)) { - patIdxTmp = i; - break; - } - } - if (patIdxTmp == patIdxStart + 1) { - // '**/**' situation, so skip one - patIdxStart++; - continue; - } - // Find the pattern between padIdxStart & padIdxTmp in str between - // strIdxStart & strIdxEnd - int patLength = (patIdxTmp - patIdxStart - 1); - int strLength = (strIdxEnd - strIdxStart + 1); - int foundIdx = -1; - strLoop: - for (int i = 0; i <= strLength - patLength; i++) { - for (int j = 0; j < patLength; j++) { - String subPat = tokenizedPattern[patIdxStart + j + 1]; - String subStr = strDirs[strIdxStart + i + j]; - if (!match(subPat, subStr, isCaseSensitive)) { - continue strLoop; - } - } - foundIdx = strIdxStart + i; - break; - } - if (foundIdx == -1) { - return false; - } - - patIdxStart = patIdxTmp; - strIdxStart = foundIdx + patLength; - } - - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (!DEEP_TREE_MATCH.equals(tokenizedPattern[i])) { - return false; - } - } - return true; - } - - -}