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