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  
21  
22  package org.apache.james.transport.matchers;
23  
24  import org.apache.mailet.base.GenericMatcher;
25  import org.apache.mailet.Mail;
26  
27  import javax.mail.MessagingException;
28  import javax.mail.internet.MimeMessage;
29  
30  import java.lang.NumberFormatException;
31  
32  import java.util.Collection;
33  import java.util.StringTokenizer;
34  
35  /**
36   * <P>Matches mails containing a header with a numeric value whose comparison with the specified value is true.
37   * If the header is missing in the message, there will be <I>no match</I></P>
38   * <P>Configuration string: The headerName, a comparison operator and the numeric headerValue
39   * to compare with, <I>space or tab delimited</I>.</P>
40   * <P>The comparison operators are: <CODE>&lt, &lt=, ==, &gt=, &gt</CODE>;
41   * another set of operators is: <CODE>LT, LE, EQ, GE, GT</CODE>.
42   * Also the following operators are accepted: <CODE>=&lt, =, =&gt</CODE>.</P>
43   * <P>Example:</P>
44   * <PRE><CODE>
45   *    &lt;mailet match="CompareNumericHeaderValue=X-MessageIsSpamProbability > 0.9" class="ToProcessor"&gt;
46   *       &lt;processor&gt; spam &lt;/processor&gt;
47   *    &lt;/mailet&gt;
48   * </CODE></PRE>
49   *
50   * @version CVS $Revision: 713949 $ $Date: 2008-11-14 07:40:21 +0000 (Fri, 14 Nov 2008) $
51   * @since 2.2.0
52   */
53  public class CompareNumericHeaderValue extends GenericMatcher {
54  
55      private String headerName = null;
56      
57      private int comparisonOperator;
58      private final static int LT = -2;
59      private final static int LE = -1;
60      private final static int EQ =  0;
61      private final static int GE = +1;
62      private final static int GT = +2;
63      
64      private Double headerValue;
65  
66      /**
67       * @see org.apache.mailet.GenericMatcher#init()
68       */
69      public void init() throws MessagingException {
70          StringTokenizer st = new StringTokenizer(getCondition(), " \t", false);
71          if (st.hasMoreTokens()) {
72              headerName = st.nextToken().trim();
73          }
74          else {
75              throw new MessagingException("Missing headerName");
76          }
77          if (st.hasMoreTokens()) {
78              String comparisonOperatorString = st.nextToken().trim();
79              if (comparisonOperatorString.equals("<")
80                  || comparisonOperatorString.equals("LT")) {
81                  comparisonOperator = LT;
82              }
83              else if (comparisonOperatorString.equals("<=")
84                       || comparisonOperatorString.equals("=<")
85                       || comparisonOperatorString.equals("LE")) {
86                  comparisonOperator = LE;
87              }
88              else if (comparisonOperatorString.equals("==")
89                       || comparisonOperatorString.equals("=")
90                       || comparisonOperatorString.equals("EQ")) {
91                  comparisonOperator = EQ;
92              }
93              else if (comparisonOperatorString.equals(">=")
94                       || comparisonOperatorString.equals("=>")
95                       || comparisonOperatorString.equals("GE")) {
96                  comparisonOperator = GE;
97              }
98              else if (comparisonOperatorString.equals(">")
99                       || comparisonOperatorString.equals("GT")) {
100                 comparisonOperator = GT;
101             }
102             else {
103                 throw new MessagingException("Bad comparisonOperator: \"" + comparisonOperatorString + "\"");
104             }
105         }
106         else {
107             throw new MessagingException("Missing comparisonOperator");
108         }
109         if (st.hasMoreTokens()) {
110             String headerValueString = st.nextToken().trim();
111             try {
112                 headerValue = Double.valueOf(headerValueString);
113             }
114             catch (NumberFormatException nfe) {
115                 throw new MessagingException("Bad header comparison value: \""
116                                              + headerValueString + "\"", nfe);
117             }
118         }
119         else {
120             throw new MessagingException("Missing headerValue threshold");
121         }
122     }
123 
124     /**
125      * @see org.apache.mailet.GenericMatcher#match(Mail)
126      */
127     public Collection match(Mail mail) throws MessagingException {
128         if (headerName == null) {
129             // should never get here
130             throw new IllegalStateException("Null headerName");
131         }
132         
133         MimeMessage message = (MimeMessage) mail.getMessage();
134         
135         String [] headerArray = message.getHeader(headerName);
136         if (headerArray != null && headerArray.length > 0) {
137             try {
138                 int comparison = Double.valueOf(headerArray[0].trim()).compareTo(headerValue);
139                 switch (comparisonOperator) {
140                     case LT:
141                         if (comparison < 0) {
142                             return mail.getRecipients();
143                         }
144                         break;
145                     case LE:
146                         if (comparison <= 0) {
147                             return mail.getRecipients();
148                         }
149                         break;
150                     case EQ:
151                         if (comparison == 0) {
152                             return mail.getRecipients();
153                         }
154                         break;
155                     case GE:
156                         if (comparison >= 0) {
157                             return mail.getRecipients();
158                         }
159                         break;
160                     case GT:
161                         if (comparison > 0) {
162                             return mail.getRecipients();
163                         }
164                         break;
165                     default:
166                         // should never get here
167                         throw new IllegalStateException("Unknown comparisonOperator" + comparisonOperator);
168                 }
169             }
170             catch (NumberFormatException nfe) {
171                 throw new MessagingException("Bad header value found in message: \"" + headerArray[0] + "\"", nfe);
172             }
173         }
174         
175         return null;
176     }
177 }