> I hope this time both attachements make the way to you, but 
> I'll doublecheck
again the mailet got lost .. I'll resend it as .java.txt

Andreas
/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache", "Jakarta", "JAMES" and "Apache Software Foundation"
 *    must not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * Portions of this software are based upon public domain software
 * originally written at the National Center for Supercomputing Applications,
 * University of Illinois, Urbana-Champaign.
 */

package org.apache.james.transport.mailets;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.MessagingException;
import javax.mail.SendFailedException;
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 org.apache.james.core.MailImpl;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
import org.apache.mailet.RFC2822Headers;
import org.apache.mailet.dates.RFC822DateFormat;



/**
 *
 * <P>Generates a Delivery Status Notification (DSN)
 * 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>
 * <P>Supports the <CODE>passThrough</CODE> init parameter (true if missing).</P>
 *
 * <P>Sample configuration:</P>
 * <PRE><CODE>
 * &lt;mailet match="All" class="DSNBounce">
 *   &lt;sender&gt;<I>an address or postmaster or sender or unaltered, 
default=postmaster</I>&lt;/sender&gt;
 *   &lt;prefix&gt;<I>optional subject prefix prepended to the original 
message</I>&lt;/prefix&gt;
 *   &lt;attachment&gt;<I>message or none, default=message</I>&lt;/attachment&gt;
 *   &lt;passThrough&gt;<I>true or false, default=true</I>&lt;/passThrough&gt;
 *   &lt;debug&gt;<I>true or false, default=false</I>&lt;/debug&gt;
 * &lt;/mailet&gt;
 * </CODE></PRE>
 *
 *
 * @author Andreas Göggerle <[EMAIL PROTECTED]>
 *
 * @see org.apache.james.transport.mailets.AbstractNotify
 */



public class DSNBounce extends AbstractNotify {

//    /**
//     *
//     * @author Andreas Göggerle <[EMAIL PROTECTED]>
//     */
//
//    public class DSNMessage extends MimeMessage {
//
//      private String type = "";
//
//      public DSNMessage() {
//        super(Session.getDefaultInstance(System.getProperties(), null));
//      }
//
//      public void setContent(Object o, String type) throws MessagingException {
//        this.type = type;
//        super.content = (byte[])o;
//      }
//
//      public void writeContentTo(OutputStream outs)
//         throws java.io.IOException, MessagingException {
//         outs.write(super.content);
//         outs.flush();
//      }
//
//      public void writeTo(OutputStream outs, String as[])
//          throws IOException, MessagingException
//      {
//          outs.write(super.content);
//          outs.flush();
//      }
//
//     }


    /**
     * Constants and getters for RFC 3463 Enhanced Mail System Status Codes
     *
     * I suggest do extract this inner class for future use in the smtp-handler
     *
     * @author Andreas Göggerle <[EMAIL PROTECTED]>
     */
    public static class DSNStatus {
        // status code classes
        /**
         * Success
         */
        public static final int SUCCESS = 2;

        /**
         * Persistent Transient Failure
         */
        public static final int TRANSIENT = 4;

        /**
         * Permanent Failure
         */
        public static final int PERMANENT = 5;

        // subjects and details

        /**
         * Other or Undefined Status
         */
        public static final int UNDEFINED = 0;

        /**
         * Other undefined status
         */
        public static final String UNDEFINED_STATUS = "0.0";

        /**
         * Addressing Status
         */
        public static final int ADDRESS = 1;

        /**
         * Other address status
         */
        public static final String ADDRESS_OTHER = "1.0";

        /**
         * Bad destination mailbox address
         */
        public static final String ADDRESS_MAILBOX = "1.1";

        /**
         * Bad destination system address
         */
        public static final String ADDRESS_SYSTEM = "1.2";

        /**
         * Bad destination mailbox address syntax
         */
        public static final String ADDRESS_SYNTAX = "1.3";

        /**
         * Destination mailbox address ambiguous
         */
        public static final String ADDRESS_AMBIGUOUS = "1.4";

        /**
         * Destination Address valid
         */
        public static final String ADDRESS_VALID = "1.5";

        /**
         * Destimation mailbox has moved, no forwarding address
         */
        public static final String ADDRESS_MOVED = "1.6";

        /**
         * Bad sender's mailbox address syntax
         */
        public static final String ADDRESS_SYNTAX_SENDER = "1.7";

