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