217 lines · 8.0 KB · Java
RawDownload
/* * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.nio.fs; import java.util.regex.PatternSyntaxException; public class Globs {    private Globs() { }     private static final String regexMetaChars = ".^$+{[]|()";    private static final String globMetaChars = "\\*?[{";     private static boolean isRegexMeta(char c) {        return regexMetaChars.indexOf(c) != -1;    }     private static boolean isGlobMeta(char c) {        return globMetaChars.indexOf(c) != -1;    }    private static char EOL = 0;  //TBD     private static char next(String glob, int i) {        if (i < glob.length()) {            return glob.charAt(i);        }        return EOL;    }     /**     * Creates a regex pattern from the given glob expression.     *     * @throws  PatternSyntaxException     */    private static String toRegexPattern(String globPattern, boolean isDos) {        boolean inGroup = false;        StringBuilder regex = new StringBuilder("^");         int i = 0;        while (i < globPattern.length()) {            char c = globPattern.charAt(i++);            switch (c) {                case '\\':                    // escape special characters                    if (i == globPattern.length()) {                        throw new PatternSyntaxException("No character to escape",                                globPattern, i - 1);                    }                    char next = globPattern.charAt(i++);                    if (isGlobMeta(next) || isRegexMeta(next)) {                        regex.append('\\');                    }                    regex.append(next);                    break;                case '/':                    if (isDos) {                        regex.append("\\\\");                    } else {                        regex.append(c);                    }                    break;                case '[':                    // don't match name separator in class                    if (isDos) {                        regex.append("[[^\\\\]&&[");                    } else {                        regex.append("[[^/]&&[");                    }                    if (next(globPattern, i) == '^') {                        // escape the regex negation char if it appears                        regex.append("\\^");                        i++;                    } else {                        // negation                        if (next(globPattern, i) == '!') {                            regex.append('^');                            i++;                        }                        // hyphen allowed at start                        if (next(globPattern, i) == '-') {                            regex.append('-');                            i++;                        }                    }                    boolean hasRangeStart = false;                    char last = 0;                    while (i < globPattern.length()) {                        c = globPattern.charAt(i++);                        if (c == ']') {                            break;                        }                        if (c == '/' || (isDos && c == '\\')) {                            throw new PatternSyntaxException("Explicit 'name separator' in class",                                    globPattern, i - 1);                        }                        // TBD: how to specify ']' in a class?                        if (c == '\\' || c == '[' ||                                c == '&' && next(globPattern, i) == '&') {                            // escape '\', '[' or "&&" for regex class                            regex.append('\\');                        }                        regex.append(c);                         if (c == '-') {                            if (!hasRangeStart) {                                throw new PatternSyntaxException("Invalid range",                                        globPattern, i - 1);                            }                            if ((c = next(globPattern, i++)) == EOL || c == ']') {                                break;                            }                            if (c < last) {                                throw new PatternSyntaxException("Invalid range",                                        globPattern, i - 3);                            }                            regex.append(c);                            hasRangeStart = false;                        } else {                            hasRangeStart = true;                            last = c;                        }                    }                    if (c != ']') {                        throw new PatternSyntaxException("Missing ']", globPattern, i - 1);                    }                    regex.append("]]");                    break;                case '{':                    if (inGroup) {                        throw new PatternSyntaxException("Cannot nest groups",                                globPattern, i - 1);                    }                    regex.append("(?:(?:");                    inGroup = true;                    break;                case '}':                    if (inGroup) {                        regex.append("))");                        inGroup = false;                    } else {                        regex.append('}');                    }                    break;                case ',':                    if (inGroup) {                        regex.append(")|(?:");                    } else {                        regex.append(',');                    }                    break;                case '*':                    if (next(globPattern, i) == '*') {                        // crosses directory boundaries                        regex.append(".*");                        i++;                    } else {                        // within directory boundary                        if (isDos) {                            regex.append("[^\\\\]*");                        } else {                            regex.append("[^/]*");                        }                    }                    break;                case '?':                   if (isDos) {                       regex.append("[^\\\\]");                   } else {                       regex.append("[^/]");                   }                   break;                 default:                    if (isRegexMeta(c)) {                        regex.append('\\');                    }                    regex.append(c);            }        }         if (inGroup) {            throw new PatternSyntaxException("Missing '}", globPattern, i - 1);        }         return regex.append('$').toString();    }     static String toUnixRegexPattern(String globPattern) {        return toRegexPattern(globPattern, false);    }     static String toWindowsRegexPattern(String globPattern) {        return toRegexPattern(globPattern, true);    }}