001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.util; 018 019/** 020 * Utility methods for simple pattern matching, in particular for 021 * Spring's typical "xxx*", "*xxx" and "*xxx*" pattern styles. 022 * 023 * @author Juergen Hoeller 024 * @since 2.0 025 */ 026public abstract class PatternMatchUtils { 027 028 /** 029 * Match a String against the given pattern, supporting the following simple 030 * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an 031 * arbitrary number of pattern parts), as well as direct equality. 032 * @param pattern the pattern to match against 033 * @param str the String to match 034 * @return whether the String matches the given pattern 035 */ 036 public static boolean simpleMatch(String pattern, String str) { 037 if (pattern == null || str == null) { 038 return false; 039 } 040 041 int firstIndex = pattern.indexOf('*'); 042 if (firstIndex == -1) { 043 return pattern.equals(str); 044 } 045 046 if (firstIndex == 0) { 047 if (pattern.length() == 1) { 048 return true; 049 } 050 int nextIndex = pattern.indexOf('*', 1); 051 if (nextIndex == -1) { 052 return str.endsWith(pattern.substring(1)); 053 } 054 String part = pattern.substring(1, nextIndex); 055 if (part.isEmpty()) { 056 return simpleMatch(pattern.substring(nextIndex), str); 057 } 058 int partIndex = str.indexOf(part); 059 while (partIndex != -1) { 060 if (simpleMatch(pattern.substring(nextIndex), str.substring(partIndex + part.length()))) { 061 return true; 062 } 063 partIndex = str.indexOf(part, partIndex + 1); 064 } 065 return false; 066 } 067 068 return (str.length() >= firstIndex && 069 pattern.substring(0, firstIndex).equals(str.substring(0, firstIndex)) && 070 simpleMatch(pattern.substring(firstIndex), str.substring(firstIndex))); 071 } 072 073 /** 074 * Match a String against the given patterns, supporting the following simple 075 * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an 076 * arbitrary number of pattern parts), as well as direct equality. 077 * @param patterns the patterns to match against 078 * @param str the String to match 079 * @return whether the String matches any of the given patterns 080 */ 081 public static boolean simpleMatch(String[] patterns, String str) { 082 if (patterns != null) { 083 for (String pattern : patterns) { 084 if (simpleMatch(pattern, str)) { 085 return true; 086 } 087 } 088 } 089 return false; 090 } 091 092}