net.sf.mmm.util.pattern.base.PathPatternCompiler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mmm-util-pattern Show documentation
Show all versions of mmm-util-pattern Show documentation
provides pattern matching abstraction to flexibly choose between regex and glob.
The newest version!
/* Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0 */
package net.sf.mmm.util.pattern.base;
import net.sf.mmm.util.pattern.api.PatternCompiler;
/**
* This is an implementation of the {@link PatternCompiler} interface that {@link #compile(String) compiles}
* path-glob-patterns. A path-glob-pattern is like a {@link GlobPatternCompiler glob-pattern} but more specific
* for matching directory paths:
*
* - {@code '?'} matches any character except for a slash ({@code '/'} or {@code '\\'}).
* - A single {@code '*'} matches a sequence of characters excluding slashes including the empty sequence.
* - {@code '**'} matches any sequence of characters (including slashes).
* - the character {@code '/'} matches a slash ({@code '/'} or {@code '\\'}).
* '**/'
matches any sequence terminated by a slash as well as the empty sequence.
*
* The idea is taken from ant even though it might be
* slightly different.
* Examples:
*
* - {@code A*bc?e} matches {@code Abcde} or {@code AFOObarbcxe} but NOT {@code abcde} or {@code Abce}.
*
*
* @author Joerg Hohwiller (hohwille at users.sourceforge.net)
* @since 1.0.0
*/
public class PathPatternCompiler extends AbstractGlobPatternCompiler {
/** A singleton instance of this instance. */
public static final PatternCompiler INSTANCE = new PathPatternCompiler();
/**
* The constructor.
*/
public PathPatternCompiler() {
super();
}
@Override
protected int process(char[] chars, int charIndex, java.lang.StringBuilder buffer) {
int next = charIndex + 1;
char c = chars[charIndex];
if (c == '*') {
if ((next < chars.length) && (chars[next] == '*')) {
// '**'
next = next + 1;
if ((next < chars.length) && (chars[next] == '/')) {
// '**/'
next = next + 1;
buffer.append("(|.*[/\\\\])");
return next;
}
buffer.append(".*");
return next;
}
buffer.append("[^/\\\\]+");
} else if (c == '?') {
buffer.append("[^/\\\\]");
} else if (c == '/') {
buffer.append("[/\\\\]");
} else {
return super.process(chars, charIndex, buffer);
}
return next;
}
}