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 * <mailet match="RecipientIs=forwarded@myhost" 51 * class="UseHeaderRecipients"> 52 * </mailet> 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 }