001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.transport.matchers;
019:
020: import org.apache.mailet.GenericMatcher;
021: import org.apache.mailet.Mail;
022:
023: import javax.mail.MessagingException;
024: import javax.mail.internet.MimeMessage;
025:
026: import java.lang.NumberFormatException;
027:
028: import java.util.Collection;
029: import java.util.StringTokenizer;
030:
031: /**
032: * <P>Matches mails containing a header with a numeric value whose comparison with the specified value is true.
033: * If the header is missing in the message, there will be <I>no match</I></P>
034: * <P>Configuration string: The headerName, a comparison operator and the numeric headerValue
035: * to compare with, <I>space or tab delimited</I>.</P>
036: * <P>The comparison operators are: <CODE><, <=, ==, >=, ></CODE>;
037: * another set of operators is: <CODE>LT, LE, EQ, GE, GT</CODE>.
038: * Also the following operators are accepted: <CODE>=<, =, =></CODE>.</P>
039: * <P>Example:</P>
040: * <PRE><CODE>
041: * <mailet match="CompareNumericHeaderValue=X-MessageIsSpamProbability > 0.9" class="ToProcessor">
042: * <processor> spam </processor>
043: * </mailet>
044: * </CODE></PRE>
045: *
046: * @version CVS $Revision: 494012 $ $Date: 2007-01-08 11:23:58 +0100 (Mo, 08 Jan 2007) $
047: * @since 2.2.0
048: */
049: public class CompareNumericHeaderValue extends GenericMatcher {
050:
051: private String headerName = null;
052:
053: private int comparisonOperator;
054: private final static int LT = -2;
055: private final static int LE = -1;
056: private final static int EQ = 0;
057: private final static int GE = +1;
058: private final static int GT = +2;
059:
060: private Double headerValue;
061:
062: public void init() throws MessagingException {
063: StringTokenizer st = new StringTokenizer(getCondition(), " \t",
064: false);
065: if (st.hasMoreTokens()) {
066: headerName = st.nextToken().trim();
067: } else {
068: throw new MessagingException("Missing headerName");
069: }
070: if (st.hasMoreTokens()) {
071: String comparisonOperatorString = st.nextToken().trim();
072: if (comparisonOperatorString.equals("<")
073: || comparisonOperatorString.equals("LT")) {
074: comparisonOperator = LT;
075: } else if (comparisonOperatorString.equals("<=")
076: || comparisonOperatorString.equals("=<")
077: || comparisonOperatorString.equals("LE")) {
078: comparisonOperator = LE;
079: } else if (comparisonOperatorString.equals("==")
080: || comparisonOperatorString.equals("=")
081: || comparisonOperatorString.equals("EQ")) {
082: comparisonOperator = EQ;
083: } else if (comparisonOperatorString.equals(">=")
084: || comparisonOperatorString.equals("=>")
085: || comparisonOperatorString.equals("GE")) {
086: comparisonOperator = GE;
087: } else if (comparisonOperatorString.equals(">")
088: || comparisonOperatorString.equals("GT")) {
089: comparisonOperator = GT;
090: } else {
091: throw new MessagingException(
092: "Bad comparisonOperator: \""
093: + comparisonOperatorString + "\"");
094: }
095: } else {
096: throw new MessagingException("Missing comparisonOperator");
097: }
098: if (st.hasMoreTokens()) {
099: String headerValueString = st.nextToken().trim();
100: try {
101: headerValue = Double.valueOf(headerValueString);
102: } catch (NumberFormatException nfe) {
103: throw new MessagingException(
104: "Bad header comparison value: \""
105: + headerValueString + "\"", nfe);
106: }
107: } else {
108: throw new MessagingException(
109: "Missing headerValue threshold");
110: }
111: }
112:
113: public Collection match(Mail mail) throws MessagingException {
114: if (headerName == null) {
115: // should never get here
116: throw new IllegalStateException("Null headerName");
117: }
118:
119: MimeMessage message = (MimeMessage) mail.getMessage();
120:
121: String[] headerArray = message.getHeader(headerName);
122: if (headerArray != null && headerArray.length > 0) {
123: try {
124: int comparison = Double.valueOf(headerArray[0].trim())
125: .compareTo(headerValue);
126: switch (comparisonOperator) {
127: case LT:
128: if (comparison < 0) {
129: return mail.getRecipients();
130: }
131: break;
132: case LE:
133: if (comparison <= 0) {
134: return mail.getRecipients();
135: }
136: break;
137: case EQ:
138: if (comparison == 0) {
139: return mail.getRecipients();
140: }
141: break;
142: case GE:
143: if (comparison >= 0) {
144: return mail.getRecipients();
145: }
146: break;
147: case GT:
148: if (comparison > 0) {
149: return mail.getRecipients();
150: }
151: break;
152: default:
153: // should never get here
154: throw new IllegalStateException(
155: "Unknown comparisonOperator"
156: + comparisonOperator);
157: }
158: } catch (NumberFormatException nfe) {
159: throw new MessagingException(
160: "Bad header value found in message: \""
161: + headerArray[0] + "\"", nfe);
162: }
163: }
164:
165: return null;
166: }
167: }
|