scripts/mir-setup/README: update with link to new doc on wiki
[mir.git] / source / mircoders / abuse / RegularExpressionFilterType.java
1 /*
2  * Copyright (C) 2001-2006 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * and distribute linked combinations including the two.  You must obey the
23  * GNU General Public License in all respects for all of the code used other than
24  * the above mentioned libraries.  If you modify this file, you may extend this
25  * exception to your version of the file, but you are not obligated to do so.
26  * If you do not wish to do so, delete this exception statement from your version.
27  */
28
29 package mircoders.abuse;
30
31 import mir.entity.Entity;
32 import mir.session.Request;
33
34 import java.util.Arrays;
35 import java.util.Iterator;
36 import java.util.List;
37
38 import org.apache.oro.text.regex.*;
39
40
41 /**
42   * A description of a regular expression filter.
43   */
44  public class RegularExpressionFilterType extends AbstractFilterType {
45     private boolean exactMatch;
46     private boolean caseSensitive;
47     private int fieldKind;
48     private List selectedFields;
49
50     public static final int ENTITY_FIELDS = 0;
51     public static final int REQUEST_HEADERS = 2;
52
53     public RegularExpressionFilterType(String aName) {
54       this(aName, false, false, null);
55     }
56
57     public RegularExpressionFilterType(String aName, boolean aCaseSensitive, boolean anExactMatch, String[] aSelectedFields) {
58       this (aName, aCaseSensitive, anExactMatch, ENTITY_FIELDS, aSelectedFields);
59     }
60
61     public RegularExpressionFilterType(String aName, boolean aCaseSensitive, boolean anExactMatch, int aFieldKind, String[] aSelectedFields) {
62       super(aName);
63
64       fieldKind = aFieldKind;
65
66       caseSensitive = aCaseSensitive;
67       exactMatch = anExactMatch;
68       if (aSelectedFields==null) {
69         selectedFields = null;
70       }
71       else {
72         selectedFields = Arrays.asList(aSelectedFields);
73       }
74     }
75
76
77   public FilterInstance constructFilterInstance(final String anExpression) throws AbuseExc {
78     try {
79       int flags = 0;
80
81       if (!caseSensitive) {
82         flags |= Perl5Compiler.CASE_INSENSITIVE_MASK;
83       }
84
85       final Pattern pattern = (new Perl5Compiler()).compile(anExpression, flags);
86
87       return new FilterInstance() {
88
89         public boolean test(Entity anEntity, Request aRequest) {
90           PatternMatcher matcher = new Perl5Matcher();
91
92           Iterator j;
93
94           switch (fieldKind) {
95             case REQUEST_HEADERS:
96               if (selectedFields != null) {
97                 j = selectedFields.iterator();
98
99                 while (j.hasNext()) {
100                   String fieldName = (String) j.next();
101                   String field = aRequest.getHeader(fieldName);
102
103                   if (exactMatch) {
104                     if (field != null && matcher.matches(field, pattern)) {
105                       return true;
106                     }
107                   }
108                   else {
109                     if (field != null && matcher.contains(field, pattern)) {
110                       return true;
111                     }
112                   }
113                 }
114               }
115               break;
116
117             case ENTITY_FIELDS:
118               if (selectedFields != null) {
119                 j = selectedFields.iterator();
120               }
121               else {
122                 j = anEntity.getFieldNames().iterator();
123               }
124
125               while (j.hasNext()) {
126                 String field = anEntity.getFieldValue( (String) j.next());
127
128                 if (exactMatch) {
129                   if (field != null && matcher.matches(field, pattern)) {
130                     return true;
131                   }
132                 }
133                 else {
134                   if (field != null && matcher.contains(field, pattern)) {
135                     return true;
136                   }
137                 }
138               }
139           }
140           return false;
141         }
142
143         public String status() {
144           return null;
145         }
146       };
147     }
148     catch (MalformedPatternException t) {
149       throw new AbuseExc("Invalid expression: " + t.getMessage());
150     }
151   }
152 }