View Javadoc

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>&lt, &lt=, ==, &gt=, &gt</CODE>;
37   * another set of operators is: <CODE>LT, LE, EQ, GE, GT</CODE>.
38   * Also the following operators are accepted: <CODE>=&lt, =, =&gt</CODE>.</P>
39   * <P>Example:</P>
40   * <PRE><CODE>
41   *    &lt;mailet match="CompareNumericHeaderValue=X-MessageIsSpamProbability > 0.9" class="ToProcessor"&gt;
42   *       &lt;processor&gt; spam &lt;/processor&gt;
43   *    &lt;/mailet&gt;
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             // should never get here
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                         // should never get here
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 }