buf.append('/'); if (segment.isTraverse()) { buf.append(WILDCARD_REPLACEMENT); for (PatternElement element : segment.getElements()) { switch (element.getKind()) { case TOKEN:
/** * Resolves the given path. * @param path the given path * @return the base path, or {@code empty} if it is not a valid base path */ public static Optional<BasePath> parse(String path) { if (isEmpty(path)) { return Optional.of(EMPTY); } FilePattern pattern = FilePattern.compile(path); List<String> results = new ArrayList<>(); for (FilePattern.Segment segment : pattern.getSegments()) { if (isPlain(segment)) { results.add(segment.toString()); } else { return Optional.empty(); } } return Optional.of(new BasePath(results)); }
LinkedList<Segment> segments = new LinkedList<>(pattern.getSegments()); while (segments.isEmpty() == false) { if (segments.getFirst().isTraverse()) { segments.removeFirst(); current = recursiveStep(fs, current);
private static List<Path> consumeStep(LinkedList<Segment> segments) { assert segments != null; assert segments.isEmpty() == false; assert segments.getFirst().isTraverse() == false; List<Path> results = new ArrayList<>(); results.add(new Path(segment)); while (isGlobRequired(current) && segments.isEmpty() == false && segments.getFirst().isTraverse() == false) { current = segments.removeFirst(); Set<String> suffixCandidates = resolve(current);
private static Set<String> resolve(Segment segment) { assert segment != null; assert segment.isTraverse() == false; List<Set<String>> candidates = new ArrayList<>(); for (PatternElement element : segment.getElements()) { switch (element.getKind()) { case TOKEN: candidates.add(Collections.singleton(element.getToken())); break; case WILDCARD: candidates.add(Collections.singleton("*")); //$NON-NLS-1$ break; case SELECTION: candidates.add(new TreeSet<>(((Selection) element).getContents())); break; default: throw new AssertionError(); } } List<String> results = stringCrossJoin(candidates); return new TreeSet<>(results); }
/** * A complex pattern. */ @Test public void complex() { FilePattern compiled = FilePattern.compile("alpha/**/{beta|gamma}/${date}-*.csv"); assertThat(compiled.containsVariables(), is(true)); List<Segment> segments = compiled.getSegments(); assertThat(segments.size(), is(4)); assertThat(segments.get(0).isTraverse(), is(false)); assertThat(segments.get(0).getElements(), is(kind(TOKEN))); assertThat(segments.get(0).getElements(), is(token("alpha"))); assertThat(segments.get(1).isTraverse(), is(true)); assertThat(segments.get(2).isTraverse(), is(false)); assertThat(segments.get(2).getElements(), is(kind(SELECTION))); assertThat(segments.get(2).getElements(), is(token("{beta|gamma}"))); assertThat(segments.get(3).isTraverse(), is(false)); assertThat(segments.get(3).getElements(), is(kind(VARIABLE, TOKEN, WILDCARD, TOKEN))); assertThat(segments.get(3).getElements(), is(token("${date}", "-", "*", ".csv"))); }
/** * multiple segments. */ @Test public void segments() { FilePattern compiled = FilePattern.compile("alpha/beta/gamma"); List<Segment> segments = compiled.getSegments(); assertThat(segments.size(), is(3)); assertThat(segments.get(0).isTraverse(), is(false)); assertThat(segments.get(0).getElements(), is(kind(TOKEN))); assertThat(segments.get(0).getElements(), is(token("alpha"))); assertThat(segments.get(1).isTraverse(), is(false)); assertThat(segments.get(1).getElements(), is(kind(TOKEN))); assertThat(segments.get(1).getElements(), is(token("beta"))); assertThat(segments.get(2).isTraverse(), is(false)); assertThat(segments.get(2).getElements(), is(kind(TOKEN))); assertThat(segments.get(2).getElements(), is(token("gamma"))); }
private static Segment consumeSegment(Cursor cursor) { assert cursor != null; int first = cursor.get(0); assert first != CHAR_SEPARATOR && first != CHAR_EOF : cursor; // special case if (first == CHAR_ASTERISK && cursor.get(1) == CHAR_ASTERISK && (cursor.get(2) == CHAR_SEPARATOR || cursor.get(2) == CHAR_EOF)) { cursor.skipWhile(CHAR_ASTERISK); cursor.skipWhile(CHAR_SEPARATOR); return Segment.TRAVERSE; } List<PatternElement> elements = consumeElements(cursor); return new Segment(elements); }
/** * Returns the pattern element kinds appeared in this pattern. * @return the pattern element kinds * @since 0.7.0 */ public Set<PatternElementKind> getPatternElementKinds() { Set<PatternElementKind> results = EnumSet.noneOf(PatternElementKind.class); for (Segment segment : segments) { for (PatternElement element : segment.getElements()) { results.add(element.getKind()); } } return results; }
/** * A selection pattern. */ @Test public void selection_empty() { FilePattern compiled = FilePattern.compile("{}"); assertThat(compiled.containsVariables(), is(false)); List<Segment> segments = compiled.getSegments(); assertThat(segments.size(), is(1)); assertThat(segments.get(0).isTraverse(), is(false)); assertThat(segments.get(0).getElements(), is(kind(SELECTION))); assertThat(segments.get(0).getElements(), is(token("{}"))); }
/** * A token. */ @Test public void token() { FilePattern compiled = FilePattern.compile("a"); assertThat(compiled.containsVariables(), is(false)); List<Segment> segments = compiled.getSegments(); assertThat(segments.size(), is(1)); assertThat(segments.get(0).isTraverse(), is(false)); assertThat(segments.get(0).getElements(), is(kind(TOKEN))); assertThat(segments.get(0).getElements(), is(token("a"))); }
/** * Returns whether this pattern contains traverse ({@code **}). * @return {@code true} if contains * @since 0.7.0 */ public boolean containsTraverse() { for (Segment segment : segments) { if (segment.isTraverse()) { return true; } } return false; }
/** * A complex pattern (all csv). */ @Test public void all_csv() { FilePattern compiled = FilePattern.compile("**/*.csv"); List<Segment> segments = compiled.getSegments(); assertThat(segments.size(), is(2)); assertThat(segments.get(0).isTraverse(), is(true)); assertThat(segments.get(1).isTraverse(), is(false)); assertThat(segments.get(1).getElements(), is(kind(WILDCARD, TOKEN))); assertThat(segments.get(1).getElements(), is(token("*", ".csv"))); }
/** * A selection pattern. */ @Test public void selection() { FilePattern compiled = FilePattern.compile("{alpha|beta|gamma}"); assertThat(compiled.containsVariables(), is(false)); List<Segment> segments = compiled.getSegments(); assertThat(segments.size(), is(1)); assertThat(segments.get(0).isTraverse(), is(false)); assertThat(segments.get(0).getElements(), is(kind(SELECTION))); assertThat(segments.get(0).getElements(), is(token("{alpha|beta|gamma}"))); }
/** * A selection pattern. */ @Test public void selection_containsEmpty() { FilePattern compiled = FilePattern.compile("{alpha||gamma}"); assertThat(compiled.containsVariables(), is(false)); List<Segment> segments = compiled.getSegments(); assertThat(segments.size(), is(1)); assertThat(segments.get(0).isTraverse(), is(false)); assertThat(segments.get(0).getElements(), is(kind(SELECTION))); assertThat(segments.get(0).getElements(), is(token("{alpha||gamma}"))); }
/** * A wildcard pattern. */ @Test public void wildcard() { FilePattern compiled = FilePattern.compile("*"); assertThat(compiled.containsVariables(), is(false)); List<Segment> segments = compiled.getSegments(); assertThat(segments.size(), is(1)); assertThat(segments.get(0).isTraverse(), is(false)); assertThat(segments.get(0).getElements(), is(kind(WILDCARD))); assertThat(segments.get(0).getElements(), is(token("*"))); }
/** * A variable pattern. */ @Test public void variable() { FilePattern compiled = FilePattern.compile("${v}"); assertThat(compiled.containsVariables(), is(true)); List<Segment> segments = compiled.getSegments(); assertThat(segments.size(), is(1)); assertThat(segments.get(0).isTraverse(), is(false)); assertThat(segments.get(0).getElements(), is(kind(VARIABLE))); assertThat(segments.get(0).getElements(), is(token("${v}"))); }
@Override public String toString() { if (isTraverse()) { return "**"; } else { StringBuilder buf = new StringBuilder(); elements.forEach(buf::append); return buf.toString(); } } }
private static BasePath headOf(FilePattern pattern) { List<String> results = new ArrayList<>(); for (FilePattern.Segment segment : pattern.getSegments()) { if (isPlain(segment)) { results.add(segment.toString()); } else { break; } } return new BasePath(results); }
private static boolean isGlobRequired(Segment segment) { assert segment != null; assert segment.isTraverse() == false; for (PatternElement element : segment.getElements()) { if (element.getKind() == PatternElementKind.WILDCARD) { return false; } } return true; }