in utils/src/main/java/com/google/apphosting/utils/glob/GlobIntersector.java [154:283]
private void doIntersectTwo(Glob inputGlob1, Glob inputGlob2, HashSet<Glob> outputGlobs) {
String pattern1 = inputGlob1.getPattern();
String pattern2 = inputGlob2.getPattern();
// To simplify the work we do below, we first check to see if the
// supplied globs share a common prefix excluding wildcards.
//
// For example:
// ab*d becomes: a | b*d
// a*cd a | *cd
String prefix = extractPrefix(pattern1, pattern2);
if (prefix != null) {
int prefixLength = prefix.length();
// The prefix is guaranteed to exclude wildcards, so if they
// don't match then we're done here.
if (!prefix.equals(pattern2.substring(0, prefixLength))) {
outputGlobs.add(inputGlob1);
outputGlobs.add(inputGlob2);
} else {
// Strip off the prefix and recurse on the non-prefixed version.
HashSet<Glob> newGlobs = new LinkedHashSet<Glob>();
doIntersectTwo(
GlobFactory.createChildGlob(pattern1.substring(prefixLength), inputGlob1),
GlobFactory.createChildGlob(pattern2.substring(prefixLength), inputGlob2),
newGlobs);
// Now put the prefix back onto all of the returned globs.
for (Glob newGlob : newGlobs) {
outputGlobs.add(GlobFactory.createChildGlob(prefix + newGlob.getPattern(), newGlob));
}
}
return;
}
// Now we do the same thing we did for prefixes with suffixes.
//
// For example:
// b*d becomes: b*d | d
// *cd *cd | d
String suffix = extractSuffix(pattern1, pattern2);
if (suffix != null) {
int suffixLength = suffix.length();
// The suffix is guaranteed to exclude wildcards, so if they
// don't match then we're done here.
if (!suffix.equals(pattern2.substring(pattern2.length() - suffixLength))) {
outputGlobs.add(inputGlob1);
outputGlobs.add(inputGlob2);
} else {
// Strip off the suffix and recurse on the non-suffixed version.
HashSet<Glob> newGlobs = new LinkedHashSet<Glob>();
doIntersectTwo(GlobFactory.createChildGlob(
pattern1.substring(0, pattern1.length() - suffixLength),
inputGlob1),
GlobFactory.createChildGlob(
pattern2.substring(0, pattern2.length() - suffixLength),
inputGlob2),
newGlobs);
// Now put the suffix back onto all of the returned globs.
for (Glob newGlob : newGlobs) {
outputGlobs.add(GlobFactory.createChildGlob(newGlob.getPattern() + suffix, newGlob));
}
}
return;
}
// For example:
// abc*xyz adds: abc*ghi*xyz
// *ghi*
if (pattern1.length() > 1 && pattern1.startsWith("*") && pattern1.endsWith("*")) {
for (int star = pattern2.indexOf("*"); star != -1; star = pattern2.indexOf("*", star + 1)) {
outputGlobs.add(GlobFactory.createChildGlob(
pattern2.substring(0, star) + pattern1 + pattern2.substring(star + 1),
inputGlob1, inputGlob2));
}
}
// This is just the opposite of what we just did because we can't
// be sure about the order.
//
// For example:
// *ghi* adds: abc*ghi*xyz
// abc*xyz
if (pattern2.length() > 1 && pattern2.startsWith("*") && pattern2.endsWith("*")) {
for (int star = pattern1.indexOf("*"); star != -1; star = pattern1.indexOf("*", star + 1)) {
outputGlobs.add(GlobFactory.createChildGlob(
pattern1.substring(0, star) + pattern2 + pattern1.substring(star + 1),
inputGlob1, inputGlob2));
}
}
// For example:
// abc* adds: abc*xyz
// *xyz
if (pattern1.length() > 1 && pattern2.length() > 1 &&
pattern1.endsWith("*") && pattern2.startsWith("*")) {
String trimmedPattern1 = pattern1.substring(0, pattern1.length() - 1);
outputGlobs.add(GlobFactory.createChildGlob(trimmedPattern1 + pattern2,
inputGlob1,
inputGlob2));
// For example:
// abc* adds: abc
// *c
if (inputGlob2.matchesAll(trimmedPattern1)) {
outputGlobs.add(GlobFactory.createChildGlob(trimmedPattern1, inputGlob1, inputGlob2));
}
}
// This is just the opposite of what we just did because we can't
// be sure about the order.
//
// For example:
// *xyz
// abc* adds: abc*xyz
if (pattern1.length() > 1 && pattern2.length() > 1 &&
pattern1.startsWith("*") && pattern2.endsWith("*")) {
String trimmedPattern2 = pattern2.substring(0, pattern2.length() - 1);
outputGlobs.add(GlobFactory.createChildGlob(trimmedPattern2 + pattern1,
inputGlob1,
inputGlob2));
// For example:
// *c adds: abc
// abc*
if (inputGlob1.matchesAll(trimmedPattern2)) {
outputGlobs.add(GlobFactory.createChildGlob(trimmedPattern2, inputGlob1, inputGlob2));
}
}
// Now include the two original patterns.
outputGlobs.add(inputGlob1);
outputGlobs.add(inputGlob2);
}