aQute.libg.glob.Glob Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.bndtools.templating.gitrepo Show documentation
Show all versions of org.bndtools.templating.gitrepo Show documentation
org.bndtools.templating.gitrepo
The newest version!
package aQute.libg.glob;
import java.io.File;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Glob {
enum State {
SIMPLE,
CURLIES,
BRACKETS,
QUOTED
}
public static final Glob ALL = new Glob("*");
public static final Glob NONE = new Glob("\uFFFF\uFFFB\uFFFE\uFFFD");
private final String glob;
private final Pattern pattern;
public Glob(String globString) {
this(globString, 0);
}
public Glob(String globString, int flags) {
this(globString, toPattern(globString, flags));
}
protected Glob(String globString, Pattern pattern) {
this.glob = globString;
this.pattern = pattern;
}
public String glob() {
return glob;
}
public Pattern pattern() {
return pattern;
}
public Matcher matcher(CharSequence input) {
return pattern.matcher(input);
}
@Override
public String toString() {
return glob;
}
public static Pattern toPattern(String line) {
return toPattern(line, 0);
}
public static Pattern toPattern(String line, int flags) {
line = line.trim();
int strLen = line.length();
StringBuilder sb = new StringBuilder(strLen << 2);
int curlyLevel = 0;
State state = State.SIMPLE;
char previousChar = 0;
for (int i = 0; i < strLen; i++) {
char currentChar = line.charAt(i);
switch (currentChar) {
case '*' :
if ((state == State.SIMPLE || state == State.CURLIES) && !isEnd(previousChar)) {
sb.append('.');
}
sb.append(currentChar);
break;
case '?' :
if ((state == State.SIMPLE || state == State.CURLIES) && !isStart(previousChar)
&& !isEnd(previousChar)) {
sb.append('.');
} else {
sb.append(currentChar);
}
break;
case '+' :
if ((state == State.SIMPLE || state == State.CURLIES) && !isEnd(previousChar)) {
sb.append('\\');
}
sb.append(currentChar);
break;
case '\\' :
sb.append(currentChar);
if (i + 1 < strLen) {
char nextChar = line.charAt(++i);
if (state == State.SIMPLE && nextChar == 'Q') {
state = State.QUOTED;
} else if (state == State.QUOTED && nextChar == 'E') {
state = State.SIMPLE;
}
sb.append(nextChar);
}
break;
case '[' :
if (state == State.SIMPLE) {
state = State.BRACKETS;
}
sb.append(currentChar);
break;
case ']' :
if (state == State.BRACKETS) {
state = State.SIMPLE;
}
sb.append(currentChar);
break;
case '{' :
if ((state == State.SIMPLE || state == State.CURLIES) && !isEnd(previousChar)) {
state = State.CURLIES;
sb.append("(?:");
curlyLevel++;
} else {
sb.append(currentChar);
}
break;
case '}' :
if (state == State.CURLIES && curlyLevel > 0) {
sb.append(')');
currentChar = ')';
curlyLevel--;
if (curlyLevel == 0)
state = State.SIMPLE;
} else {
sb.append(currentChar);
}
break;
case ',' :
if (state == State.CURLIES) {
sb.append('|');
} else {
sb.append(currentChar);
}
break;
case '^' :
case '.' :
case '$' :
case '@' :
case '%' :
if (state == State.SIMPLE || state == State.CURLIES)
sb.append('\\');
// FALL THROUGH
default :
sb.append(currentChar);
break;
}
previousChar = currentChar;
}
return Pattern.compile(sb.toString(), flags);
}
private static boolean isStart(char c) {
return c == '(';
}
private static boolean isEnd(char c) {
return c == ')' || c == ']';
}
public void select(Collection> objects) {
for (Iterator> i = objects.iterator(); i.hasNext();) {
String s = i.next()
.toString();
if (!matches(s))
i.remove();
}
}
public void select(List> objects) {
this.select((Collection>) objects);
}
/**
* Get a list of files that match the glob expression
*
* @param root the directory to get the files from
* @param recursive to traverse the dirs recursive
* @return file list
*/
public List getFiles(File root, boolean recursive, boolean usePath) {
List result = new ArrayList<>();
getFiles(root, result, recursive, usePath);
return result;
}
public void getFiles(File root, List result, boolean recursive, boolean usePath) {
if ((root != null) && root.isDirectory()) {
File[] files = root.listFiles();
if (files != null) {
Collator collator = Collator.getInstance(Locale.ROOT);
collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
collator.setStrength(Collator.IDENTICAL); // case-sensitive
Arrays.sort(files, Comparator.comparing(File::getName, collator::compare));
for (File sub : files) {
if (sub.isFile()) {
String s = usePath ? sub.getAbsolutePath() : sub.getName();
if (matcher(s).matches()) {
result.add(sub);
}
} else if (recursive && sub.isDirectory()) {
getFiles(sub, result, recursive, usePath);
}
}
}
}
}
public static boolean in(Glob[] globs, String key) {
for (Glob g : globs) {
if (g.matcher(key)
.matches())
return true;
}
return false;
}
public static boolean in(Collection extends Glob> globs, String key) {
for (Glob g : globs) {
if (g.matcher(key)
.matches())
return true;
}
return false;
}
public int finds(CharSequence s) {
Matcher matcher = matcher(s);
if (matcher.find()) {
return matcher.start();
}
return -1;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((glob == null) ? 0 : glob.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Glob other = (Glob) obj;
return Objects.equals(glob, other.glob);
}
public boolean matches(String s) {
return matches((CharSequence) s);
}
public boolean matches(CharSequence s) {
return matcher(s).matches();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy