зеркало из https://github.com/mozilla/gecko-dev.git
239 строки
5.2 KiB
Java
239 строки
5.2 KiB
Java
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is the GFilt filter package, as integrated into
|
|
* the Grendel mail/news reader.
|
|
*
|
|
* The Initial Developer of the Original Code is Ian Clarke.
|
|
* Portions created by Ian Clarke are
|
|
* Copyright (C) 2000 Ian Clarke. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
|
|
package grendel.filters; // formerly GFilt
|
|
import java.util.*;
|
|
|
|
public class Filter {
|
|
/**
|
|
* Set to true to output debugging information
|
|
**/
|
|
public boolean debug = false;
|
|
Pattern patterns = null;
|
|
|
|
/**
|
|
* Get the number of patterns in the filter
|
|
* @return The number of patterns in the filter
|
|
**/
|
|
public int getLength() {
|
|
Pattern cur = patterns;
|
|
int r = 0;
|
|
while (cur != null) {
|
|
cur = cur.next;
|
|
r++;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
public int getTLength() {
|
|
Pattern cur = patterns;
|
|
int r = 0;
|
|
while (cur != null)
|
|
{
|
|
r += cur.str.length() + 1;
|
|
cur = cur.next;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
public void setString(String str, int p) {
|
|
Pattern pat = patterns;
|
|
for (int x = 0; x < p; x++) {
|
|
pat = pat.next;
|
|
}
|
|
pat.str = str;
|
|
}
|
|
public void setAnd(boolean and, int p) {
|
|
Pattern pat = patterns;
|
|
for (int x = 0; x < p; x++) {
|
|
pat = pat.next;
|
|
}
|
|
pat.and = and;
|
|
}
|
|
|
|
public void del(int p) {
|
|
if (p == 0) {
|
|
patterns = patterns.next;
|
|
} else {
|
|
Pattern cur = patterns;
|
|
for (int x = 0; x < (p - 1); x++) {
|
|
cur = cur.next;
|
|
}
|
|
cur.next = cur.next.next;
|
|
}
|
|
}
|
|
|
|
|
|
public String getString(int p) {
|
|
Pattern pat = patterns;
|
|
for (int x = 0; x < p; x++) {
|
|
pat = pat.next;
|
|
}
|
|
|
|
return pat.str;
|
|
|
|
}
|
|
|
|
public boolean getAnd(int p) {
|
|
Pattern pat = patterns;
|
|
for (int x = 0; x < p; x++) {
|
|
pat = pat.next;
|
|
}
|
|
return pat.and;
|
|
}
|
|
|
|
public void insert(String s, boolean and, int p) {
|
|
Pattern n = new Pattern(s, and);
|
|
Pattern cur = patterns;
|
|
if (p == 0) {
|
|
n.next = patterns;
|
|
patterns = n;
|
|
} else {
|
|
for (int x = 0; x < p - 1; x++) {
|
|
cur = cur.next;
|
|
}
|
|
n.next = cur.next;
|
|
cur.next = n;
|
|
}
|
|
}
|
|
|
|
public void push(String s, boolean and) {
|
|
|
|
if (patterns == null) {
|
|
patterns = new Pattern(s, and);
|
|
} else {
|
|
Pattern p = patterns;
|
|
|
|
while (p.next != null) {
|
|
p = p.next;
|
|
}
|
|
p.next = new Pattern(s, and);
|
|
}
|
|
}
|
|
|
|
public boolean match(String str) {
|
|
return match(str, 0, patterns);
|
|
}
|
|
|
|
public Filter duplicate()
|
|
{
|
|
Filter n = new Filter();
|
|
Pattern cur = patterns;
|
|
while(cur != null)
|
|
{
|
|
n.push(cur.str, cur.and);
|
|
cur = cur.next;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
protected boolean match(String str, int pos, Pattern pat)
|
|
{
|
|
if (pat == null)
|
|
{
|
|
System.err.println("Attempted to match with empty pattern list");
|
|
return false;
|
|
}
|
|
int p = str.indexOf(pat.str, pos);
|
|
if (debug)
|
|
System.err.print("Matching "+pat.str + " from "+pos + " - ");
|
|
if (p == -1) {
|
|
if (debug)
|
|
System.err.print("Not found - ");
|
|
if (pat.next == null) {
|
|
if (debug)
|
|
System.err.println("Last pattern - failing");
|
|
return false;
|
|
}
|
|
if (pat.and) {
|
|
if (debug)
|
|
System.err.println("And relationship - failing");
|
|
return false;
|
|
} else {
|
|
if (debug)
|
|
System.err.println("Or relationship - recursing");
|
|
return match(str, pos, pat.next);
|
|
}
|
|
} else {
|
|
if (debug)
|
|
System.err.print("Found at "+p + " - ");
|
|
Pattern tPat = pat;
|
|
while (!(tPat.and)) {
|
|
if (tPat.next == null) {
|
|
if (debug)
|
|
System.err.println("Last one - success");
|
|
return true;
|
|
}
|
|
tPat = tPat.next;
|
|
}
|
|
if (tPat.next == null) {
|
|
if (debug)
|
|
System.err.println("All others are 'or' - success");
|
|
return true;
|
|
}
|
|
if (debug)
|
|
System.err.println("Skipping to end of or group");
|
|
if (match(str, p + pat.str.length(), tPat.next))
|
|
return true;
|
|
else {
|
|
if (debug)
|
|
System.err.println("Backtracking..");
|
|
return (match(str, pos, pat.next));
|
|
}
|
|
}
|
|
}
|
|
|
|
public String toString() {
|
|
StringBuffer s = new StringBuffer();
|
|
Pattern cur = patterns;
|
|
while (cur != null) {
|
|
String andV;
|
|
if (cur.and)
|
|
andV = " and then ";
|
|
else
|
|
andV = "or";
|
|
if (cur.next != null)
|
|
s.append("\""+cur.str + "\" "+andV + " ");
|
|
else
|
|
s.append("\""+cur.str + "\"");
|
|
cur = cur.next;
|
|
}
|
|
return s.toString();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
class Pattern {
|
|
public boolean and;
|
|
public Pattern next = null;
|
|
public String str;
|
|
public Pattern(String s, boolean a) {
|
|
and = a;
|
|
str = s;
|
|
}
|
|
}
|
|
|
|
|
|
|