KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > xam > ui > search > WildcardStringMatcher


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.xam.ui.search;
21
22 /**
23  * A string matcher that supports a small set of wildcards (e.g. * and ?).
24  * See the documentation for the <code>match()</code> method for details.
25  *
26  * @see #match(String, String)
27  * @author Nathan Fiedler
28  */

29 public class WildcardStringMatcher {
30
31     /**
32      * Creates a new instance of WildcardStringMatcher.
33      */

34     private WildcardStringMatcher() {
35     }
36
37     /**
38      * Determines if the given query string contains wildcards that this
39      * string matcher understands.
40      *
41      * @param query query string, which may or may not contain wildcards.
42      * @return true if query has recognized wildcards, false otherwise.
43      */

44     public static boolean containsWildcards(String JavaDoc query) {
45         return query.contains("*") || query.contains("?");
46     }
47
48     /**
49      * Scans the given text for a pattern, indicating if the text matched
50      * the pattern or not. The pattern wildcards are as follows:
51      *
52      * <ul>
53      * <li>? matches any single character.</li>
54      * <li>* matches zero or more characters.</li>
55      * </ul>
56      *
57      * <p>The text must match the entire pattern, or it is not considered
58      * a match. That is, if "floss*" is the pattern, then it will only
59      * match text that begins with "floss", while "floss?" will match
60      * "flossy" but not "floss" since it expects an additional character.</p>
61      *
62      * <p>Note that * is greedy, such that "*foo" will match "foofoofoo".</p>
63      *
64      * @param text the text in which to look for the pattern.
65      * @param query the pattern to match, may contain wildcards.
66      * @return true if matches, false otherwise.
67      */

68     public static boolean match(String JavaDoc text, String JavaDoc query) {
69         int ti;
70         int qi;
71         int tl = text.length();
72         int ql = query.length();
73         boolean star = false;
74
75         for (ti = 0, qi = 0; ti < tl; ti++, qi++) {
76             // This line allows this algorithm to be greedy, such that
77
// "*foo" will match "foofoofoo", and "*a" matches "aaa".
78
char qc = qi < ql ? query.charAt(qi) : 0;
79             switch (qc) {
80                 case '?':
81                     // We allow question marks to match anything.
82
break;
83                 case '*':
84                     star = true;
85                     // Skip over consecutive asterisks.
86
do {
87                         qi++;
88                     } while (qi < ql && query.charAt(qi) == '*');
89                     if (qi == ql) {
90                         // Query ended with an asterisk, that makes a match.
91
return true;
92                     }
93                     // Simulate recursion on both substrings.
94
text = text.substring(ti);
95                     query = query.substring(qi);
96                     tl = text.length();
97                     ql = query.length();
98                     ti = -1;
99                     qi = -1;
100                     break;
101                 default:
102                     char tc = text.charAt(ti);
103                     if (tc != qc) {
104                         if (!star) {
105                             // No asterisk and not a match, exit immediately.
106
return false;
107                         }
108                         // Simulate recursion on the text substring.
109
text = text.substring(1);
110                         tl--;
111                         ti = -1;
112                         qi = -1;
113                     }
114                     break;
115             }
116         }
117         // Consume any trailing asterisks in query.
118
while (qi < ql && query.charAt(qi) == '*') {
119             qi++;
120         }
121         // It is a match only if we reached the ends of both strings.
122
return ti >= tl && qi >= ql;
123     }
124 }
125
Popular Tags