com.thaiopensource.validate.picl.PathPattern Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wicketstuff-jing Show documentation
Show all versions of wicketstuff-jing Show documentation
Jing is a validator for RELAX NG and other schema languages. This
project was taken from http://code.google.com/p/jing-trang and
mavenized for inclusion in the Wicket Stuff HTML Validator.
The code was taken from the 20091111 release.
package com.thaiopensource.validate.picl;
abstract class PathPattern extends Pattern {
private final String[] names;
private final boolean[] descendantsOrSelf;
static final String ANY = "#any";
PathPattern(String[] names, boolean[] descendantsOrSelf) {
this.names = names;
this.descendantsOrSelf = descendantsOrSelf;
}
abstract boolean isAttribute();
boolean matches(Path path, int rootDepth) {
return (isAttribute() == path.isAttribute()
&& matchSegment(path, rootDepth, path.length() - rootDepth, 0, names.length >> 1, false));
}
private boolean matchSegment(Path path, int pathStartIndex, int pathLength,
int patternStartIndex, int patternLength,
boolean ignoreRightmostDescendantsOrSelf) {
if (patternLength > pathLength)
return false;
while (patternLength > 0
&& (ignoreRightmostDescendantsOrSelf
|| !descendantsOrSelf[patternStartIndex + patternLength])) {
if (!matchStep(path, pathStartIndex + pathLength - 1, patternStartIndex + patternLength - 1))
return false;
pathLength--;
patternLength--;
ignoreRightmostDescendantsOrSelf = false;
}
while (patternLength > 0 && !descendantsOrSelf[patternStartIndex]) {
if (!matchStep(path, pathStartIndex, patternStartIndex))
return false;
pathStartIndex++;
patternStartIndex++;
pathLength--;
patternLength--;
}
if (patternLength == 0)
return descendantsOrSelf[patternStartIndex] || pathLength == 0;
for (pathLength--; pathLength >= patternLength; pathLength--)
if (matchSegment(path, pathStartIndex, pathLength, patternStartIndex, patternLength, true))
return true;
return false;
}
private boolean matchStep(Path path, int pathIndex, int patternIndex) {
patternIndex *= 2;
return (matchName(path.getNamespaceUri(pathIndex), names[patternIndex])
&& matchName(path.getLocalName(pathIndex), names[patternIndex + 1]));
}
private static boolean matchName(String str, String pattern) {
if (pattern == ElementPathPattern.ANY)
return true;
return str.equals(pattern);
}
public String toString() {
StringBuffer buf = new StringBuffer();
for (int i = 0, j = 0; i < names.length; i += 2, j++) {
if (j != 0)
buf.append(descendantsOrSelf[j] ? "//" : "/");
else if (descendantsOrSelf[0])
buf.append(".//");
if (isAttribute() && i + 2 == names.length)
buf.append('@');
if (names[i] == ANY)
buf.append('*');
else {
if (names[i].length() != 0) {
buf.append('{');
buf.append(names[i]);
buf.append('}');
}
buf.append(names[i + 1] == ANY ? "*" : names[i + 1]);
}
}
if (names.length == 0)
buf.append(descendantsOrSelf[0] ? ".//." : ".");
else if (descendantsOrSelf[descendantsOrSelf.length - 1])
buf.append("//.");
return buf.toString();
}
}