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.mailets;
21  
22  import org.apache.mailet.GenericMailet;
23  import org.apache.mailet.Mail;
24  import org.apache.mailet.MailAddress;
25  
26  import javax.mail.MessagingException;
27  import javax.mail.internet.InternetAddress;
28  import javax.mail.internet.MimeMessage;
29  import java.util.Collection;
30  import java.util.StringTokenizer;
31  import java.util.Vector;
32  
33  /***
34   * <p>Mailet designed to process the recipients from the mail headers rather
35   * than the recipients specified in the SMTP message header.  This can be
36   * useful if your mail is redirected on-route by a mail server that
37   * substitutes a fixed recipient address for the original.</p>
38   *
39   * <p>To use this, match against the redirection address using the
40   * <code>RecipientIs</code> matcher and set the mailet 'class' to
41   * <code>UseHeaderRecipients</code>.  This will cause the email to be
42   * re-injected into the root process with the recipient substituted
43   * by all the recipients in the Mail-For, To and Cc headers
44   * of the message.</p>
45   *
46   * <p>e.g.</p>
47   * <pre>
48   *    <mailet match="RecipientIs=forwarded@myhost"
49   *            class="UseHeaderRecipients">
50   *    </mailet>
51   * </pre>
52   *
53   * @version 1.0.0, 24/11/2000
54   */
55  public class UseHeaderRecipients extends GenericMailet {
56  
57      /***
58       * Controls certain log messages
59       */
60      private boolean isDebug = false;
61  
62      /***
63       * Initialize the mailet
64       *
65       * initializes the DEBUG flag
66       */
67      public void init() {
68          isDebug = (getInitParameter("debug") == null) ? false : new Boolean(getInitParameter("debug")).booleanValue();
69      }
70  
71      /***
72       * Process an incoming email, removing the currently identified
73       * recipients and replacing them with the recipients indicated in
74       * the Mail-For, To and Cc headers of the actual email.
75       *
76       * @param mail incoming email
77       */
78      public void service(Mail mail) throws MessagingException {
79          MimeMessage message = mail.getMessage();
80  
81          // Utilise features of Set Collections such that they automatically
82          // ensure that no two entries are equal using the equality method
83          // of the element objects.  MailAddress objects test equality based
84          // on equivalent but not necessarily visually identical addresses.
85          Collection recipients = mail.getRecipients();
86          // Wipe all the exist recipients
87          recipients.clear();
88          recipients.addAll(getHeaderMailAddresses(message, "Mail-For"));
89          if (recipients.isEmpty()) {
90              recipients.addAll(getHeaderMailAddresses(message, "To"));
91              recipients.addAll(getHeaderMailAddresses(message, "Cc"));
92          }
93          if (isDebug) {
94              log("All recipients = " + recipients.toString());
95              log("Reprocessing mail using recipients in message headers");
96          }
97  
98          // Return email to the "root" process.
99          getMailetContext().sendMail(mail.getSender(), mail.getRecipients(), mail.getMessage());
100         mail.setState(Mail.GHOST);
101     }
102 
103 
104     /***
105      * Return a string describing this mailet.
106      *
107      * @return a string describing this mailet
108      */
109     public String getMailetInfo() {
110         return "UseHeaderRecipients Mailet";
111     }
112 
113     /***
114      * Work through all the headers of the email with a matching name and
115      * extract all the mail addresses as a collection of addresses.
116      *
117      * @param mail the mail message to read
118      * @param name the header name as a String
119      * @return the collection of MailAddress objects.
120      */
121     private Collection getHeaderMailAddresses(MimeMessage message, String name) throws MessagingException {
122 
123         if (isDebug) {
124             StringBuffer logBuffer =
125                 new StringBuffer(64)
126                         .append("Checking ")
127                         .append(name)
128                         .append(" headers");
129             log(logBuffer.toString());
130         }
131         Collection addresses = new Vector();
132         String[] headers = message.getHeader(name);
133         String addressString;
134         InternetAddress iAddress;
135         if (headers != null) {
136             for(int i = 0; i < headers.length; i++) {
137                 StringTokenizer st = new StringTokenizer(headers[i], ",", false);
138                 while (st.hasMoreTokens()) {
139                     addressString = st.nextToken();
140                     iAddress = new InternetAddress(addressString);
141                     if (isDebug) {
142                         log("Address = " + iAddress.toString());
143                     }
144                     addresses.add(new MailAddress(iAddress));
145                 }
146             }
147         }
148         return addresses;
149     }
150 
151 }