diff --git a/src/main/java/com/alibaba/druid/util/AntPathMatcher.java b/src/main/java/com/alibaba/druid/util/AntPathMatcher.java deleted file mode 100644 index f16a662313..0000000000 --- a/src/main/java/com/alibaba/druid/util/AntPathMatcher.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright 1999-2011 Alibaba Group Holding Ltd. - * - * Licensed 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 com.alibaba.druid.util; - -/** - *

- * PathMatcher implementation for Ant-style path patterns. Examples are provided below. - *

- *

- * Part of this mapping code has been kindly borrowed from Apache Ant. - *

- * The mapping matches URLs using the following rules:
- *

- *

- * Some examples:
- *

- *

- * N.B.: This class was borrowed (with much appreciation) from the Shiro - * and the Spring Framework with modifications. We didn't want to reinvent - * the wheel of great work they've done, but also didn't want to force every Shiro user to depend on Spring - *

- *

- * As per the Apache 2.0 license, the original copyright notice and all author and copyright information have remained - * in tact. - *

- * - * @since 16.07.2003 - */ -public class AntPathMatcher implements PatternMatcher { - - // TODO - complete JavaDoc - - /** - * Default path separator: "/" - */ - public static final String DEFAULT_PATH_SEPARATOR = "/"; - - private String pathSeparator = DEFAULT_PATH_SEPARATOR; - - /** - * Set the path separator to use for pattern parsing. Default is "/", as in Ant. - */ - public void setPathSeparator(String pathSeparator) { - this.pathSeparator = (pathSeparator != null ? pathSeparator : DEFAULT_PATH_SEPARATOR); - } - - public boolean isPattern(String path) { - return (path.indexOf('*') != -1 || path.indexOf('?') != -1); - } - - public boolean matches(String pattern, String source) { - return match(pattern, source); - } - - public boolean match(String pattern, String path) { - return doMatch(pattern, path, true); - } - - public boolean matchStart(String pattern, String path) { - return doMatch(pattern, path, false); - } - - /** - * Actually match the given path against the given pattern. - * - * @param pattern the pattern to match against - * @param path the path String to test - * @param fullMatch whether a full pattern match is required (else a pattern match as far as the given base path - * goes is sufficient) - * @return true if the supplied path matched, false if it didn't - */ - protected boolean doMatch(String pattern, String path, boolean fullMatch) { - if (path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) { - return false; - } - - String[] pattDirs = StringUtils.tokenizeToStringArray(pattern, this.pathSeparator); - String[] pathDirs = StringUtils.tokenizeToStringArray(path, this.pathSeparator); - - int pattIdxStart = 0; - int pattIdxEnd = pattDirs.length - 1; - int pathIdxStart = 0; - int pathIdxEnd = pathDirs.length - 1; - - // Match all elements up to the first ** - while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) { - String patDir = pattDirs[pattIdxStart]; - if ("**".equals(patDir)) { - break; - } - if (!matchStrings(patDir, pathDirs[pathIdxStart])) { - return false; - } - pattIdxStart++; - pathIdxStart++; - } - - if (pathIdxStart > pathIdxEnd) { - // Path is exhausted, only match if rest of pattern is * or **'s - if (pattIdxStart > pattIdxEnd) { - return (pattern.endsWith(this.pathSeparator) ? path.endsWith(this.pathSeparator) : !path.endsWith(this.pathSeparator)); - } - if (!fullMatch) { - return true; - } - if (pattIdxStart == pattIdxEnd && pattDirs[pattIdxStart].equals("*") && path.endsWith(this.pathSeparator)) { - return true; - } - for (int i = pattIdxStart; i <= pattIdxEnd; i++) { - if (!pattDirs[i].equals("**")) { - return false; - } - } - return true; - } else if (pattIdxStart > pattIdxEnd) { - // String not exhausted, but pattern is. Failure. - return false; - } else if (!fullMatch && "**".equals(pattDirs[pattIdxStart])) { - // Path start definitely matches due to "**" part in pattern. - return true; - } - - // up to last '**' - while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) { - String patDir = pattDirs[pattIdxEnd]; - if (patDir.equals("**")) { - break; - } - if (!matchStrings(patDir, pathDirs[pathIdxEnd])) { - return false; - } - pattIdxEnd--; - pathIdxEnd--; - } - if (pathIdxStart > pathIdxEnd) { - // String is exhausted - for (int i = pattIdxStart; i <= pattIdxEnd; i++) { - if (!pattDirs[i].equals("**")) { - return false; - } - } - return true; - } - - while (pattIdxStart != pattIdxEnd && pathIdxStart <= pathIdxEnd) { - int patIdxTmp = -1; - for (int i = pattIdxStart + 1; i <= pattIdxEnd; i++) { - if (pattDirs[i].equals("**")) { - patIdxTmp = i; - break; - } - } - if (patIdxTmp == pattIdxStart + 1) { - // '**/**' situation, so skip one - pattIdxStart++; - continue; - } - // Find the pattern between padIdxStart & padIdxTmp in str between - // strIdxStart & strIdxEnd - int patLength = (patIdxTmp - pattIdxStart - 1); - int strLength = (pathIdxEnd - pathIdxStart + 1); - int foundIdx = -1; - - strLoop: for (int i = 0; i <= strLength - patLength; i++) { - for (int j = 0; j < patLength; j++) { - String subPat = (String) pattDirs[pattIdxStart + j + 1]; - String subStr = (String) pathDirs[pathIdxStart + i + j]; - if (!matchStrings(subPat, subStr)) { - continue strLoop; - } - } - foundIdx = pathIdxStart + i; - break; - } - - if (foundIdx == -1) { - return false; - } - - pattIdxStart = patIdxTmp; - pathIdxStart = foundIdx + patLength; - } - - for (int i = pattIdxStart; i <= pattIdxEnd; i++) { - if (!pattDirs[i].equals("**")) { - return false; - } - } - - return 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 pattern to match against. Must not be null. - * @param str string which must be matched against the pattern. Must not be null. - * @return true if the string matches against the pattern, or false otherwise. - */ - private boolean matchStrings(String pattern, String str) { - char[] patArr = pattern.toCharArray(); - char[] strArr = str.toCharArray(); - int patIdxStart = 0; - int patIdxEnd = patArr.length - 1; - int strIdxStart = 0; - int strIdxEnd = strArr.length - 1; - char ch; - - boolean containsStar = false; - for (char aPatArr : patArr) { - if (aPatArr == '*') { - 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++) { - ch = patArr[i]; - if (ch != '?') { - if (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 ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) { - if (ch != '?') { - if (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. - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (patArr[i] != '*') { - return false; - } - } - return true; - } - - // Process characters after last star - while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) { - if (ch != '?') { - if (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. - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (patArr[i] != '*') { - return false; - } - } - return true; - } - - // 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++) { - ch = patArr[patIdxStart + j + 1]; - if (ch != '?') { - if (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. - for (int i = patIdxStart; i <= patIdxEnd; i++) { - if (patArr[i] != '*') { - return false; - } - } - - return true; - } - - /** - * Given a pattern and a full path, determine the pattern-mapped part. - *

- * For example: - *

- *

- * Assumes that {@link #match} returns true for 'pattern' and 'path', but - * does not enforce this. - */ - public String extractPathWithinPattern(String pattern, String path) { - String[] patternParts = StringUtils.tokenizeToStringArray(pattern, this.pathSeparator); - String[] pathParts = StringUtils.tokenizeToStringArray(path, this.pathSeparator); - - StringBuilder buffer = new StringBuilder(); - - // Add any path parts that have a wildcarded pattern part. - int puts = 0; - for (int i = 0; i < patternParts.length; i++) { - String patternPart = patternParts[i]; - if ((patternPart.indexOf('*') > -1 || patternPart.indexOf('?') > -1) && pathParts.length >= i + 1) { - if (puts > 0 || (i == 0 && !pattern.startsWith(this.pathSeparator))) { - buffer.append(this.pathSeparator); - } - buffer.append(pathParts[i]); - puts++; - } - } - - // Append any trailing path parts. - for (int i = patternParts.length; i < pathParts.length; i++) { - if (puts > 0 || i > 0) { - buffer.append(this.pathSeparator); - } - buffer.append(pathParts[i]); - } - - return buffer.toString(); - } - -} diff --git a/src/main/java/com/alibaba/druid/util/StringUtils.java b/src/main/java/com/alibaba/druid/util/StringUtils.java index 3fe910318f..6b5ef08567 100644 --- a/src/main/java/com/alibaba/druid/util/StringUtils.java +++ b/src/main/java/com/alibaba/druid/util/StringUtils.java @@ -79,22 +79,6 @@ public class StringUtils { } } - /** - * @param in - * @return - */ - public static Long stringToLong(String in) { - if (in == null) return null; - in = in.trim(); - if (in.length() == 0) return null; - try { - return Long.parseLong(in); - } catch (NumberFormatException e) { - LOG.warn("stringToLong fail,string=" + in, e); - return null; - } - } - public static Map getParameters(String url) { if (url == null || (url = url.trim()).length() == 0) return null; @@ -115,97 +99,18 @@ public class StringUtils { return parameters; } - /** - * Tokenize the given String into a String array via a StringTokenizer. Trims tokens and omits empty tokens. - *

- * The given delimiters string is supposed to consist of any number of delimiter characters. Each of those - * characters can be used to separate tokens. A delimiter is always a single character; for multi-character - * delimiters, consider using delimitedListToStringArray - *

- *

- * Copied from the Spring Framework while retaining all license, copyright and author information. - * - * @param str the String to tokenize - * @param delimiters the delimiter characters, assembled as String (each of those characters is individually - * considered as delimiter). - * @return an array of the tokens - * @see java.util.StringTokenizer - * @see java.lang.String#trim() - */ - public static String[] tokenizeToStringArray(String str, String delimiters) { - return tokenizeToStringArray(str, delimiters, true, true); - } - - /** - * Tokenize the given String into a String array via a StringTokenizer. - *

- * The given delimiters string is supposed to consist of any number of delimiter characters. Each of those - * characters can be used to separate tokens. A delimiter is always a single character; for multi-character - * delimiters, consider using delimitedListToStringArray - *

- *

- * Copied from the Spring Framework while retaining all license, copyright and author information. - * - * @param str the String to tokenize - * @param delimiters the delimiter characters, assembled as String (each of those characters is individually - * considered as delimiter) - * @param trimTokens trim the tokens via String's trim - * @param ignoreEmptyTokens omit empty tokens from the result array (only applies to tokens that are empty after - * trimming; StringTokenizer will not consider subsequent delimiters as token in the first place). - * @return an array of the tokens (null if the input String was null) - * @see java.util.StringTokenizer - * @see java.lang.String#trim() - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static String[] tokenizeToStringArray(String str, String delimiters, boolean trimTokens, - boolean ignoreEmptyTokens) { - - if (str == null) { - return null; - } - StringTokenizer st = new StringTokenizer(str, delimiters); - List tokens = new ArrayList(); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - if (trimTokens) { - token = token.trim(); - } - if (!ignoreEmptyTokens || token.length() > 0) { - tokens.add(token); - } - } - return toStringArray(tokens); - } - - /** - * Copy the given Collection into a String array. The Collection must contain String elements only. - *

- *

- * Copied from the Spring Framework while retaining all license, copyright and author information. - * - * @param collection the Collection to copy - * @return the String array (null if the passed-in Collection was null) - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static String[] toStringArray(Collection collection) { - if (collection == null) { - return null; - } - return (String[]) collection.toArray(new String[collection.size()]); - } - public static boolean equals(String a, String b) { if (a == null) { return b == null; } return a.equals(b); } - + public static boolean isEmpty(String value) { if (value == null || value.length() == 0) { return true; } - + return false; } } diff --git a/src/test/java/com/alibaba/druid/bvt/utils/ConcurrentIdentityHashMapTest.java b/src/test/java/com/alibaba/druid/bvt/utils/ConcurrentIdentityHashMapTest.java new file mode 100644 index 0000000000..ce18c60443 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/utils/ConcurrentIdentityHashMapTest.java @@ -0,0 +1,31 @@ +package com.alibaba.druid.bvt.utils; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.util.ConcurrentIdentityHashMap; + +public class ConcurrentIdentityHashMapTest extends TestCase { + + public void test_0() throws Exception { + ConcurrentIdentityHashMap map = new ConcurrentIdentityHashMap(); + + Integer v1 = new Integer(3); + map.put(v1, "3"); + + Assert.assertTrue(map.contains("3")); + Assert.assertTrue(map.containsKey(v1)); + + Assert.assertFalse(map.contains("4")); + Assert.assertFalse(map.containsKey(new Integer(3))); + + map.put(v1, "33"); + Assert.assertFalse(map.contains("3")); + Assert.assertTrue(map.contains("33")); + + Assert.assertEquals(1, map.size()); + + map.clear(); + Assert.assertEquals(0, map.size()); + } +}