package com.github.marschall.memoryfilesystem;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.util.Collections;
import java.util.List;
final class GlobPathMatcher implements PathMatcher {
private final boolean isAbsolute;
private final List<GlobMatch> matches;
GlobPathMatcher(boolean isAbsolute, List<GlobMatch> matches) {
this.isAbsolute = isAbsolute;
this.matches = matches;
}
@Override
public boolean matches(Path path) {
if (path.isAbsolute() != this.isAbsolute) {
return false;
}
ElementPath elementPath = (ElementPath) path;
return this.matches(elementPath.getNameElements(), this.matches);
}
private boolean matches(List<String> elements, List<GlobMatch> matches) {
if (elements.isEmpty()) {
for (GlobMatch match : matches) {
if (!match.isFlexible()) {
return false;
}
}
return true;
}
String element = elements.get(0);
if (elements.size() == 1) {
for (int i = 0; i < matches.size(); ++i) {
GlobMatch match = matches.get(i);
if (!match.isFlexible()) {
if (!match.matches(element)) {
return false;
} else if (i == matches.size() - 1) {
return true;
} else {
List<GlobMatch> remainingMatches = matches.subList(i + 1, matches.size());
return this.matches(Collections.<String>emptyList(), remainingMatches);
}
}
}
}
if (matches.isEmpty()) {
return false;
}
GlobMatch firstMatch = matches.get(0);
if (!firstMatch.isFlexible()) {
if (firstMatch.matches(element) && matches.size() > 1) {
return this.matches(elements.subList(1, elements.size()), matches.subList(1, matches.size()));
} else {
return false;
}
} else {
List<String> remainingElements = elements.subList(1, elements.size());
return this.matches(remainingElements, matches)
|| this.matches(remainingElements, matches.subList(1, matches.size()));
}
}
static String name() {
return "glob";
}
interface GlobMatch {
boolean isFlexible();
boolean matches(String element);
}
}