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 org.apache.regexp.RE;
24  import org.apache.log4j.Logger;
25  
26  /***
27   * TODO Add docs
28   * Created on 04.12.2004
29   *
30   * Contributing Author(s):
31   *
32   *   Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital implementation)
33   *   Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital implementation)
34   *
35   * @author vlads
36   * @version $Revision: 1.2 $ ($Author: vlads $) $Date: 2004/12/05 07:36:08 $
37   */
38  public class MatchStringFilter extends BasicFilter {
39  	
40  	protected static final Logger log = Logger.getLogger(MatchStringFilter.class);
41  	
42  	String pattern;
43  	
44  	private RE rePattern;
45  	
46  	boolean negative;
47  	
48  	private static final boolean useRegexp = true;
49  	
50  	protected MatchStringFilter() {
51  	}
52  	
53  	public MatchStringFilter(String pattern) {
54  		setPattern(pattern);
55  	}
56  	
57  	public void debug() {
58  		if (negative) {
59  			log.debug("pattern:!" + pattern);
60  		} else {
61  			log.debug("pattern:" + pattern);
62  		}
63  	}
64  	
65  	public boolean setPattern(String pattern) {
66          if ((pattern == null) || (pattern.length() == 0)) {
67          	return false;
68          }
69  		if (pattern.startsWith("!")) {
70  			this.pattern = pattern.substring(1);
71  			negative = true;
72  		} else {
73  			this.pattern = pattern;
74  			negative = false;
75  		}
76  		if (useRegexp) {
77  			this.rePattern = getGlobPattern(this.pattern);
78  		}
79  		return true;
80  	}
81  	
82  	public int matchState(Object obj) {
83  		int rc;
84  		if (this.pattern == null) {
85  			return MATCH_NO;
86  		}
87  		if (useRegexp) {
88  			if (BasicFilter.accept(this.rePattern, (String)obj)) {
89  				rc = MATCH_YES;
90  			} else {
91  				rc = MATCH_NO;
92  			}
93  		} else {
94  		 	rc = matchSimple(this.pattern, (String)obj);
95  		}
96  		if (negative) {
97  			rc = notMatch(rc);
98  		}
99  		
100 		if (debug) {
101 			String s= "";
102 			if (negative) {
103 				s = "NOT ";
104 			}
105 			log.debug(s + this.pattern + "->" + match2String(rc) 
106 				+ " testing[" + obj + "]");
107 		}
108 		
109 		return rc;
110 	}
111 	
112 	public boolean match(String text) {
113 		return isMatch(matchState(text));
114 	}
115 	
116 	public static int matchSimple(String pattern, String text) {
117 		if (text == null) {
118 			return MATCH_NO;
119 		}
120 		// add sentinel so don't need to worry about *'s at end of pattern
121 		text += '\0';
122 		pattern += '\0';
123 
124 		int N = pattern.length();
125 
126 		boolean[] states = new boolean[N + 1];
127 		boolean[] old = new boolean[N + 1];
128 		old[0] = true;
129 
130 		boolean wildcard = false;
131 
132 		for (int i = 0; i < text.length(); i++) {
133 			char c = text.charAt(i);
134 			states = new boolean[N + 1]; // initialized to false
135 			for (int j = 0; j < N; j++) {
136 				char p = pattern.charAt(j);
137 
138 				// hack to handle *'s that match 0 characters
139 				if (old[j] && (p == '*')) {
140 					old[j + 1] = true;
141 					wildcard = true;
142 				}
143 
144 				if (old[j] && (p == c))
145 					states[j + 1] = true;
146 
147 				if (old[j] && (p == '?')) {
148 					states[j + 1] = true;
149 					wildcard = true;
150 				}
151 
152 				if (old[j] && (p == '*')) {
153 					states[j] = true;
154 					wildcard = true;
155 				}
156 
157 				if (old[j] && (p == '*')) {
158 					states[j + 1] = true;
159 					wildcard = true;
160 				}
161 			}
162 			old = states;
163 		}
164 
165 		if (!states[N]) {
166 			return MATCH_NO;
167 		} else if (wildcard) {
168 			return MATCH_YES;
169 		} else {
170 			return MATCH_EXACT;
171 		}
172 	}
173 
174 }