001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.tools.file;
031:
032: import java.io.*;
033:
034: /**
035: * Handles wildcards for filename matching.
036: */
037: public class WildcardMatch {
038: private boolean ignoreCase = true;
039:
040: private boolean matchSeparators = true;
041:
042: /**
043: *
044: */
045: public WildcardMatch() {
046: super ();
047: }
048:
049: /**
050: * Insert the method's description here. Creation date: (12.11.00 20:31:00)
051: *
052: * @param newIgnoreCase
053: * boolean
054: */
055: public void setIgnoreCase(boolean newIgnoreCase) {
056: ignoreCase = newIgnoreCase;
057: }
058:
059: /**
060: * Insert the method's description here. Creation date: (12.11.00 20:31:00)
061: *
062: * @return boolean
063: */
064: public boolean isIgnoreCase() {
065: return ignoreCase;
066: }
067:
068: /**
069: * Insert the method's description here. Creation date: (12.11.00 21:17:35)
070: *
071: * @param newMatchSeparators
072: * boolean
073: */
074: public void setMatchSeparators(boolean newMatchSeparators) {
075: matchSeparators = newMatchSeparators;
076: }
077:
078: /**
079: * Insert the method's description here. Creation date: (12.11.00 21:17:35)
080: *
081: * @return boolean
082: */
083: public boolean isMatchSeparators() {
084: return matchSeparators;
085: }
086:
087: /**
088: * Match STRING against the filename pattern PATTERN
089: *
090: * <p> \
091: * </p>
092: *
093: * @param pattern
094: * A string using wildcards ( and ?)
095: * @param string
096: * The string to check for wildcards.
097: *
098: * @return true if match
099: */
100: public boolean match(final String pattern, final String string) {
101: // TODO lot of optimizations
102: // be sure test still runs
103: char c;
104: int len = pattern.length();
105: int n = 0;
106: for (int p = 0; p < len; p++) {
107: c = adjustCase(pattern.charAt(p));
108: switch (c) {
109: case '?':
110: if (string.length() == n) {
111: return false;
112: }
113: if (!matchSeparators
114: && (string.charAt(n) == File.separatorChar)) {
115: return false;
116: }
117: break;
118: case '*':
119: if (++p == pattern.length()) {
120: for (; string.length() > n; ++n) {
121: if ((string.charAt(n) == File.separatorChar)
122: && !matchSeparators) {
123: return false;
124: }
125: }
126: return true;
127: } else {
128: for (; string.length() >= n; ++n) {
129: if (match(pattern.substring(p), string
130: .substring(n))) {
131: return true;
132: }
133: if ((n == string.length())
134: || ((string.charAt(n) == File.separatorChar) && !matchSeparators)) {
135: return false;
136: }
137: }
138: }
139: return false;
140: default:
141: if (string.length() == n) {
142: return false;
143: }
144: if (c != adjustCase(string.charAt(n))) {
145: return false;
146: }
147: }
148: ++n;
149: }
150: if (string.length() == n) {
151: return true;
152: }
153: return false;
154: }
155:
156: // protected methods
157: /**
158: * If flags has its FNM_CASEFOLD bit set, then returns the lowercase of c;
159: * otherwise returns c.
160: *
161: * @param c
162: * A character to fold.
163: *
164: * @return A `folded' character.
165: */
166: protected char adjustCase(char c) {
167: return ignoreCase ? Character.toLowerCase(c) : c;
168: }
169: }
|