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 java.util.Collection;
25  import java.util.HashSet;
26  
27  import javax.mail.MessagingException;
28  import javax.mail.internet.InternetAddress;
29  
30  import org.apache.mailet.Mail;
31  import org.apache.mailet.MailAddress;
32  
33  
34  /**
35   * <P>Generates a response to the reverse-path address.
36   * Note that this is different than a mail-client's
37   * reply, which would use the Reply-To or From header.</P>
38   * <P>Bounced messages are attached in their entirety (headers and
39   * content) and the resulting MIME part type is "message/rfc822".<BR>
40   * The reverse-path and the Return-Path header of the response is set to "null" ("<>"),
41   * meaning that no reply should be sent.</P>
42   * <P>A sender of the notification message can optionally be specified.
43   * If one is not specified, the postmaster's address will be used.<BR>
44   * A notice text can be specified, and in such case will be inserted into the
45   * notification inline text.<BR>
46   * If the notified message has an "error message" set, it will be inserted into the
47   * notification inline text. If the <CODE>attachStackTrace</CODE> init parameter
48   * is set to true, such error message will be attached to the notification message.<BR>
49   * <P>Supports the <CODE>passThrough</CODE> init parameter (true if missing).</P>
50   *
51   * <P>Sample configuration:</P>
52   * <PRE><CODE>
53   * &lt;mailet match="All" class="Bounce">
54   *   &lt;sender&gt;<I>an address or postmaster or sender or unaltered, default=postmaster</I>&lt;/sender&gt;
55   *   &lt;attachError&gt;<I>true or false, default=false</I>&lt;/attachError&gt;
56   *   &lt;message&gt;<I>notice attached to the original message text (optional)</I>&lt;/message&gt;
57   *   &lt;prefix&gt;<I>optional subject prefix prepended to the original message</I>&lt;/prefix&gt;
58   *   &lt;inline&gt;<I>see {@link Resend}, default=none</I>&lt;/inline&gt;
59   *   &lt;attachment&gt;<I>see {@link Resend}, default=message</I>&lt;/attachment&gt;
60   *   &lt;passThrough&gt;<I>true or false, default=true</I>&lt;/passThrough&gt;
61   *   &lt;fakeDomainCheck&gt;<I>true or false, default=true</I>&lt;/fakeDomainCheck&gt;
62   *   &lt;debug&gt;<I>true or false, default=false</I>&lt;/debug&gt;
63   * &lt;/mailet&gt;
64   * </CODE></PRE>
65   *
66   * <P>The behaviour of this mailet is equivalent to using Resend with the following
67   * configuration:</P>
68   * <PRE><CODE>
69   * &lt;mailet match="All" class="Resend">
70   *   &lt;sender&gt;<I>an address or postmaster or sender or unaltered</I>&lt;/sender&gt;
71   *   &lt;attachError&gt;<I>true or false</I>&lt;/attachError&gt;
72   *   &lt;message&gt;<I><B>dynamically built</B></I>&lt;/message&gt;
73   *   &lt;prefix&gt;<I>a string</I>&lt;/prefix&gt;
74   *   &lt;passThrough&gt;true or false&lt;/passThrough&gt;
75   *   &lt;fakeDomainCheck&gt;<I>true or false</I>&lt;/fakeDomainCheck&gt;
76   *   &lt;recipients&gt;<B>sender</B>&lt;/recipients&gt;
77   *   &lt;reversePath&gt;null&lt;/reversePath&gt;
78   *   &lt;inline&gt;see {@link Resend}&lt;/inline&gt;
79   *   &lt;attachment&gt;see {@link Resend}&lt;/attachment&gt;
80   *   &lt;isReply&gt;true&lt;/isReply&gt;
81   *   &lt;debug&gt;<I>true or false</I>&lt;/debug&gt;
82   * &lt;/mailet&gt;
83   * </CODE></PRE>
84   * <P><I>notice</I> and <I>sendingAddress</I> can be used instead of
85   * <I>message</I> and <I>sender</I>; such names are kept for backward compatibility.</P>
86   *
87   * @version CVS $Revision: 426007 $ $Date: 2006-07-27 09:52:06 +0100 (Thu, 27 Jul 2006) $
88   * @since 2.2.0
89   */
90  public class Bounce extends AbstractNotify {
91  
92      /**
93       * Return a string describing this mailet.
94       *
95       * @return a string describing this mailet
96       */
97      public String getMailetInfo() {
98          return "Bounce Mailet";
99      }
100 
101     /** Gets the expected init parameters. */
102     protected  String[] getAllowedInitParameters() {
103         String[] allowedArray = {
104 //            "static",
105             "debug",
106             "passThrough",
107             "fakeDomainCheck",
108             "inline",
109             "attachment",
110             "message",
111             "notice",
112             "sender",
113             "sendingAddress",
114             "prefix",
115             "attachError",
116         };
117         return allowedArray;
118     }
119     
120     /* ******************************************************************** */
121     /* ****************** Begin of getX and setX methods ****************** */
122     /* ******************************************************************** */
123 
124     /**
125      * @return <CODE>SpecialAddress.REVERSE_PATH</CODE>
126      */
127     protected Collection getRecipients() {
128         Collection newRecipients = new HashSet();
129         newRecipients.add(SpecialAddress.REVERSE_PATH);
130         return newRecipients;
131     }
132 
133     /**
134      * @return <CODE>SpecialAddress.REVERSE_PATH</CODE>
135      */
136     protected InternetAddress[] getTo() {
137         InternetAddress[] apparentlyTo = new InternetAddress[1];
138         apparentlyTo[0] = SpecialAddress.REVERSE_PATH.toInternetAddress();
139         return apparentlyTo;
140     }
141 
142     /**
143      * @return <CODE>SpecialAddress.NULL</CODE> (the meaning of bounce)
144      */
145     protected MailAddress getReversePath(Mail originalMail) {
146         return SpecialAddress.NULL;
147     }
148 
149     /* ******************************************************************** */
150     /* ******************* End of getX and setX methods ******************* */
151     /* ******************************************************************** */
152 
153     /**
154      * Service does the hard work,and redirects the originalMail in the form specified.
155      * Checks that the original return path is not empty,
156      * and then calls super.service(originalMail), otherwise just returns.
157      *
158      * @param originalMail the mail to process and redirect
159      * @throws MessagingException if a problem arises formulating the redirected mail
160      */
161     public void service(Mail originalMail) throws MessagingException {
162         if (originalMail.getSender() == null) {
163             if (isDebug)
164                 log("Processing a bounce request for a message with an empty reverse-path.  No bounce will be sent.");
165             if(!getPassThrough(originalMail)) {
166                 originalMail.setState(Mail.GHOST);
167             }
168             return;
169         }
170 
171         if (isDebug)
172             log("Processing a bounce request for a message with a reverse path.  The bounce will be sent to " + originalMail.getSender().toString());
173 
174         super.service(originalMail);
175     }
176 
177 }
178