/* * 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()); } }