        /**
         * Bad sender's system address
         */
        public static final String ADDRESS_SYSTEM_SENDER = "1.8";


        /**
         * Mailbox Status
         */
        public static final int MAILBOX = 2;

        /**
         * Other or Undefined Mailbox Status
         */
        public static final String MAILBOX_OTHER = "2.0";

        /**
         * Mailbox disabled, not accepting messages
         */
        public static final String MAILBOX_DISABLED = "2.1";

        /**
         * Mailbox full
         */
        public static final String MAILBOX_FULL = "2.2";

        /**
         * Message length exceeds administrative limit
         */
        public static final String MAILBOX_MSG_TOO_BIG = "2.3";

        /**
         * Mailing list expansion problem
         */
        public static final String MAILBOX_LIST_EXPANSION = "2.4";


        /**
         * Mail System Status
         */
        public static final int SYSTEM = 3;

        /**
         * Other or undefined mail system status
         */
        public static final String SYSTEM_OTHER = "3.0";

        /**
         * Mail system full
         */
        public static final String SYSTEM_FULL = "3.1";

        /**
         * System not accepting messages
         */
        public static final String SYSTEM_NOT_ACCEPTING = "3.2";

        /**
         * System not capable of selected features
         */
        public static final String SYSTEM_NOT_CAPABLE = "3.3";

        /**
         * Message too big for system
         */
        public static final String SYSTEM_MSG_TOO_BIG = "3.4";

        /**
         * System incorrectly configured
         */
        public static final String SYSTEM_CFG_ERROR = "3.5";


        /**
         * Network and Routing Status
         */
        public static final int NETWORK = 4;

        /**
         * Other or undefined network or routing status
         */
        public static final String NETWORK_OTHER = "4.0";

        /**
         * No answer form host
         */
        public static final String NETWORK_NO_ANSWER = "4.1";

        /**
         * Bad Connection
         */
        public static final String NETWORK_CONNECTION = "4.2";

        /**
         * Directory server failure
         */
        public static final String NETWORK_DIR_SERVER = "4.3";

        /**
         * Unable to route
         */
        public static final String NETWORK_ROUTE = "4.4";

        /**
         * Mail system congestion
         */
        public static final String NETWORK_CONGESTION = "4.5";

        /**
         * Routing loop detected
         */
        public static final String NETWORK_LOOP = "4.6";

        /**
         * Delivery time expired
         */
        public static final String NETWORK_EXPIRED = "4.7";


        /**
         * Mail Delivery Protocol Status
         */
        public static final int DELIVERY = 5;

        /**
         * Other or undefined (SMTP) protocol status
         */
        public static final String DELIVERY_OTHER = "5.0";

        /**
         * Invalid command
         */
        public static final String DELIVERY_INVALID_CMD = "5.1";

        /**
         * Syntax error
         */
        public static final String DELIVERY_SYNTAX = "5.2";

        /**
         * Too many recipients
         */
        public static final String DELIVERY_TOO_MANY_REC = "5.3";

        /**
         * Invalid command arguments
         */
        public static final String DELIVERY_INVALID_ARG = "5.4";

        /**
         * Wrong protocol version
         */
        public static final String DELIVERY_VERSION = "5.5";


        /**
         * Message Content or Media Status
         */
        public static final int CONTENT = 6;

        /**
         * Other or undefined media error
         */
        public static final String CONTENT_OTHER = "6.0";

        /**
         * Media not supported
         */
        public static final String CONTENT_UNSUPPORTED = "6.1";

        /**
         * Conversion required and prohibited
         */
        public static final String CONTENT_CONVERSION_NOT_ALLOWED = "6.2";

        /**
         * Conversion required, but not supported
         */
        public static final String CONTENT_CONVERSION_NOT_SUPPORTED = "6.3";

        /**
         * Conversion with loss performed
         */
        public static final String CONTENT_CONVERSION_LOSS = "6.4";

        /**
         * Conversion failed
         */
        public static final String CONTENT_CONVERSION_FAILED = "6.5";


        /**
         * Security or Policy Status
         */
        public static final int SECURITY = 7;

        /**
         * Other or undefined security status
         */
        public static final String SECURITY_OTHER = "7.0";

        /**
         * Delivery not authorized, message refused
         */
        public static final String SECURITY_AUTH = "7.1";

