/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.transport.mailets;
import org.apache.mailet.RFC2822Headers;
import org.apache.mailet.GenericMailet;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
import org.apache.mailet.MailetException;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.Collection;
import java.util.Iterator;
import java.util.ArrayList;
/**
* <P>Generates a response to the reverse-path address.
* Note that this is different than a mail-client's
* reply, which would use the Reply-To or From header.</P>
* <P>Bounced messages are attached in their entirety (headers and
* content) and the resulting MIME part type is "message/rfc822".<BR>
* The reverse-path and the Return-Path header of the response is set to "null" ("<>"),
* meaning that no reply should be sent.</P>
* <P>A sender of the notification message can optionally be specified.
* If one is not specified, the postmaster's address will be used.<BR>
* A notice text can be specified, and in such case will be inserted into the
* notification inline text.<BR>
* If the notified message has an "error message" set, it will be inserted into the
* notification inline text. If the <CODE>attachStackTrace</CODE> init parameter
* is set to true, such error message will be attached to the notification message.<BR>
* <P>Supports the <CODE>passThrough</CODE> init parameter (true if missing).</P>
*
* <P>Sample configuration:</P>
* <PRE><CODE>
* <mailet match="All" class="Bounce">
* <sender><I>an address or postmaster or sender or unaltered, default=postmaster</I></sender>
* <attachError><I>true or false, default=false</I></attachError>
* <message><I>notice attached to the original message text (optional)</I></message>
* <prefix><I>optional subject prefix prepended to the original message</I></prefix>
* <inline><I>see {@link Resend}, default=none</I></inline>
* <attachment><I>see {@link Resend}, default=message</I></attachment>
* <passThrough><I>true or false, default=true</I></passThrough>
* <fakeDomainCheck><I>true or false, default=true</I></fakeDomainCheck>
* <debug><I>true or false, default=false</I></debug>
* </mailet>
* </CODE></PRE>
*
* <P>The behaviour of this mailet is equivalent to using Resend with the following
* configuration:</P>
* <PRE><CODE>
* <mailet match="All" class="Resend">
* <sender><I>an address or postmaster or sender or unaltered</I></sender>
* <attachError><I>true or false</I></attachError>
* <message><I><B>dynamically built</B></I></message>
* <prefix><I>a string</I></prefix>
* <passThrough>true or false</passThrough>
* <fakeDomainCheck><I>true or false</I></fakeDomainCheck>
* <recipients><B>sender</B></recipients>
* <reversePath>null</reversePath>
* <inline>see {@link Resend}</inline>
* <attachment>see {@link Resend}</attachment>
* <isReply>true</isReply>
* <debug><I>true or false</I></debug>
* </mailet>
* </CODE></PRE>
* <P><I>notice</I> and <I>sendingAddress</I> can be used instead of
* <I>message</I> and <I>sender</I>; such names are kept for backward compatibility.</P>
*
* @version CVS $Revision: 494012 $ $Date: 2007-01-08 11:23:58 +0100 (Mo, 08 Jan 2007) $
* @since 2.2.0
*/
public class Bounce extends AbstractNotify {
/**
* Return a string describing this mailet.
*
* @return a string describing this mailet
*/
public String getMailetInfo() {
return "Bounce Mailet";
}
/** Gets the expected init parameters. */
protected String[] getAllowedInitParameters() {
String[] allowedArray = {
// "static",
"debug",
"passThrough",
"fakeDomainCheck",
"inline",
"attachment",
"message",
"notice",
"sender",
"sendingAddress",
"prefix",
"attachError",
};
return allowedArray;
}
/* ******************************************************************** */
/* ****************** Begin of getX and setX methods ****************** */
/* ******************************************************************** */
/**
* @return <CODE>SpecialAddress.REVERSE_PATH</CODE>
*/
protected Collection getRecipients() {
Collection newRecipients = new HashSet();
newRecipients.add(SpecialAddress.REVERSE_PATH);
return newRecipients;
}
/**
* @return <CODE>SpecialAddress.REVERSE_PATH</CODE>
*/
protected InternetAddress[] getTo() {
InternetAddress[] apparentlyTo = new InternetAddress[1];
apparentlyTo[0] = SpecialAddress.REVERSE_PATH.toInternetAddress();
return apparentlyTo;
}
/**
* @return <CODE>SpecialAddress.NULL</CODE> (the meaning of bounce)
*/
protected MailAddress getReversePath(Mail originalMail) {
return SpecialAddress.NULL;
}
/* ******************************************************************** */
/* ******************* End of getX and setX methods ******************* */
/* ******************************************************************** */
/**
* Service does the hard work,and redirects the originalMail in the form specified.
* Checks that the original return path is not empty,
* and then calls super.service(originalMail), otherwise just returns.
*
* @param originalMail the mail to process and redirect
* @throws MessagingException if a problem arises formulating the redirected mail
*/
public void service(Mail originalMail) throws MessagingException {
if (originalMail.getSender() == null) {
if (isDebug)
log("Processing a bounce request for a message with an empty reverse-path. No bounce will be sent.");
if(!getPassThrough(originalMail)) {
originalMail.setState(Mail.GHOST);
}
return;
}
if (isDebug)
log("Processing a bounce request for a message with a reverse path. The bounce will be sent to " + originalMail.getSender().toString());
super.service(originalMail);
}
}
|