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 * <mailet match="All" class="Bounce">
54 * <sender><I>an address or postmaster or sender or unaltered, default=postmaster</I></sender>
55 * <attachError><I>true or false, default=false</I></attachError>
56 * <message><I>notice attached to the original message text (optional)</I></message>
57 * <prefix><I>optional subject prefix prepended to the original message</I></prefix>
58 * <inline><I>see {@link Resend}, default=none</I></inline>
59 * <attachment><I>see {@link Resend}, default=message</I></attachment>
60 * <passThrough><I>true or false, default=true</I></passThrough>
61 * <fakeDomainCheck><I>true or false, default=true</I></fakeDomainCheck>
62 * <debug><I>true or false, default=false</I></debug>
63 * </mailet>
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 * <mailet match="All" class="Resend">
70 * <sender><I>an address or postmaster or sender or unaltered</I></sender>
71 * <attachError><I>true or false</I></attachError>
72 * <message><I><B>dynamically built</B></I></message>
73 * <prefix><I>a string</I></prefix>
74 * <passThrough>true or false</passThrough>
75 * <fakeDomainCheck><I>true or false</I></fakeDomainCheck>
76 * <recipients><B>sender</B></recipients>
77 * <reversePath>null</reversePath>
78 * <inline>see {@link Resend}</inline>
79 * <attachment>see {@link Resend}</attachment>
80 * <isReply>true</isReply>
81 * <debug><I>true or false</I></debug>
82 * </mailet>
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