mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Moving to root below branch label
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2005 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
640
source/java/org/alfresco/filesys/util/WildCard.java
Normal file
640
source/java/org/alfresco/filesys/util/WildCard.java
Normal file
@@ -0,0 +1,640 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* 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.alfresco.filesys.util;
|
||||
|
||||
/**
|
||||
* Wildcard Utility Class.
|
||||
* <p>
|
||||
* The WildCard class may be used to check Strings against a wildcard pattern using the SMB/CIFS
|
||||
* wildcard rules.
|
||||
* <p>
|
||||
* A number of static convenience methods are also provided.
|
||||
*
|
||||
* @author GKSpencer
|
||||
*/
|
||||
public final class WildCard
|
||||
{
|
||||
|
||||
// Multiple character wildcard
|
||||
|
||||
public static final int MULTICHAR_WILDCARD = '*';
|
||||
|
||||
// Single character wildcard
|
||||
|
||||
public static final int SINGLECHAR_WILDCARD = '?';
|
||||
|
||||
// Unicode wildcards
|
||||
//
|
||||
// The spec states :-
|
||||
// translate '?' to '>'
|
||||
// translate '.' to '"' if followed by a '?' or '*'
|
||||
// translate '*' to '<' if followed by a '.'
|
||||
|
||||
public static final int SINGLECHAR_UNICODE_WILDCARD = '>';
|
||||
public static final int DOT_UNICODE_WILDCARD = '"';
|
||||
public static final int MULTICHAR_UNICODE_WILDCARD = '<';
|
||||
|
||||
// Wildcard types
|
||||
|
||||
public static final int WILDCARD_NONE = 0; // no wildcard characters present in pattern
|
||||
public static final int WILDCARD_ALL = 1; // '*.*' and '*'
|
||||
public static final int WILDCARD_NAME = 2; // '*.ext'
|
||||
public static final int WILDCARD_EXT = 3; // 'name.*'
|
||||
public static final int WILDCARD_COMPLEX = 4; // complex wildcard
|
||||
|
||||
public static final int WILDCARD_INVALID = -1;
|
||||
|
||||
// Wildcard pattern and type
|
||||
|
||||
private String m_pattern;
|
||||
private int m_type;
|
||||
|
||||
// Start/end string to match for name/extension matching
|
||||
|
||||
private String m_matchPart;
|
||||
private boolean m_caseSensitive;
|
||||
|
||||
// Complex wildcard pattern
|
||||
|
||||
private char[] m_patternChars;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public WildCard()
|
||||
{
|
||||
setType(WILDCARD_INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param pattern String
|
||||
* @param caseSensitive boolean
|
||||
*/
|
||||
public WildCard(String pattern, boolean caseSensitive)
|
||||
{
|
||||
setPattern(pattern, caseSensitive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the wildcard pattern type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int isType()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if case sensitive matching is enabled
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean isCaseSensitive()
|
||||
{
|
||||
return m_caseSensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the wildcard pattern string
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getPattern()
|
||||
{
|
||||
return m_pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the match part for wildcard name and wildcard extension type patterns
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getMatchPart()
|
||||
{
|
||||
return m_matchPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the string matches the wildcard pattern
|
||||
*
|
||||
* @param str String
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean matchesPattern(String str)
|
||||
{
|
||||
|
||||
// Check the pattern type and compare the string
|
||||
|
||||
boolean sts = false;
|
||||
|
||||
switch (isType())
|
||||
{
|
||||
|
||||
// Match all wildcard
|
||||
|
||||
case WILDCARD_ALL:
|
||||
sts = true;
|
||||
break;
|
||||
|
||||
// Match any name
|
||||
|
||||
case WILDCARD_NAME:
|
||||
if (isCaseSensitive())
|
||||
{
|
||||
|
||||
// Check if the string ends with the required file extension
|
||||
|
||||
sts = str.endsWith(m_matchPart);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Normalize the string and compare
|
||||
|
||||
String upStr = str.toUpperCase();
|
||||
sts = upStr.endsWith(m_matchPart);
|
||||
}
|
||||
break;
|
||||
|
||||
// Match any file extension
|
||||
|
||||
case WILDCARD_EXT:
|
||||
if (isCaseSensitive())
|
||||
{
|
||||
|
||||
// Check if the string starts with the required file name
|
||||
|
||||
sts = str.startsWith(m_matchPart);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Normalize the string and compare
|
||||
|
||||
String upStr = str.toUpperCase();
|
||||
sts = upStr.startsWith(m_matchPart);
|
||||
}
|
||||
break;
|
||||
|
||||
// Complex wildcard matching
|
||||
|
||||
case WILDCARD_COMPLEX:
|
||||
if (isCaseSensitive())
|
||||
sts = matchComplexWildcard(str);
|
||||
else
|
||||
{
|
||||
|
||||
// Normalize the string and compare
|
||||
|
||||
String upStr = str.toUpperCase();
|
||||
sts = matchComplexWildcard(upStr);
|
||||
}
|
||||
break;
|
||||
|
||||
// No wildcard characters in pattern, compare strings
|
||||
|
||||
case WILDCARD_NONE:
|
||||
if (isCaseSensitive())
|
||||
{
|
||||
if (str.compareTo(m_pattern) == 0)
|
||||
sts = true;
|
||||
}
|
||||
else if (str.equalsIgnoreCase(m_pattern))
|
||||
sts = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Return the wildcard match status
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a complex wildcard pattern with the specified string
|
||||
*
|
||||
* @param str String
|
||||
* @return boolean
|
||||
*/
|
||||
protected final boolean matchComplexWildcard(String str)
|
||||
{
|
||||
|
||||
// Convert the string to a char array for matching
|
||||
|
||||
char[] strChars = str.toCharArray();
|
||||
|
||||
// Compare the string to the wildcard pattern
|
||||
|
||||
int wpos = 0;
|
||||
int wlen = m_patternChars.length;
|
||||
|
||||
int spos = 0;
|
||||
int slen = strChars.length;
|
||||
|
||||
char patChar;
|
||||
boolean matchFailed = false;
|
||||
|
||||
while (matchFailed == false && wpos < m_patternChars.length)
|
||||
{
|
||||
|
||||
// Match the current pattern character
|
||||
|
||||
patChar = m_patternChars[wpos++];
|
||||
|
||||
switch (patChar)
|
||||
{
|
||||
|
||||
// Match single character
|
||||
|
||||
case SINGLECHAR_WILDCARD:
|
||||
if (spos < slen)
|
||||
spos++;
|
||||
else
|
||||
matchFailed = true;
|
||||
break;
|
||||
|
||||
// Match zero or more characters
|
||||
|
||||
case MULTICHAR_WILDCARD:
|
||||
|
||||
// Check if there is another character in the wildcard pattern
|
||||
|
||||
if (wpos < wlen)
|
||||
{
|
||||
|
||||
// Check if the character is not a wildcard character
|
||||
|
||||
patChar = m_patternChars[wpos];
|
||||
if (patChar != SINGLECHAR_WILDCARD && patChar != MULTICHAR_WILDCARD)
|
||||
{
|
||||
|
||||
// Find the required character in the string
|
||||
|
||||
while (spos < slen && strChars[spos] != patChar)
|
||||
spos++;
|
||||
if (spos >= slen)
|
||||
matchFailed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Multi character wildcard at the end of the pattern, match all remaining
|
||||
// characters
|
||||
|
||||
spos = slen;
|
||||
}
|
||||
break;
|
||||
|
||||
// Match the pattern and string character
|
||||
|
||||
default:
|
||||
if (spos >= slen || strChars[spos] != patChar)
|
||||
matchFailed = true;
|
||||
else
|
||||
spos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the match was successul and return status
|
||||
|
||||
if (matchFailed == false && spos == slen)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the wildcard pattern string
|
||||
*
|
||||
* @param pattern String
|
||||
* @param caseSensitive boolean
|
||||
*/
|
||||
public final void setPattern(String pattern, boolean caseSensitive)
|
||||
{
|
||||
|
||||
// Save the pattern string and case sensitive flag
|
||||
|
||||
m_pattern = pattern;
|
||||
m_caseSensitive = caseSensitive;
|
||||
|
||||
setType(WILDCARD_INVALID);
|
||||
|
||||
// Check if the pattern string is valid
|
||||
|
||||
if (pattern == null || pattern.length() == 0)
|
||||
return;
|
||||
|
||||
// Check for the match all wildcard
|
||||
|
||||
if (pattern.compareTo("*.*") == 0 || pattern.compareTo("*") == 0)
|
||||
{
|
||||
setType(WILDCARD_ALL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for a name wildcard, ie. '*.ext'
|
||||
|
||||
if (pattern.startsWith("*."))
|
||||
{
|
||||
|
||||
// Split the string to get the extension string
|
||||
|
||||
if (pattern.length() > 2)
|
||||
m_matchPart = pattern.substring(1);
|
||||
else
|
||||
m_matchPart = "";
|
||||
|
||||
// If matching is case insensitive then normalize the string
|
||||
|
||||
if (isCaseSensitive() == false)
|
||||
m_matchPart = m_matchPart.toUpperCase();
|
||||
|
||||
// If the file extension contains wildcards we will need to use a regular expression
|
||||
|
||||
if (containsWildcards(m_matchPart) == false)
|
||||
{
|
||||
setType(WILDCARD_NAME);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a file extension wildcard
|
||||
|
||||
if (pattern.endsWith(".*"))
|
||||
{
|
||||
|
||||
// Split the string to get the name string
|
||||
|
||||
if (pattern.length() > 2)
|
||||
m_matchPart = pattern.substring(0, pattern.length() - 2);
|
||||
else
|
||||
m_matchPart = "";
|
||||
|
||||
// If matching is case insensitive then normalize the string
|
||||
|
||||
if (isCaseSensitive() == false)
|
||||
m_matchPart = m_matchPart.toUpperCase();
|
||||
|
||||
// If the file name contains wildcards we will need to use a regular expression
|
||||
|
||||
if (containsWildcards(m_matchPart) == false)
|
||||
{
|
||||
setType(WILDCARD_EXT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the complex wildcard pattern as a char array for later pattern matching
|
||||
|
||||
if (isCaseSensitive() == false)
|
||||
m_patternChars = m_pattern.toUpperCase().toCharArray();
|
||||
else
|
||||
m_patternChars = m_pattern.toCharArray();
|
||||
|
||||
setType(WILDCARD_COMPLEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the wildcard type
|
||||
*
|
||||
* @param typ int
|
||||
*/
|
||||
private final void setType(int typ)
|
||||
{
|
||||
m_type = typ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the wildcard as a string
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer str = new StringBuffer();
|
||||
str.append("[");
|
||||
str.append(getPattern());
|
||||
str.append(",");
|
||||
str.append(isType());
|
||||
str.append(",");
|
||||
|
||||
if (m_matchPart != null)
|
||||
str.append(m_matchPart);
|
||||
|
||||
if (isCaseSensitive())
|
||||
str.append(",Case");
|
||||
else
|
||||
str.append(",NoCase");
|
||||
str.append("]");
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the string contains any wildcard characters.
|
||||
*
|
||||
* @return boolean
|
||||
* @param str java.lang.String
|
||||
*/
|
||||
public final static boolean containsWildcards(String str)
|
||||
{
|
||||
|
||||
// Check the string for wildcard characters
|
||||
|
||||
if (str.indexOf(MULTICHAR_WILDCARD) != -1)
|
||||
return true;
|
||||
|
||||
if (str.indexOf(SINGLECHAR_WILDCARD) != -1)
|
||||
return true;
|
||||
|
||||
// No wildcards found in the string
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a string contains any of the Unicode wildcard characters
|
||||
*
|
||||
* @param str String
|
||||
* @return boolean
|
||||
*/
|
||||
public final static boolean containsUnicodeWildcard(String str)
|
||||
{
|
||||
|
||||
// Check if the string contains any of the Unicode wildcards
|
||||
|
||||
if (str.indexOf(SINGLECHAR_UNICODE_WILDCARD) != -1 || str.indexOf(MULTICHAR_UNICODE_WILDCARD) != -1
|
||||
|| str.indexOf(DOT_UNICODE_WILDCARD) != -1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the Unicode wildcard string to a standard DOS wildcard string
|
||||
*
|
||||
* @param str String
|
||||
* @return String
|
||||
*/
|
||||
public final static String convertUnicodeWildcardToDOS(String str)
|
||||
{
|
||||
|
||||
// Create a buffer for the new wildcard string
|
||||
|
||||
StringBuffer newStr = new StringBuffer(str.length());
|
||||
|
||||
// Convert the Unicode wildcard string to a DOS wildcard string
|
||||
|
||||
for (int i = 0; i < str.length(); i++)
|
||||
{
|
||||
|
||||
// Get the current character
|
||||
|
||||
char ch = str.charAt(i);
|
||||
|
||||
// Check for a Unicode wildcard character
|
||||
|
||||
if (ch == SINGLECHAR_UNICODE_WILDCARD)
|
||||
{
|
||||
|
||||
// Translate to the DOS single character wildcard character
|
||||
|
||||
ch = SINGLECHAR_WILDCARD;
|
||||
}
|
||||
else if (ch == MULTICHAR_UNICODE_WILDCARD)
|
||||
{
|
||||
|
||||
// Check if the current character is followed by a '.', if so then translate to the
|
||||
// DOS multi character
|
||||
// wildcard
|
||||
|
||||
if (i < (str.length() - 1) && str.charAt(i + 1) == '.')
|
||||
ch = MULTICHAR_WILDCARD;
|
||||
}
|
||||
else if (ch == DOT_UNICODE_WILDCARD)
|
||||
{
|
||||
|
||||
// Check if the current character is followed by a DOS single/multi character
|
||||
// wildcard
|
||||
|
||||
if (i < (str.length() - 1))
|
||||
{
|
||||
char nextCh = str.charAt(i + 1);
|
||||
if (nextCh == SINGLECHAR_WILDCARD || nextCh == MULTICHAR_WILDCARD
|
||||
|| nextCh == SINGLECHAR_UNICODE_WILDCARD)
|
||||
ch = '.';
|
||||
}
|
||||
}
|
||||
|
||||
// Append the character to the translated wildcard string
|
||||
|
||||
newStr.append(ch);
|
||||
}
|
||||
|
||||
// Return the translated wildcard string
|
||||
|
||||
return newStr.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a wildcard string to a regular expression
|
||||
*
|
||||
* @param path String
|
||||
* @return String
|
||||
*/
|
||||
public final static String convertToRegexp(String path)
|
||||
{
|
||||
|
||||
// Convert the path to characters, check if the wildcard string ends with a single character
|
||||
// wildcard
|
||||
|
||||
char[] smbPattern = path.toCharArray();
|
||||
boolean endsWithQ = smbPattern[smbPattern.length - 1] == '?';
|
||||
|
||||
// Build up the regular expression
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append('^');
|
||||
|
||||
for (int i = 0; i < smbPattern.length; i++)
|
||||
{
|
||||
|
||||
// Process the current character
|
||||
|
||||
switch (smbPattern[i])
|
||||
{
|
||||
|
||||
// Multi character wildcard
|
||||
|
||||
case '*':
|
||||
sb.append(".*");
|
||||
break;
|
||||
|
||||
// Single character wildcard
|
||||
|
||||
case '?':
|
||||
if (endsWithQ)
|
||||
{
|
||||
boolean restQ = true;
|
||||
for (int j = i + 1; j < smbPattern.length; j++)
|
||||
{
|
||||
if (smbPattern[j] != '?')
|
||||
{
|
||||
restQ = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (restQ)
|
||||
sb.append(".?");
|
||||
else
|
||||
sb.append('.');
|
||||
}
|
||||
else
|
||||
sb.append('.');
|
||||
break;
|
||||
|
||||
// Escape regular expression special characters
|
||||
|
||||
case '.':
|
||||
case '+':
|
||||
case '\\':
|
||||
case '[':
|
||||
case ']':
|
||||
case '^':
|
||||
case '$':
|
||||
case '(':
|
||||
case ')':
|
||||
sb.append('\\');
|
||||
sb.append(smbPattern[i]);
|
||||
break;
|
||||
|
||||
// Normal characters, just pass through
|
||||
|
||||
default:
|
||||
sb.append(smbPattern[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sb.append('$');
|
||||
|
||||
// Return the regular expression string
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user