1 /************************************************************************
2 * Copyright (c) 2000-2006 The Apache Software Foundation. *
3 * All rights reserved. *
4 * ------------------------------------------------------------------- *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you *
6 * may not use this file except in compliance with the License. You *
7 * may obtain a copy of the License at: *
8 * *
9 * http://www.apache.org/licenses/LICENSE-2.0 *
10 * *
11 * Unless required by applicable law or agreed to in writing, software *
12 * distributed under the License is distributed on an "AS IS" BASIS, *
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14 * implied. See the License for the specific language governing *
15 * permissions and limitations under the License. *
16 ***********************************************************************/
17
18 package org.apache.james.transport.matchers;
19
20 import org.apache.mailet.GenericMatcher;
21 import org.apache.mailet.Mail;
22
23 import javax.mail.MessagingException;
24 import javax.mail.internet.MimeMessage;
25
26 import java.lang.NumberFormatException;
27
28 import java.util.Collection;
29 import java.util.StringTokenizer;
30
31 /***
32 * <P>Matches mails containing a header with a numeric value whose comparison with the specified value is true.
33 * If the header is missing in the message, there will be <I>no match</I></P>
34 * <P>Configuration string: The headerName, a comparison operator and the numeric headerValue
35 * to compare with, <I>space or tab delimited</I>.</P>
36 * <P>The comparison operators are: <CODE><, <=, ==, >=, ></CODE>;
37 * another set of operators is: <CODE>LT, LE, EQ, GE, GT</CODE>.
38 * Also the following operators are accepted: <CODE>=<, =, =></CODE>.</P>
39 * <P>Example:</P>
40 * <PRE><CODE>
41 * <mailet match="CompareNumericHeaderValue=X-MessageIsSpamProbability > 0.9" class="ToProcessor">
42 * <processor> spam </processor>
43 * </mailet>
44 * </CODE></PRE>
45 *
46 * @version CVS $Revision: 365582 $ $Date: 2006-01-03 08:51:21 +0000 (mar, 03 gen 2006) $
47 * @since 2.2.0
48 */
49 public class CompareNumericHeaderValue extends GenericMatcher {
50
51 private String headerName = null;
52
53 private int comparisonOperator;
54 private final static int LT = -2;
55 private final static int LE = -1;
56 private final static int EQ = 0;
57 private final static int GE = +1;
58 private final static int GT = +2;
59
60 private Double headerValue;
61
62 public void init() throws MessagingException {
63 StringTokenizer st = new StringTokenizer(getCondition(), " \t", false);
64 if (st.hasMoreTokens()) {
65 headerName = st.nextToken().trim();
66 }
67 else {
68 throw new MessagingException("Missing headerName");
69 }
70 if (st.hasMoreTokens()) {
71 String comparisonOperatorString = st.nextToken().trim();
72 if (comparisonOperatorString.equals("<")
73 || comparisonOperatorString.equals("LT")) {
74 comparisonOperator = LT;
75 }
76 else if (comparisonOperatorString.equals("<=")
77 || comparisonOperatorString.equals("=<")
78 || comparisonOperatorString.equals("LE")) {
79 comparisonOperator = LE;
80 }
81 else if (comparisonOperatorString.equals("==")
82 || comparisonOperatorString.equals("=")
83 || comparisonOperatorString.equals("EQ")) {
84 comparisonOperator = EQ;
85 }
86 else if (comparisonOperatorString.equals(">=")
87 || comparisonOperatorString.equals("=>")
88 || comparisonOperatorString.equals("GE")) {
89 comparisonOperator = GE;
90 }
91 else if (comparisonOperatorString.equals(">")
92 || comparisonOperatorString.equals("GT")) {
93 comparisonOperator = GT;
94 }
95 else {
96 throw new MessagingException("Bad comparisonOperator: \"" + comparisonOperatorString + "\"");
97 }
98 }
99 else {
100 throw new MessagingException("Missing comparisonOperator");
101 }
102 if (st.hasMoreTokens()) {
103 String headerValueString = st.nextToken().trim();
104 try {
105 headerValue = Double.valueOf(headerValueString);
106 }
107 catch (NumberFormatException nfe) {
108 throw new MessagingException("Bad header comparison value: \""
109 + headerValueString + "\"", nfe);
110 }
111 }
112 else {
113 throw new MessagingException("Missing headerValue threshold");
114 }
115 }
116
117 public Collection match(Mail mail) throws MessagingException {
118 if (headerName == null) {
119
120 throw new IllegalStateException("Null headerName");
121 }
122
123 MimeMessage message = (MimeMessage) mail.getMessage();
124
125 String [] headerArray = message.getHeader(headerName);
126 if (headerArray != null && headerArray.length > 0) {
127 try {
128 int comparison = Double.valueOf(headerArray[0].trim()).compareTo(headerValue);
129 switch (comparisonOperator) {
130 case LT:
131 if (comparison < 0) {
132 return mail.getRecipients();
133 }
134 break;
135 case LE:
136 if (comparison <= 0) {
137 return mail.getRecipients();
138 }
139 break;
140 case EQ:
141 if (comparison == 0) {
142 return mail.getRecipients();
143 }
144 break;
145 case GE:
146 if (comparison >= 0) {
147 return mail.getRecipients();
148 }
149 break;
150 case GT:
151 if (comparison > 0) {
152 return mail.getRecipients();
153 }
154 break;
155 default:
156
157 throw new IllegalStateException("Unknown comparisonOperator" + comparisonOperator);
158 }
159 }
160 catch (NumberFormatException nfe) {
161 throw new MessagingException("Bad header value found in message: \"" + headerArray[0] + "\"", nfe);
162 }
163 }
164
165 return null;
166 }
167 }