ngmf.util.FilenameUtils Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ngmf.util;
import java.io.File;
import java.util.ArrayList;
import java.util.Stack;
public class FilenameUtils {
/**
* The extension separator character.
*/
public static final char EXTENSION_SEPARATOR = '.';
/**
* The extension separator String.
*/
public static final String EXTENSION_SEPARATOR_STR = (new Character(EXTENSION_SEPARATOR)).toString();
/**
* The Unix separator character.
*/
private static final char UNIX_SEPARATOR = '/';
/**
* The Windows separator character.
*/
private static final char WINDOWS_SEPARATOR = '\\';
/**
* The system separator character.
*/
private static final char SYSTEM_SEPARATOR = File.separatorChar;
/**
* The separator character that is the opposite of the system separator.
*/
private static final char OTHER_SEPARATOR;
static {
if (isSystemWindows()) {
OTHER_SEPARATOR = UNIX_SEPARATOR;
} else {
OTHER_SEPARATOR = WINDOWS_SEPARATOR;
}
}
/**
* Instances should NOT be constructed in standard programming.
*/
static boolean isSystemWindows() {
return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR;
}
/**
* Checks a filename to see if it matches the specified wildcard matcher
* allowing control over case-sensitivity.
*
* 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
*/
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.size() > 0) {
int[] array = (int[]) backtrack.pop();
wcsIdx = array[0];
textIdx = array[1];
anyChars = true;
}
// loop whilst tokens and text left to process
while (wcsIdx < wcs.length) {
if (wcs[wcsIdx].equals("?")) {
// ? so move to next text char
textIdx++;
anyChars = false;
} else if (wcs[wcsIdx].equals("*")) {
// set any chars status
anyChars = true;
if (wcsIdx == wcs.length - 1) {
textIdx = filename.length();
}
} else {
// 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;
}
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;
}
}
// matched text token, move text index to end of matched token
textIdx += wcs[wcsIdx].length();
anyChars = false;
}
wcsIdx++;
}
// full match
if (wcsIdx == wcs.length && textIdx == filename.length()) {
return true;
}
} while (backtrack.size() > 0);
return false;
}
/**
* Splits a string into a number of tokens.
*
* @param text the text to split
* @return the tokens, never null
*/
static String[] splitOnTokens(String text) {
// used by wildcardMatch
// package level so a unit test may run on this
if (text.indexOf("?") == -1 && text.indexOf("*") == -1) {
return new String[] { text };
}
char[] array = text.toCharArray();
ArrayList list = new ArrayList();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < array.length; i++) {
if (array[i] == '?' || array[i] == '*') {
if (buffer.length() != 0) {
list.add(buffer.toString());
buffer.setLength(0);
}
if (array[i] == '?') {
list.add("?");
} else if (list.size() == 0 ||
(i > 0 && list.get(list.size() - 1).equals("*") == false)) {
list.add("*");
}
} else {
buffer.append(array[i]);
}
}
if (buffer.length() != 0) {
list.add(buffer.toString());
}
return (String[]) list.toArray( new String[ list.size() ] );
}
}