        /**
         * Mailing list expansion prohibited
         */
        public static final String SECURITY_LIST_EXP = "7.2";

        /**
         * Security conversion required, but not possible
         */
        public static final String SECURITY_CONVERSION = "7.3";

        /**
         * Security features not supported
         */
        public static final String SECURITY_UNSUPPORTED = "7.4";

        /**
         * Cryptographic failure
         */
        public static final String SECURITY_CRYPT_FAIL = "7.5";

        /**
         * Cryptographic algorithm not supported
         */
        public static final String SECURITY_CRYPT_ALGO = "7.6";

        /**
         * Message integrity failure
         */
        public static final String SECURITY_INTEGRITY = "7.7";


        // get methods

        public static String getStatus(int type, String detail) {
            return type + "." + detail;
        }

        public static String getStatus(int type, int subject, int detail) {
            return type + "." + subject + "." + detail;
        }
    }

    private static final RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();

    //  Used to generate new mail names
    private static final java.util.Random random = new java.util.Random();

    // regexp pattern for scaning status code from exception message
    private static final Pattern statusPattern = 
Pattern.compile(".*\\s*([245]\\.\\d{1,3}\\.\\d{1,3}).*\\s*");




    /**
     * Service does the hard work and bounces the originalMail in the format specified 
by RFC3464.
     *
     * @param originalMail the mail to bounce
     * @throws MessagingException if a problem arises formulating the redirected mail
     *
     * @see org.apache.mailet.Mailet#service(org.apache.mailet.Mail)
     */
    public void service(Mail originalMail) throws MessagingException {


        // duplicates the Mail object, to be able to modify the new mail keeping the 
original untouched
        Mail newMail = ((MailImpl) originalMail).duplicate(newName((MailImpl) 
originalMail));
        // We don't need to use the original Remote Address and Host,
        // and doing so would likely cause a loop with spam detecting
        // matchers.
        try {
            ((MailImpl) 
newMail).setRemoteAddr(java.net.InetAddress.getLocalHost().getHostAddress());
            ((MailImpl) 
newMail).setRemoteHost(java.net.InetAddress.getLocalHost().getHostName());
        } catch (java.net.UnknownHostException _) {
            ((MailImpl) newMail).setRemoteAddr("127.0.0.1");
            ((MailImpl) newMail).setRemoteHost("localhost");
        }
        MailAddress returnAddress = getExistingReturnPath(originalMail);
        Collection newRecipients = new HashSet();
        if (returnAddress == SpecialAddress.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;
        } else if (returnAddress == null) {
            log("WARNING: Mail to be bounced does not contain a reverse-path.");
        } else {
            if (isDebug)
                log("Processing a bounce request for a message with a return path 
header.  The bounce will be sent to " + returnAddress);
        }

        newRecipients.add(returnAddress);
        newMail.setRecipients(newRecipients);

        if (isDebug) {
            MailImpl newMailImpl = (MailImpl) newMail;
            log("New mail - sender: " + newMailImpl.getSender()
                       + ", recipients: " + 
arrayToString(newMailImpl.getRecipients().toArray())
                       + ", name: " + newMailImpl.getName()
                       + ", remoteHost: " + newMailImpl.getRemoteHost()
                       + ", remoteAddr: " + newMailImpl.getRemoteAddr()
                       + ", state: " + newMailImpl.getState()
                       + ", lastUpdated: " + newMailImpl.getLastUpdated()
                       + ", errorMessage: " + newMailImpl.getErrorMessage());
        }

        // create the bounce message
        MimeMessage newMessage = new 
MimeMessage(Session.getDefaultInstance(System.getProperties(), null));
        MimeMultipart multipart = new MimeMultipart("report; 
report-type=delivery-status");

        // part 1: descripive text message
        MimeBodyPart part1 = createTextMsg(originalMail);
        multipart.addBodyPart(part1);

        // part 2: DSN
        MimeBodyPart part2 = createDSN(originalMail);
        multipart.addBodyPart(part2);


        // part 3: original mail (optional)
        if (getAttachmentType() != NONE) {
            MimeBodyPart part3 = createAttachedOriginal(originalMail);
            multipart.addBodyPart(part3);
        }


        // stuffing all together
        newMessage.setContent(multipart);
        newMessage.setHeader(RFC2822Headers.CONTENT_TYPE, multipart.getContentType());
        newMail.setMessage(newMessage);

        //Set additional headers
        setRecipients(newMail, getRecipients(originalMail), originalMail);
        setTo(newMail, getTo(originalMail), originalMail);
        setSubjectPrefix(newMail, getSubjectPrefix(originalMail), originalMail);
        if(newMail.getMessage().getHeader(RFC2822Headers.DATE) == null) {
            newMail.getMessage().setHeader(RFC2822Headers.DATE, 
rfc822DateFormat.format(new Date()));
        }
        setReplyTo(newMail, getReplyTo(originalMail), originalMail);
        setReversePath(newMail, getReversePath(originalMail), originalMail);
        setSender(newMail, getSender(originalMail), originalMail);
        setIsReply(newMail, isReply(originalMail), originalMail);

        newMail.getMessage().saveChanges();
        getMailetContext().sendMail(newMail);

        // ghosting the original mail
        if(!getPassThrough(originalMail)) {
            originalMail.setState(Mail.GHOST);
        }
    }

    /**
     * Create a MimeBodyPart with a textual description for human readers.
     *
     * @param originalMail
     * @return MimeBodyPart
     * @throws MessagingException
     */
    private MimeBodyPart createTextMsg(Mail originalMail)
        throws MessagingException {
        MimeBodyPart part1 = new MimeBodyPart();
        StringWriter sout = new StringWriter();
        PrintWriter out = new PrintWriter(sout, true);
        String machine = "[unknown]";
        try {
            InetAddress me = InetAddress.getLocalHost();
            machine = me.getHostName();
        } catch(Exception e){
            machine = "[address unknown]";
        }
        StringBuffer bounceBuffer =
            new StringBuffer(128)
                    .append("Hi. This is the James mail server at ")
                    .append(machine)
                    .append(".");
        out.println(bounceBuffer.toString());
        out.println("I'm afraid I wasn't able to deliver your message to the following 
addresses.");
        out.println("This is a permanent error; I've given up. Sorry it didn't work 
out.  Below");
        out.println("I include the list of recipients and the reason why I was unable 
to deliver");
        out.println("your message.");
        out.println();
        out.println("Failed recipient(s):");
        for (Iterator i = originalMail.getRecipients().iterator(); i.hasNext(); ) {
            out.println(i.next());
        }
        MessagingException ex = (MessagingException) 
originalMail.getAttribute("delivery-error");
        out.println();
        out.println("Error message:");
        out.println(getErrorMsg(ex));
        out.println();

        part1.setText(sout.toString());
        return part1;
    }

    /**
     * creates the DSN-bodypart for automated processing
     *
     * @param originalMail
     * @return MimeBodyPart dsn-bodypart
     * @throws MessagingException
     */
    private MimeBodyPart createDSN(Mail originalMail) throws MessagingException {
        MimeBodyPart dsn = new MimeBodyPart();
        MimeMessage dsnMessage = new 
MimeMessage(Session.getDefaultInstance(System.getProperties(), null));
        StringWriter sout = new StringWriter();
        PrintWriter out = new PrintWriter(sout, true);
        String errorMsg = null;
        String nameType = null;


        ////////////////////////
        // per message fields //
        ////////////////////////

        //optional: envelope-id
        // TODO: Envelope-Id
        // The Original-Envelope-Id is NOT the same as the Message-Id from the header.
        // The Message-Id identifies the content of the message, while the 
Original-Envelope-ID
        // identifies the transaction in which the message is sent.  (see RFC3461)
        // so do NOT out.println("Original-Envelope-Id: 
"+originalMail.getMessage().getMessageID());


        //required: reporting MTA
        // this is always us, since we do not translate non-internet-mail
        // failure reports into DSNs
        nameType = "dns";
        try {
            String myAddress = InetAddress.getLocalHost().getCanonicalHostName();
            out.println("Reporting-MTA: "+nameType+"; "+myAddress);
        } catch(Exception e){
            // we should always know our address, so we shouldn't get here
            log("WARNING: sending DSN without required Reporting-MTA Address");
        }

        //only for gateways to non-internet mail systems: dsn-gateway

        //optional: received from
        out.println("Received-From-MTA: "+nameType+"; "+originalMail.getRemoteHost());

        //optional: Arrival-Date

        //////////////////////////
        // per recipient fields //
        //////////////////////////

        Iterator recipients = originalMail.getRecipients().iterator();
        while (recipients.hasNext())
        {
            MailAddress rec = (MailAddress)recipients.next();
            String addressType = "rfc822";

            //required: blank line
            out.println();

            //optional: original recipient (see RFC3461)
            //out.println("Original-Recipient: "+addressType+"; "+ ??? );

            //required: final recipient
            out.println("Final-Recipient: "+addressType+"; "+rec.toString());

            //required: action
            // alowed values: failed, delayed, delivered, relayed, expanded
            // TODO: until now, we do error-bounces only
            out.println("Action: failed");

            //required: status
            // get Exception for getting status information
            // TODO: it would be nice if the SMTP-handler would set a status attribute 
we can use here
            MessagingException ex = (MessagingException) 
originalMail.getAttribute("delivery-error");
            out.println("Status: "+getStatus(ex));

            //optional: remote MTA
            //to which MTA were we talking while the Error occured?

            //optional: diagnostic-code
                        String diagnosticType = null;
            // this typically is the return value received during smtp
            // (or other transport) communication
            // and should be stored as attribute by the smtp handler
            // but until now we only have error-messages.
            String diagnosticCode = getErrorMsg(ex);
            // Sometimes this is the smtp diagnostic code,
            // but James often gives us other messages
            Pattern diagPattern = Pattern.compile("^\\d{3}\\s.*$");
            Matcher diagMatcher = diagPattern.matcher(diagnosticCode);
            boolean smtpDiagCodeAvailable = diagMatcher.matches();
            if (smtpDiagCodeAvailable){
                diagnosticType = "smtp";
            } else {
                diagnosticType = "X-James";
            }
                        out.println("Diagnostic-Code: "+diagnosticType+"; 
"+diagnosticCode);

            //optional: last attempt
            out.println("Last-Attempt-Date: 
"+rfc822DateFormat.format(originalMail.getLastUpdated()));

            //optional: retry until
            //only for 'delayed' reports .. but we don't report this (at least until 
now)

            //optional: extension fields

        }


        // setting content
        dsnMessage.setText(sout.toString());
        dsnMessage.saveChanges();
        // TODO: activation doesn't know how to handle the  "message/delivery-status" 
MIME-Type

        //DataHandler dh = new DataHandler(dsnMessage, "message/delivery-status");
        //dsn.setDataHandler(dh);

        //dsn.setContent(dsnMessage, "message/delivery-status");

        dsn.setContent(sout.toString(), "text/plain");
        dsn.setDescription("Delivery Status Notification");
        dsn.setFileName("status.dat");
        return dsn;
    }

    /**
     * Create a MimeBodyPart with the original Mail as Attachment
     *
     * @param originalMail
     * @return MimeBodyPart
     * @throws MessagingException
     */
    private MimeBodyPart createAttachedOriginal(Mail originalMail)
        throws MessagingException {
        MimeBodyPart part = new MimeBodyPart();
        MimeMessage originalMessage = originalMail.getMessage();
        part.setContent(originalMessage, "message/rfc822");
        if ((originalMessage.getSubject() != null) && 
(originalMessage.getSubject().trim().length() > 0)) {
            part.setFileName(originalMessage.getSubject().trim());
        } else {
            part.setFileName("No Subject");
        }
        part.setDisposition("Attachment");
        return part;
    }

    /**
     * Guessing status code by the exception provided.
     * This method should use the status attribute when the
     * SMTP-handler somewhen provides it
     *
     * @param MessagingException
     * @return status code
     */
    private String getStatus(MessagingException me) {
        if (me.getNextException() == null) {
            String mess = me.getMessage();
            Matcher m = statusPattern.matcher(mess);
            StringBuffer sb = new StringBuffer();
            if (m.matches()) {
                sb.append(m.group(1));
                return sb.toString();
            }
            // bad destination system adress
            if (mess.startsWith("There are no DNS entries for the hostname"))
                return DSNStatus.getStatus(DSNStatus.PERMANENT, 
DSNStatus.ADDRESS_SYSTEM);

            // no answer from host (4.4.1) or
            // system not accepting network messages (4.3.2), lets guess ...
            if (mess.equals("No mail server(s) available at this time."))
                return DSNStatus.getStatus(DSNStatus.TRANSIENT, 
DSNStatus.NETWORK_NO_ANSWER);

            // other/unknown error
            return DSNStatus.getStatus(DSNStatus.PERMANENT, 
DSNStatus.UNDEFINED_STATUS);
        } else {
            String retVal = null;
            Exception ex1 = me.getNextException();
            Matcher m = statusPattern.matcher(ex1.getMessage());
            StringBuffer sb = new StringBuffer();
            if (m.matches()) {
                sb.append(m.group(1));
                return sb.toString();
            } else if (ex1 instanceof SendFailedException) {
                // other/undefined protocol status

                // if we get an smtp returncode starting with 4
                // it is an persistent transient error, else permanent
                if (ex1.getMessage().startsWith("4")) {
                    return DSNStatus.getStatus(DSNStatus.TRANSIENT, 
DSNStatus.DELIVERY_OTHER);
                } else return DSNStatus.getStatus(DSNStatus.PERMANENT, 
DSNStatus.DELIVERY_OTHER);
            } else if (ex1 instanceof UnknownHostException) {
                // bad destination system address
                return DSNStatus.getStatus(DSNStatus.PERMANENT, 
DSNStatus.ADDRESS_SYSTEM);
            } else if (ex1 instanceof ConnectException) {
                // bad connection
                return DSNStatus.getStatus(DSNStatus.TRANSIENT, 
DSNStatus.NETWORK_CONNECTION);
            } else if (ex1 instanceof SocketException) {
                // bad connection
                return DSNStatus.getStatus(DSNStatus.TRANSIENT, 
DSNStatus.NETWORK_CONNECTION);
            } else {
                // other/undefined/unknown error
                return DSNStatus.getStatus(DSNStatus.PERMANENT, 
DSNStatus.UNDEFINED_STATUS);
            }
        }
    }

    /**
     * Utility method for getting the error message from the (nested) exception.
     * @param MessagingException
     * @return error message
     */
    private String getErrorMsg(MessagingException me) {
        if (me.getNextException() == null) {
            return me.getMessage().trim();
        } else {
            Exception ex1 = me.getNextException();
            return ex1.getMessage().trim();
        }
    }

    /**
     * Utility method for obtaining a string representation of an array of Objects.
     */
    private String arrayToString(Object[] array) {
        if (array == null) {
            return "null";
        }
        StringBuffer sb = new StringBuffer(1024);
        sb.append("[");
        for (int i = 0; i < array.length; i++) {
            if (i > 0) {
                sb.append(",");
            }
            sb.append(array[i]);
        }
        sb.append("]");
        return sb.toString();
    }

    /**
     * Create a unique new primary key name.
     *
     * @param mail the mail to use as the basis for the new mail name
     * @return a new name
     */
    private String newName(MailImpl mail) throws MessagingException {
        String oldName = mail.getName();

        // Checking if the original mail name is too long, perhaps because of a
        // loop caused by a configuration error.
        // it could cause a "null pointer exception" in AvalonMailRepository much
        // harder to understand.
        if (oldName.length() > 76) {
            int count = 0;
            int index = 0;
            while ((index = oldName.indexOf('!', index + 1)) >= 0) {
                count++;
            }
            // It looks like a configuration loop. It's better to stop.
            if (count > 7) {
                throw new MessagingException("Unable to create a new message name: too 
long."
                                             + " Possible loop in config.xml.");
            }
            else {
                oldName = oldName.substring(0, 76);
            }
        }

        StringBuffer nameBuffer =
                                 new StringBuffer(64)
                                 .append(oldName)
                                 .append("-!")
                                 .append(random.nextInt(1048576));
        return nameBuffer.toString();
    }



    public String getMailetInfo() {
        return "DSNBounce Mailet";
    }
    /* ******************************************************************** */
    /* ****************** Begin of getX and setX methods ****************** */
    /* ******************************************************************** */

    /** Gets the expected init parameters.  */
    protected  String[] getAllowedInitParameters() {
        String[] allowedArray = {
            "debug",
            "passThrough",
            "attachment",
            "sender",
            "prefix"
        };
        return allowedArray;
    }

    /**
     * @return the <CODE>attachment</CODE> init parameter, or <CODE>MESSAGE</CODE> if 
missing
     */
    protected int getAttachmentType() throws MessagingException {
        if(getInitParameter("attachment") == null) {
            return MESSAGE;
        } else {
            return getTypeCode(getInitParameter("attachment"));
        }
    }


    /**
     * @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 ******************* */
    /* ******************************************************************** */

}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to