Path: blob/master/src/java.base/share/classes/sun/nio/fs/Globs.java
41159 views
/*1* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.fs;2627import java.util.regex.PatternSyntaxException;2829public class Globs {30private Globs() { }3132private static final String regexMetaChars = ".^$+{[]|()";33private static final String globMetaChars = "\\*?[{";3435private static boolean isRegexMeta(char c) {36return regexMetaChars.indexOf(c) != -1;37}3839private static boolean isGlobMeta(char c) {40return globMetaChars.indexOf(c) != -1;41}42private static char EOL = 0; //TBD4344private static char next(String glob, int i) {45if (i < glob.length()) {46return glob.charAt(i);47}48return EOL;49}5051/**52* Creates a regex pattern from the given glob expression.53*54* @throws PatternSyntaxException55*/56private static String toRegexPattern(String globPattern, boolean isDos) {57boolean inGroup = false;58StringBuilder regex = new StringBuilder("^");5960int i = 0;61while (i < globPattern.length()) {62char c = globPattern.charAt(i++);63switch (c) {64case '\\':65// escape special characters66if (i == globPattern.length()) {67throw new PatternSyntaxException("No character to escape",68globPattern, i - 1);69}70char next = globPattern.charAt(i++);71if (isGlobMeta(next) || isRegexMeta(next)) {72regex.append('\\');73}74regex.append(next);75break;76case '/':77if (isDos) {78regex.append("\\\\");79} else {80regex.append(c);81}82break;83case '[':84// don't match name separator in class85if (isDos) {86regex.append("[[^\\\\]&&[");87} else {88regex.append("[[^/]&&[");89}90if (next(globPattern, i) == '^') {91// escape the regex negation char if it appears92regex.append("\\^");93i++;94} else {95// negation96if (next(globPattern, i) == '!') {97regex.append('^');98i++;99}100// hyphen allowed at start101if (next(globPattern, i) == '-') {102regex.append('-');103i++;104}105}106boolean hasRangeStart = false;107char last = 0;108while (i < globPattern.length()) {109c = globPattern.charAt(i++);110if (c == ']') {111break;112}113if (c == '/' || (isDos && c == '\\')) {114throw new PatternSyntaxException("Explicit 'name separator' in class",115globPattern, i - 1);116}117// TBD: how to specify ']' in a class?118if (c == '\\' || c == '[' ||119c == '&' && next(globPattern, i) == '&') {120// escape '\', '[' or "&&" for regex class121regex.append('\\');122}123regex.append(c);124125if (c == '-') {126if (!hasRangeStart) {127throw new PatternSyntaxException("Invalid range",128globPattern, i - 1);129}130if ((c = next(globPattern, i++)) == EOL || c == ']') {131break;132}133if (c < last) {134throw new PatternSyntaxException("Invalid range",135globPattern, i - 3);136}137regex.append(c);138hasRangeStart = false;139} else {140hasRangeStart = true;141last = c;142}143}144if (c != ']') {145throw new PatternSyntaxException("Missing ']", globPattern, i - 1);146}147regex.append("]]");148break;149case '{':150if (inGroup) {151throw new PatternSyntaxException("Cannot nest groups",152globPattern, i - 1);153}154regex.append("(?:(?:");155inGroup = true;156break;157case '}':158if (inGroup) {159regex.append("))");160inGroup = false;161} else {162regex.append('}');163}164break;165case ',':166if (inGroup) {167regex.append(")|(?:");168} else {169regex.append(',');170}171break;172case '*':173if (next(globPattern, i) == '*') {174// crosses directory boundaries175regex.append(".*");176i++;177} else {178// within directory boundary179if (isDos) {180regex.append("[^\\\\]*");181} else {182regex.append("[^/]*");183}184}185break;186case '?':187if (isDos) {188regex.append("[^\\\\]");189} else {190regex.append("[^/]");191}192break;193194default:195if (isRegexMeta(c)) {196regex.append('\\');197}198regex.append(c);199}200}201202if (inGroup) {203throw new PatternSyntaxException("Missing '}", globPattern, i - 1);204}205206return regex.append('$').toString();207}208209static String toUnixRegexPattern(String globPattern) {210return toRegexPattern(globPattern, false);211}212213static String toWindowsRegexPattern(String globPattern) {214return toRegexPattern(globPattern, true);215}216}217218219