/*
* RHQ Management Platform
* Copyright (C) 2005-2009 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.augeas.util;
import java.io.File;
import java.io.FileFilter;
import java.util.regex.Pattern;
/**
* A filter implementing a glob pattern match.
*
* @author Lukas Krejci
*/
public class GlobFilter implements FileFilter {
private String globPattern;
private Pattern regexPattern;
public static final char[] WILDCARD_CHARS;
static {
if (File.separatorChar == '\\') {
WILDCARD_CHARS = new char[] { '*', '?' };
} else {
WILDCARD_CHARS = new char[] { '*', '?', '[', ']' };
}
}
public GlobFilter(String globPattern) {
if (globPattern == null) {
throw new IllegalArgumentException("The glob pattern cannot be null.");
}
this.globPattern = globPattern;
this.regexPattern = convert(globPattern);
}
public String getGlobPattern() {
return globPattern;
}
/* (non-Javadoc)
* @see java.io.FileFilter#accept(java.io.File)
*/
public boolean accept(File pathname) {
return regexPattern.matcher(pathname.getAbsolutePath()).matches();
}
private static Pattern convert(String globPattern) {
StringBuilder regexPattern = new StringBuilder("^");
int i = 0;
//path starts require special handling only on UNIX platforms
boolean pathStart = File.separatorChar != '\\';
boolean inRangeSpec = false;
while (i < globPattern.length()) {
switch (globPattern.charAt(i)) {
case '\\':
if (File.separatorChar == '\\') {
//we're on windows, \ is a separator
regexPattern.append("\\\\");
} else {
//anywhere else, \ is a escape sequence
if (i == globPattern.length() - 1) {
throw new IllegalArgumentException("Illegal glob pattern: " + globPattern);
}
regexPattern.append("\\").append(globPattern.charAt(i + 1));
i += 1; //just skip the next character
}
pathStart = false;
break;
case '*':
if (pathStart) {
//on UNIX platforms, the "/*" doesn't match
//the hidden files (i.e. the ones prefixed by dot
regexPattern.append("($|[^\\.].*)");
} else if (inRangeSpec) {
//* has no special meaning inside a range spec
regexPattern.append("\\*");
} else {
regexPattern.append(".*");
}
pathStart = false;
break;
case '?':
if (inRangeSpec) {
//? has no special meaning inside a range spec
regexPattern.append("\\?");
} else {
regexPattern.append(".");
}
pathStart = false;
break;
case '.':
regexPattern.append("\\.");
pathStart = false;
break;
case '/':
regexPattern.append("\\/");
if (File.separatorChar != '\\') {
pathStart = true;
}
break;
case '[':
regexPattern.append("[");
inRangeSpec = true;
break;
case ']':
regexPattern.append(']');
inRangeSpec = false;
break;
default:
regexPattern.append(globPattern.charAt(i));
pathStart = false;
break;
}
i++;
}
regexPattern.append("$");
return Pattern.compile(regexPattern.toString());
}
}