View Javadoc

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