com.day.text.GlobPattern Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2012 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.day.text;
/**
* The GlobPattern
implements matching operations that do a
* pattern globbing.
*/
public class GlobPattern {
/** Pattern strings should be compared to. */
private final String pattern;
/** if this is present, use for handle comparison (acl) */
private final String handlePattern;
/**
* Class constructor that create a GlobPattern
with the given
* pattern. If the ishandle
flag is true
this
* will construct a hierarchy matcher.
*
* @param pattern pattern string
* @param ishandle if true
and the pattern contains no
* wildcards, the {@link #matches(String)} returns true, if
* the compared string is equal or starts with the
* pattern+"/" (i.e. is a child page)
*/
public GlobPattern(String pattern, boolean ishandle) {
this.pattern = pattern;
if (ishandle && !containsWildcards(pattern)) {
handlePattern = (pattern.equals("/")) ? "/" : pattern + '/';
} else {
handlePattern = null;
}
}
/**
* Class constructor that create a GlobPattern
with the given
* pattern.
*
* @param pattern pattern string
*/
public GlobPattern(String pattern) {
this(pattern, false);
}
/**
* Returns a flag indicating whether a string matches this pattern.
*
* @param s string to be checked
* @return true
if s matches this pattern, else
* false
.
*/
public final boolean matches(String s) {
if (handlePattern != null) {
// do handle comparison
if (pattern.equals(s)) return true;
return s.startsWith(handlePattern);
}
return recurseMatchPattern(pattern, s, 0, 0);
}
/**
* Returns a flag indicating whether a string matches a pattern.
*
* @param pattern pattern used for comparison
* @param s string to be checked
* @return true
if s matches pattern,
* else false
.
*/
public static final boolean matches(String pattern, String s) {
return recurseMatchPattern(pattern, s, 0, 0);
}
/**
* Returns a flag indicating whether a string matches a pattern. if the
* ishandle is true
and the pattern contains
* no wildcards, the method returns true, if the pattern is a hierarchical
* father of the string.
*
* @param pattern pattern used for comparison
* @param s string to be checked
* @param ishandle flag, indicating, if a handle comparison has to be
* performed
* @return true
if s matches pattern,
* else false
.
*/
public static final boolean matches(String pattern, String s,
boolean ishandle) {
if (ishandle && !containsWildcards(pattern)) {
if (pattern.equals(s)) {
return true;
}
return s.startsWith(pattern + '/');
}
return GlobPattern.matches(pattern, s);
}
/**
* Returns a flag indicating whether a string matches a pattern. unlike the
* matches
methods, this matching is done shell-like.
*
* @param s string to be checked
*
* @return true
if the string matches shell-like;
* false
otherwise.
*/
public boolean shellMatches(String s) {
return shellMatches(s, '/');
}
/**
* Returns a flag indicating whether a string matches a pattern. unlike the
* matches
methods, this matching is done shell-like.
*
* @param s string to be checked
* @param c character to be used as path delimiter
*
* @return true
if the string matches shell-like;
* false
otherwise.
*/
public boolean shellMatches(String s, char c) {
if (pattern.equals("*")) return true;
int sc = 0;
for (int len = s.length() - 1; len >= 0; len--)
if (s.charAt(len) == c) sc++;
for (int len = pattern.length() - 1; len >= 0; len--)
if (pattern.charAt(len) == c) sc--;
if (sc != 0) return false;
return matches(s);
}
/**
* Returns true
if the string contains wildcards.
*
* @param s string to be checked
* @return true
if s contains wildcards, else
* false
.
*/
public static final boolean containsWildcards(String s) {
return indexOfWildcard(s) >= 0;
}
/**
* Returns the index of the first wildcard character in the string or
* -1
if the string does not contain a wild card character.
*
* @param s string to be checked
*/
public static final int indexOfWildcard(String s) {
for (int i = 0; i < s.length(); i++) {
if ("*?[]".indexOf(s.charAt(i)) != -1) {
return i;
}
}
// not found, return -1
return -1;
}
/**
* An internal routine to implement expression matching.
* This routine is based on a self-recursive algorithm.
*
* @param pattern The pattern
* @param s The string to be compared.
* @param sIdx The index of where we are in string.
* @param pIdx The index of where we are in pattern.
* @return True if string matched pattern, else false.
*/
private static boolean recurseMatchPattern(String pattern, String s,
int sIdx, int pIdx) {
int pLen = pattern.length();
int sLen = s.length();
for (;;) {
if (pIdx >= pLen) {
return (sIdx >= sLen);
}
if (sIdx >= sLen && pattern.charAt(pIdx) != '*') {
return false;
}
// Check for a '*' as the next pattern char.
// This is handled by a recursive call for
// each postfix of the name.
if (pattern.charAt(pIdx) == '*') {
if (++pIdx >= pLen) {
return true;
}
for (;;) {
if (recurseMatchPattern(pattern, s, sIdx, pIdx)) {
return true;
}
if (sIdx >= sLen) {
return false;
}
++sIdx;
}
}
// Check for '?' as the next pattern char.
// This matches the current character.
if (pattern.charAt(pIdx) == '?') {
++pIdx;
++sIdx;
continue;
}
// Check for '[' as the next pattern char.
// This is a list of acceptable characters,
// which can include character ranges.
if (pattern.charAt(pIdx) == '[') {
for (++pIdx ; ; ++pIdx) {
if (pIdx >= pLen || pattern.charAt(pIdx) == ']') {
return false;
}
if (pattern.charAt(pIdx) == s.charAt(sIdx) ) {
break;
}
if (pIdx < (pLen - 1)
&& pattern.charAt(pIdx + 1) == '-') {
if (pIdx >= (pLen - 2)) {
return false;
}
char chStr = s.charAt(sIdx);
char chPtn = pattern.charAt(pIdx);
char chPtn2 = pattern.charAt(pIdx+2);
if ((chPtn <= chStr) && (chPtn2 >= chStr)) {
break;
}
if ((chPtn >= chStr) && (chPtn2 <= chStr)) {
break;
}
pIdx += 2;
}
}
for ( ; pattern.charAt(pIdx) != ']'; ++pIdx) {
if (pIdx >= pLen) {
--pIdx;
break;
}
}
++pIdx;
++sIdx;
continue;
}
// Check for backslash escapes
// We just skip over them to match the next char.
if (pattern.charAt(pIdx) == '\\' ) {
if (++pIdx >= pLen) {
return false;
}
}
if (pIdx < pLen && sIdx < sLen) {
if (pattern.charAt(pIdx) != s.charAt(sIdx)) {
return false;
}
}
++pIdx;
++sIdx;
}
}
/**
* Returns the pattern of this GlobPattern
* @return the pattern.
*/
public String toString() {
return pattern;
}
/**
* Returns true
if this
GlobPattern
* is equal to object obj
.
*
* @param obj the object to compare for equality.
* @return true
if this
GlobPattern
* is equal to object obj
.
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof GlobPattern) {
GlobPattern other = (GlobPattern)obj;
return (this.pattern.equals(other.pattern)
&& this.isHandlePattern() == other.isHandlePattern());
}
return false;
}
/**
* Returns the hashCode for this GlobPattern
.
* @return the hashCode for this GlobPattern
.
*/
public int hashCode() {
return this.pattern.hashCode() + ((isHandlePattern()) ? 1 : 0);
}
/**
* Returns true
if this GlobPattern is a handle pattern.
* @return true
if this GlobPattern is a handle pattern;
* false
otherwise.
*/
private boolean isHandlePattern() {
return handlePattern != null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy