liquibase-core/src/main/java/liquibase/util/file/FilenameUtils.java
public static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity) {
        if ((filename == null) && (wildcardMatcher == null)) {
            return true;
        }
        if ((filename == null) || (wildcardMatcher == null)) {
            return false;
        }
        if (caseSensitivity == null) {
            caseSensitivity = IOCase.SENSITIVE;
        }
        filename = caseSensitivity.convertCase(filename);
        wildcardMatcher = caseSensitivity.convertCase(wildcardMatcher);
        String[] wcs = splitOnTokens(wildcardMatcher);
        boolean anyChars = false;
        int textIdx = 0;
        int wcsIdx = 0;
        Stack backtrack = new Stack();

        // loop around a backtrack stack, to handle complex * matching
        do {
            if (!backtrack.isEmpty()) {
                int[] array = (int[]) backtrack.pop();
                wcsIdx = array[0];
                textIdx = array[1];
                anyChars = true;
            }

            // loop whilst tokens and text left to process
            label:
            while (wcsIdx < wcs.length) {
        
                switch (wcs[wcsIdx]) {
                    case "?":
                        // ? so move to next text char
                        textIdx++;
                        anyChars = false;
                
                        break;
                    case "*":
                        // set any chars status
                        anyChars = true;
                        if (wcsIdx == (wcs.length - 1)) {
                            textIdx = filename.length();
                        }
                
                        break;
                    default:
                        // matching text token
                        if (anyChars) {
                            // any chars then try to locate text token
                            textIdx = filename.indexOf(wcs[wcsIdx], textIdx);
                            if (textIdx == -1) {
                                // token not found
                                break label;
                            }
                            int repeat = filename.indexOf(wcs[wcsIdx], textIdx + 1);
                            if (repeat >= 0) {
                                backtrack.push(new int[]{wcsIdx, repeat});
                            }
                        } else {
                            // matching from current position
                            if (!filename.startsWith(wcs[wcsIdx], textIdx)) {
                                // couldnt match token
                                break label;
                            }
                        }
                
                        // matched text token, move text index to end of matched token
                        textIdx += wcs[wcsIdx].length();
                        anyChars = false;
                        break;
                }
        
                wcsIdx++;
            }

            // full match
            if ((wcsIdx == wcs.length) && (textIdx == filename.length())) {
                return true;
            }

        } while (!backtrack.isEmpty());

        return false;
    }
public static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity) {
        if ((filename == null) && (wildcardMatcher == null)) {
            return true;
        }
        if ((filename == null) || (wildcardMatcher == null)) {
            return false;
        }
        if (caseSensitivity == null) {
            caseSensitivity = IOCase.SENSITIVE;
        }
        filename = caseSensitivity.convertCase(filename);
        wildcardMatcher = caseSensitivity.convertCase(wildcardMatcher);
        String[] wcs = splitOnTokens(wildcardMatcher);
        boolean anyChars = false;
        int textIdx = 0;
        int wcsIdx = 0;
        Stack backtrack = new Stack();

        // loop around a backtrack stack, to handle complex * matching
        do {
            if (!backtrack.isEmpty()) {
                int[] array = (int[]) backtrack.pop();
                wcsIdx = array[0];
                textIdx = array[1];
                anyChars = true;
            }

            // loop whilst tokens and text left to process
            label:
            while (wcsIdx < wcs.length) {
        
                switch (wcs[wcsIdx]) {
                    case "?":
                        // ? so move to next text char
                        textIdx++;
                        anyChars = false;
                
                        break;
                    case "*":
                        // set any chars status
                        anyChars = true;
                        if (wcsIdx == (wcs.length - 1)) {
                            textIdx = filename.length();
                        }
                
                        break;
                    default:
                        // matching text token
                        if (anyChars) {
                            // any chars then try to locate text token
                            textIdx = filename.indexOf(wcs[wcsIdx], textIdx);
                            if (textIdx == -1) {
                                // token not found
                                break label;
                            }
                            int repeat = filename.indexOf(wcs[wcsIdx], textIdx + 1);
                            if (repeat >= 0) {
                                backtrack.push(new int[]{wcsIdx, repeat});
                            }
                        } else {
                            // matching from current position
                            if (!filename.startsWith(wcs[wcsIdx], textIdx)) {
                                // couldnt match token
                                break label;
                            }
                        }
                
                        // matched text token, move text index to end of matched token
                        textIdx += wcs[wcsIdx].length();
                        anyChars = false;
                        break;
                }
        
                wcsIdx++;
            }

            // full match
            if ((wcsIdx == wcs.length) && (textIdx == filename.length())) {
                return true;
            }

        } while (!backtrack.isEmpty());

        return false;
    }
public static boolean wildcardMatch ( String filename , String wildcardMatcher , IOCase caseSensitivity ) { if ( ( filename == null ) && ( wildcardMatcher == null ) ) { return true ; } if ( ( filename == null ) || ( wildcardMatcher == null ) ) { return false ; } if ( caseSensitivity == null ) { caseSensitivity = IOCase . SENSITIVE ; } filename = caseSensitivity . convertCase ( filename ) ; wildcardMatcher = caseSensitivity . convertCase ( wildcardMatcher ) ; String [ ] wcs = splitOnTokens ( wildcardMatcher ) ; boolean anyChars = false ; int textIdx = 0 ; int wcsIdx = 0 ; Stack backtrack = new Stack ( ) ; // loop around a backtrack stack, to handle complex * matching do { if ( ! backtrack . isEmpty ( ) ) { int [ ] array = ( int [ ] ) backtrack . pop ( ) ; wcsIdx = array [ 0 ] ; textIdx = array [ 1 ] ; anyChars = true ; } // loop whilst tokens and text left to process label : while ( wcsIdx < wcs . length ) { switch ( wcs [ wcsIdx ] ) { case "?" : // ? so move to next text char textIdx ++ ; anyChars = false ; break ; case "*" : // set any chars status anyChars = true ; if ( wcsIdx == ( wcs . length - 1 ) ) { textIdx = filename . length ( ) ; } break ; default : // matching text token if ( anyChars ) { // any chars then try to locate text token textIdx = filename . indexOf ( wcs [ wcsIdx ] , textIdx ) ; if ( textIdx == - 1 ) { // token not found break label ; } int repeat = filename . indexOf ( wcs [ wcsIdx ] , textIdx + 1 ) ; if ( repeat >= 0 ) { backtrack . push ( new int [ ] { wcsIdx , repeat } ) ; } } else { // matching from current position if ( ! filename . startsWith ( wcs [ wcsIdx ] , textIdx ) ) { // couldnt match token break label ; } } // matched text token, move text index to end of matched token textIdx += wcs [ wcsIdx ] . length ( ) ; anyChars = false ; break ; } wcsIdx ++ ; } // full match if ( ( wcsIdx == wcs . length ) && ( textIdx == filename . length ( ) ) ) { return true ; } } while ( ! backtrack . isEmpty ( ) ) ; return false ; }
Checks a filename to see if it matches the specified wildcard matcher
allowing control over case-sensitivity.
<p>
The wildcard matcher uses the characters '?' and '*' to represent a
single or multiple wildcard characters.

@param filename  the filename to match on
@param wildcardMatcher  the wildcard string to match against
@param caseSensitivity  what case sensitivity rule to use, null means case-sensitive
@return true if the filename matches the wilcard string
@since Commons IO 1.3
Checks a filename to see if it matches the specified wildcard matcher allowing control over case - sensitivity . <p > The wildcard matcher uses the characters ? and * to represent a single or multiple wildcard characters .