View Javadoc

1   /*
2    * Jour - java profiler and monitoring library
3    *
4    * Copyright (C) 2004 Jour team
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Library General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Library General Public License for more details.
15   *
16   * You should have received a copy of the GNU Library General Public
17   * License along with this library; if not, write to the
18   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19   * Boston, MA  02111-1307, USA.
20   */
21  package net.sf.jour.filter;
22  
23  import java.util.regex.Pattern;
24  
25  import net.sf.jour.log.Logger;
26  
27  /**
28   * TODO Add docs Created on 04.12.2004
29   * 
30   * Contributing Author(s):
31   * 
32   * Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital
33   * implementation) Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital
34   * implementation)
35   * 
36   * @author vlads
37   * @version $Revision: 47 $ ($Author: vlads $) $Date: 2006-11-19 16:52:09 -0500
38   *          (Sun, 19 Nov 2006) $
39   */
40  public class MatchStringFilter extends BasicFilter {
41  
42  	protected static final Logger log = Logger.getLogger();
43  
44  	String pattern;
45  
46  	private Pattern rePattern;
47  
48  	boolean negative;
49  
50  	private static final boolean useRegexp = true;
51  
52  	protected MatchStringFilter() {
53  	}
54  
55  	public MatchStringFilter(String pattern) {
56  		setPattern(pattern);
57  	}
58  
59  	public void debug() {
60  		if (negative) {
61  			log.debug("pattern:!" + pattern);
62  		} else {
63  			log.debug("pattern:" + pattern);
64  		}
65  	}
66  
67  	public boolean setPattern(String pattern) {
68  		if ((pattern == null) || (pattern.length() == 0)) {
69  			return false;
70  		}
71  		if (pattern.startsWith("!")) {
72  			this.pattern = pattern.substring(1);
73  			negative = true;
74  		} else {
75  			this.pattern = pattern;
76  			negative = false;
77  		}
78  		if (useRegexp) {
79  			this.rePattern = getGlobPattern(this.pattern);
80  		}
81  		return true;
82  	}
83  
84  	public int matchState(Object obj) {
85  		int rc;
86  		if (this.pattern == null) {
87  			return MATCH_NO;
88  		}
89  		if (useRegexp) {
90  			if (BasicFilter.accept(this.rePattern, (String) obj)) {
91  				rc = MATCH_YES;
92  			} else {
93  				rc = MATCH_NO;
94  			}
95  		} else {
96  			rc = matchSimple(this.pattern, (String) obj);
97  		}
98  		if (negative) {
99  			rc = notMatch(rc);
100 		}
101 
102 		if (debug) {
103 			String s = "";
104 			if (negative) {
105 				s = "NOT ";
106 			}
107 			log.debug(s + this.pattern + "->" + match2String(rc) + " testing[" + obj + "]");
108 		}
109 
110 		return rc;
111 	}
112 
113 	public boolean match(String text) {
114 		return isMatch(matchState(text));
115 	}
116 
117 	public static int matchSimple(String pattern, String text) {
118 		if (text == null) {
119 			return MATCH_NO;
120 		}
121 		// add sentinel so don't need to worry about *'s at end of pattern
122 		text += '\0';
123 		pattern += '\0';
124 
125 		int N = pattern.length();
126 
127 		boolean[] states = new boolean[N + 1];
128 		boolean[] old = new boolean[N + 1];
129 		old[0] = true;
130 
131 		boolean wildcard = false;
132 
133 		for (int i = 0; i < text.length(); i++) {
134 			char c = text.charAt(i);
135 			states = new boolean[N + 1]; // initialized to false
136 			for (int j = 0; j < N; j++) {
137 				char p = pattern.charAt(j);
138 
139 				// hack to handle *'s that match 0 characters
140 				if (old[j] && (p == '*')) {
141 					old[j + 1] = true;
142 					wildcard = true;
143 				}
144 
145 				if (old[j] && (p == c))
146 					states[j + 1] = true;
147 
148 				if (old[j] && (p == '?')) {
149 					states[j + 1] = true;
150 					wildcard = true;
151 				}
152 
153 				if (old[j] && (p == '*')) {
154 					states[j] = true;
155 					wildcard = true;
156 				}
157 
158 				if (old[j] && (p == '*')) {
159 					states[j + 1] = true;
160 					wildcard = true;
161 				}
162 			}
163 			old = states;
164 		}
165 
166 		if (!states[N]) {
167 			return MATCH_NO;
168 		} else if (wildcard) {
169 			return MATCH_YES;
170 		} else {
171 			return MATCH_EXACT;
172 		}
173 	}
174 
175 }