Changeset 5156
- Timestamp:
- 2003-08-18T13:58:40+12:00 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/gui/metaaudit/Autofilter.java
r4366 r5156 6 6 * University of Waikato, New Zealand. 7 7 * 8 * <BR><BR>9 *10 8 * Author: John Thompson, Greenstone Digital Library, University of Waikato 11 9 * 12 * <BR><BR>13 *14 10 * Copyright (C) 1999 New Zealand Digital Library Project 15 *16 * <BR><BR>17 11 * 18 12 * This program is free software; you can redistribute it and/or modify … … 21 15 * (at your option) any later version. 22 16 * 23 * <BR><BR>24 *25 17 * This program is distributed in the hope that it will be useful, 26 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 20 * GNU General Public License for more details. 29 *30 * <BR><BR>31 21 * 32 22 * You should have received a copy of the GNU General Public License … … 35 25 *######################################################################## 36 26 */ 37 38 39 40 41 42 43 /* GPL_HEADER */44 27 package org.greenstone.gatherer.gui.metaaudit; 45 28 /************************************************************************************** … … 50 33 * Written: /05/02 51 34 * Revised: 22/08/02 Revamped, Optimized and Commented. 35 * 13-08-03 Extended matching functionality to correctly handle the wildcard character 52 36 **************************************************************************************/ 53 37 54 38 import java.util.ArrayList; 39 import org.greenstone.gatherer.util.StaticStrings; 55 40 /** An Autofilter object stores the filters set on a single column, and provides a method for determining if a certain value passes the filter. 56 41 * @author John Thompson … … 58 43 */ 59 44 public class Autofilter { 45 46 static public void main(String[] args) { 47 if(args.length != 2) { 48 System.err.println("Usage: java Autofilter <string> <pattern>"); 49 } 50 else { 51 switch(compareToPattern(args[0], args[1])) { 52 case LESS_THAN: 53 System.err.print(args[0] + " is less than"); 54 break; 55 case GREATER_THAN: 56 System.err.print(args[0] + " is greater than"); 57 break; 58 case EQUAL: 59 System.err.print(args[0] + " is equal to"); 60 break; 61 default: 62 System.err.print(args[0] + " is something to"); 63 } 64 System.err.println(" " + args[1]); 65 } 66 } 67 68 /** A String comparison which also recognises the WildCard character. The basic idea is that '*' matches zero or more of any characters, and if we limited patterns to be like "a*" then as soon as we hit the star we could return a match. The problem is that we want patterns like "b*y" which would match "boy" but not "bee" nor "bus" (but should return less than or greater than for each of these respectively). Thus our testing has to become non-deterministic so the matches are conducted like so: 69 * Given p = [ b * y ] 70 * Test s = [ b e e ] Result: p0=s0,{(p2>s1=>ERROR),(p1=s1,{(p1>s2=>ERROR),(p2>s2=>LESS_THAN)})} => LESS_THAN 71 * Test s = [ b o y ] Result: p0=s0,{(p2>s1=>ERROR),(p1=s1,{(p1>s2=>ERROR),(p2=s2=>EQUAL)})} => EQUAL 72 * Test s = [ b u s ] Result: p0=s0,{(p2>s1=>ERROR),(p1=s1,{(p1>s2=>ERROR),(p2<s2=>GREATER_THAN)})} => GREATER_THAN 73 * where the two () phrases within a {} represent two different 'threads' of processing. Errors are generated when one string runs out of characters before the other. Only non-error results are propogated. I've decided to implement this non-deterministic matching as a recursive function call. 74 * If you analyse it you can see there are three possible actions when a '*' is detected. 75 * 1. * is an empty string, ignore it in pattern and try to compare the next character in p with the current character in s. This case only occurs if there are more characters in p (otherwise apple would be greater than a*) 76 * 2. * matches exactly the current character in s, try to match the next character in p with the next character in s 77 * 3. * matches some string of characters including the current character in s, try to match '*' against the next character in s 78 * @param s the String being matched 79 * @param p the Pattern to match it against 80 * @return -1 if s is less than p, 0 if they are equal, 1 if s is greater than p 81 */ 82 static public int compareToPattern(String s, String p) { 83 if(p.indexOf(StaticStrings.STAR_CHAR) == -1) { 84 return compareToPattern(s, p, 0, 0, false); 85 } 86 else { 87 return compareToPattern(s, p, 0, 0, true); 88 } 89 } 90 91 static final private int LESS_THAN = -1; 92 static final private int EQUAL = 0; 93 static final private int GREATER_THAN = 1; 94 static final private int ERROR = 42; 95 96 static private int compareToPattern(String s, String p, int s_index, int p_index, boolean wildcard_matching) { 97 // Lets do the simple cases first. 98 // Both out of characters at the same time 99 if(s_index >= s.length() && p_index >= p.length()) { 100 ///ystem.err.println("Both out of characters. Equal."); 101 return EQUAL; 102 } 103 // s out of characters first 104 if(s_index >= s.length()) { 105 // Not allowed to run out if matching wildcard 106 if(wildcard_matching) { 107 return ERROR; 108 } 109 // Remember that wildcard matches the empty string too, so as long as there are only '*' characters left in the pattern we can say they are equal as well. 110 else { 111 while(p_index < p.length()) { 112 if(p.charAt(p_index) == StaticStrings.STAR_CHAR) { 113 p_index++; 114 } 115 else { 116 ///ystem.err.println("S out of characters. Less Than."); 117 return LESS_THAN; 118 } 119 } 120 // We've run out of pattern and it only contained '*' so we're still equal 121 ///ystem.err.println("Both out of characters. Equal."); 122 return EQUAL; 123 } 124 } 125 // p out of characters first 126 if(p_index >= p.length()) { 127 // Not allowed to run out if matching wildcard 128 if(wildcard_matching) { 129 return ERROR; 130 } 131 // so it is greater than 132 else { 133 ///ystem.err.println("P out of characters. Greater Than."); 134 return GREATER_THAN; 135 } 136 } 137 char s_char = s.charAt(s_index); 138 char p_char = p.charAt(p_index); 139 ///ystem.err.println("Comparing " + s_char + " against pattern character " + p_char); 140 // Equivelent characters 141 // Now the tricky-dicky bit - WildCard matching. 142 if(p_char == StaticStrings.STAR_CHAR) { 143 int result; 144 // Case 1 145 ///ystem.err.println("WildCard Case 1"); 146 if(p_index + 1 < p.length()) { 147 if((result = compareToPattern(s, p, s_index, p_index + 1, wildcard_matching)) != ERROR) { 148 return result; 149 } 150 } 151 // Case 2 152 ///ystem.err.println("WildCard Case 2"); 153 if((result = compareToPattern(s, p, s_index + 1, p_index + 1, wildcard_matching)) != ERROR) { 154 return result; 155 } 156 // Case 3 157 ///ystem.err.println("WildCard Case 3"); 158 if((result = compareToPattern(s, p, s_index + 1, p_index, wildcard_matching)) != ERROR) { 159 return result; 160 } 161 } 162 if(s_char == p_char) { 163 return compareToPattern(s, p, s_index + 1, p_index + 1, wildcard_matching); 164 } 165 // A preceeding character 166 if(s_char < p_char) { 167 ///ystem.err.println("s char is less than p char"); 168 if(wildcard_matching) { 169 ///ystem.err.println("Because we are wildcard matching we still have to match the rest of s incase of errors."); 170 if(compareToPattern(s, p, s_index + 1, p_index + 1, wildcard_matching) != ERROR) { 171 ///ystem.err.println("No error. Less than."); 172 return LESS_THAN; 173 } 174 else { 175 ///ystem.err.println("Error detected."); 176 return ERROR; 177 } 178 } 179 else { 180 ///ystem.err.println("Less than."); 181 return LESS_THAN; 182 } 183 } 184 // A succeeding character 185 if(s_char > p_char) { 186 ///ystem.err.println("s char is greater than p char"); 187 if(wildcard_matching) { 188 ///ystem.err.println("Because we are wildcard matching we still have to match the rest of s incase of errors."); 189 if(compareToPattern(s, p, s_index + 1, p_index + 1, wildcard_matching) != ERROR) { 190 ///ystem.err.println("No error. Greater than."); 191 return GREATER_THAN; 192 } 193 else { 194 ///ystem.err.println("Error detected."); 195 return ERROR; 196 } 197 } 198 else { 199 ///ystem.err.println("Greater than."); 200 return GREATER_THAN; 201 } 202 } 203 // Oh-No. Well, we'll just assume that string is less than pattern 204 return LESS_THAN; 205 } 206 60 207 /** <i>true</i> if the filter should be applied, <i>false</i> to indicate the filter is turned off. */ 61 208 public boolean active; … … 169 316 } 170 317 else { 171 318 // For each value in the list... 172 319 for(int i = 0; i < values.size(); i++) { 173 320 boolean pass; … … 180 327 source = values.get(i).toString().toLowerCase(); 181 328 } 329 System.err.println("Testing " + source + " against pattern " + target); 182 330 // Perform the match, based on the selected method. 183 331 switch(method) { 184 332 case 1: // !EQ 185 pass = !(source.equals(target));333 pass = (compareToPattern(source, target) != 0); 186 334 break; 187 335 case 2: // < 188 pass = ( source.compareTo(target) < 0);336 pass = (compareToPattern(source, target) < 0); 189 337 break; 190 338 case 3: // <eq 191 pass = ( source.compareTo(target) <= 0);339 pass = (compareToPattern(source, target) <= 0); 192 340 break; 193 341 case 4: // > 194 pass = ( source.compareTo(target) > 0);342 pass = (compareToPattern(source, target) > 0); 195 343 break; 196 344 case 5: // >eq 197 pass = ( source.compareTo(target) >= 0);345 pass = (compareToPattern(source, target) >= 0); 198 346 break; 199 347 case 6: // ^ … … 216 364 break; 217 365 default: // EQEQ 218 pass = source.equals(target);366 pass = (compareToPattern(source, target) == 0); 219 367 break; 220 368 }
Note:
See TracChangeset
for help on using the changeset viewer.