vincenzo    2003/06/30 02:42:08

  Modified:    src/java/org/apache/james/transport/mailets Tag:
                        branch_2_1_fcs AbstractNotify.java
                        AbstractRedirect.java Bounce.java Forward.java
                        GenericListserv.java NotifyPostmaster.java
                        NotifySender.java Redirect.java Resend.java
  Log:
  AbstractRedirect hierarchy:
  
  1) Enhancement and cleanup in default parameter management.
  2) Throws MessagingException instead of log in case of address parsing errors.
  3) Was not copying default headers in case of inline != unaltered - major fix.
  4) Redirect supports <subject>.
  4) Applied Hontvari Joszef's patch for supporting non-ascii characters (involves 
also GenericListserv).
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.8   +4 -4      
jakarta-james/src/java/org/apache/james/transport/mailets/AbstractNotify.java
  
  Index: AbstractNotify.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/AbstractNotify.java,v
  retrieving revision 1.1.2.7
  retrieving revision 1.1.2.8
  diff -u -r1.1.2.7 -r1.1.2.8
  --- AbstractNotify.java       27 Jun 2003 14:34:37 -0000      1.1.2.7
  +++ AbstractNotify.java       30 Jun 2003 09:42:07 -0000      1.1.2.8
  @@ -258,10 +258,10 @@
       }
   
       /**
  -     * @return null
  +     * @return [EMAIL PROTECTED] AbstractRedirect#getSender(Mail)}, meaning the new 
requested sender if any
        */
  -    protected MailAddress getReturnPath() throws MessagingException {
  -        return null;
  +    protected MailAddress getReturnPath(Mail originalMail) throws 
MessagingException {
  +        return getSender(originalMail);
       }
   
       /**
  
  
  
  1.1.2.14  +169 -114  
jakarta-james/src/java/org/apache/james/transport/mailets/AbstractRedirect.java
  
  Index: AbstractRedirect.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/AbstractRedirect.java,v
  retrieving revision 1.1.2.13
  retrieving revision 1.1.2.14
  diff -u -r1.1.2.13 -r1.1.2.14
  --- AbstractRedirect.java     27 Jun 2003 14:34:37 -0000      1.1.2.13
  +++ AbstractRedirect.java     30 Jun 2003 09:42:07 -0000      1.1.2.14
  @@ -464,10 +464,12 @@
   
           StringTokenizer st = new StringTokenizer(addressList, ",", false);
           while(st.hasMoreTokens()) {
  +            String token = null;
               try {
  -                newRecipients.add(new MailAddress(st.nextToken()));
  +                token = st.nextToken();
  +                newRecipients.add(new MailAddress(token));
               } catch(Exception e) {
  -                log("add recipient failed in getRecipients");
  +                throw new MessagingException("Exception thrown in getRecipients() 
parsing: " + token, e);
               }
           }
           return newRecipients;
  @@ -480,12 +482,13 @@
        *
        * @return [EMAIL PROTECTED] #getRecipients()},
        * replacing <CODE>SpecialAddress.SENDER</CODE> if applicable with the original 
sender
  -     * and <CODE>SpecialAddress.UNALTERED</CODE> if applicable with null
  +     * and <CODE>SpecialAddress.UNALTERED</CODE>
  +     * and <CODE>SpecialAddress.RECIPIENTS</CODE> if applicable with null
        */
       protected Collection getRecipients(Mail originalMail) throws MessagingException 
{
           Collection recipients = (isStatic()) ? this.recipients : getRecipients();
           if (recipients != null && recipients.size() == 1) {
  -            if (recipients.contains(SpecialAddress.UNALTERED)) {
  +            if (recipients.contains(SpecialAddress.UNALTERED) || 
recipients.contains(SpecialAddress.RECIPIENTS)) {
                   recipients = null;
               } else if (recipients.contains(SpecialAddress.SENDER)) {
                   recipients = new ArrayList();
  @@ -558,7 +561,7 @@
                   tokenx     = rec.nextToken();
                   iaarray[i] = new InternetAddress(tokenx);
               } catch(Exception e) {
  -                log("Internet address exception in getTo()");
  +                throw new MessagingException("Exception thrown in getTo() parsing: 
" + tokenx, e);
               }
           }
           return iaarray;
  @@ -583,6 +586,7 @@
        *      </LI>
        *      <LI>
        *          If <CODE>getTo()</CODE> returns 
<CODE>SpecialAddress.UNALTERED</CODE>
  +     *                                          or <CODE>SpecialAddress.TO</CODE>
        *          it returns the original <I>TO:</I>.
        *      </LI>
        *      <LI>
  @@ -595,7 +599,9 @@
        * </UL>
        *
        * @return [EMAIL PROTECTED] #getTo()}, replacing 
<CODE>SpecialAddress.SENDER</CODE>,
  -     * <CODE>SpecialAddress.SENDER</CODE> and <CODE>SpecialAddress.UNALTERED</CODE> 
if applicable
  +     * <CODE>SpecialAddress.SENDER</CODE>,
  +     * <CODE>SpecialAddress.TO</CODE>,
  +     * and <CODE>SpecialAddress.UNALTERED</CODE> if applicable
        */
       protected InternetAddress[] getTo(Mail originalMail) throws MessagingException {
           InternetAddress[] apparentlyTo = (isStatic()) ? this.apparentlyTo : getTo();
  @@ -618,7 +624,8 @@
                       apparentlyTo = new InternetAddress[1];
                       apparentlyTo[0] = mailAddress.toInternetAddress();
                   }
  -            } else if 
(apparentlyTo[0].equals(SpecialAddress.UNALTERED.toInternetAddress())) {
  +            } else if 
(apparentlyTo[0].equals(SpecialAddress.UNALTERED.toInternetAddress())
  +                       || 
apparentlyTo[0].equals(SpecialAddress.TO.toInternetAddress())) {
                   apparentlyTo = (InternetAddress[]) 
originalMail.getMessage().getRecipients(Message.RecipientType.TO);
               } else if 
(apparentlyTo[0].equals(SpecialAddress.RETURN_PATH.toInternetAddress())) {
                   MailAddress mailAddress = getExistingReturnPath(originalMail);
  @@ -683,7 +690,7 @@
               try {
                   return new MailAddress(addressString);
               } catch(Exception e) {
  -                log("Parse error in getReplyTo: " + addressString);
  +                throw new MessagingException("Exception thrown in getReplyTo() 
parsing: " + addressString, e);
               }
           }
   
  @@ -697,12 +704,15 @@
        *
        * @return [EMAIL PROTECTED] #getReplyTo()}
        * replacing <CODE>SpecialAddress.UNALTERED</CODE> if applicable with null
  +     * and <CODE>SpecialAddress.SENDER</CODE> with the original mail sender
        */
       protected MailAddress getReplyTo(Mail originalMail) throws MessagingException {
           MailAddress replyTo = (isStatic()) ? this.replyTo : getReplyTo();
           if (replyTo != null) {
               if (replyTo == SpecialAddress.UNALTERED) {
                   replyTo = null;
  +            } else if (replyTo == SpecialAddress.SENDER) {
  +                replyTo = originalMail.getSender();
               }
           }
           return replyTo;
  @@ -710,25 +720,12 @@
   
       /**
        * <P>Sets the "Reply-To:" header of <I>newMail</I> to <I>replyTo</I>.</P>
  -     * <P>If the requested value is <CODE>SpecialAddress.SENDER</CODE> will use the 
original "From:" header;
  -     * if this header is empty will use the original "Sender:" header;
  -     * if this header is empty will use the original sender.
        * If the requested value is <CODE>SpecialAddress.NULL</CODE> will remove the 
"Reply-To:" header.
        * If the requested value is null does nothing.</P>
        * Is a "setX(Mail, Tx, Mail)" method.
        */
       protected void setReplyTo(Mail newMail, MailAddress replyTo, Mail originalMail) 
throws MessagingException {
           if(replyTo != null) {
  -            if (replyTo == SpecialAddress.SENDER) {
  -                replyTo = getSafeApparentSender(originalMail);
  -
  -                // if still null give up.
  -                if (replyTo == null) {
  -                    return;
  -                }
  -            }
  -            
  -            // do the job
               InternetAddress[] iart = null;
               if (replyTo != SpecialAddress.NULL) {
                   iart = new InternetAddress[1];
  @@ -769,7 +766,7 @@
               try {
                   return new MailAddress(addressString);
               } catch(Exception e) {
  -                log("Parse error in getReturnPath: " + addressString);
  +                throw new MessagingException("Exception thrown in getReturnPath() 
parsing: " + addressString, e);
               }
           }
   
  @@ -783,13 +780,15 @@
        *
        * @return [EMAIL PROTECTED] #getReturnPath()},
        * replacing <CODE>SpecialAddress.SENDER</CODE> if applicable with the original 
sender,
  -     * replacing <CODE>SpecialAddress.UNALTERED</CODE> if applicable with null,
  +     * replacing <CODE>SpecialAddress.UNALTERED</CODE>
  +     * and <CODE>SpecialAddress.UNALTERED</CODE> if applicable with null,
        * but not replacing <CODE>SpecialAddress.NULL</CODE>
  +     * that will be handled by [EMAIL PROTECTED] #setReturnPath}
        */
       protected MailAddress getReturnPath(Mail originalMail) throws 
MessagingException {
           MailAddress returnPath = (isStatic()) ? this.returnPath : getReturnPath();
           if (returnPath != null) {
  -            if (returnPath == SpecialAddress.UNALTERED) {
  +            if (returnPath == SpecialAddress.UNALTERED || returnPath == 
SpecialAddress.RETURN_PATH) {
                   returnPath = null;
               }
               else if (returnPath == SpecialAddress.SENDER) {
  @@ -844,7 +843,7 @@
               try {
                   return new MailAddress(addressString);
               } catch(Exception e) {
  -                log("Parse error in getSender: " + addressString);
  +                throw new MessagingException("Exception thrown in getSender() 
parsing: " + addressString, e);
               }
           }
   
  @@ -857,12 +856,13 @@
        * Is a "getX(Mail)" method.
        *
        * @return [EMAIL PROTECTED] #getSender()}
  -     * replacing <CODE>SpecialAddress.UNALTERED</CODE> if applicable with null
  +     * replacing <CODE>SpecialAddress.UNALTERED</CODE>
  +     * and <CODE>SpecialAddress.SENDER</CODE> if applicable with null
        */
       protected MailAddress getSender(Mail originalMail) throws MessagingException {
           MailAddress sender = (isStatic()) ? this.sender : getSender();
           if (sender != null) {
  -            if (sender == SpecialAddress.UNALTERED) {
  +            if (sender == SpecialAddress.UNALTERED || sender == 
SpecialAddress.SENDER) {
                   sender = null;
               }
           }
  @@ -870,35 +870,14 @@
       }
   
       /**
  -     * <P>Sets the sender and the "From:" header of <I>newMail</I> to 
<I>sender</I>.</P>
  -     * <P>If the requested value is <CODE>SpecialAddress.SENDER</CODE> will use the 
original "From:" header;
  -     * if this header is empty will use the original "Sender:" header;
  -     * if this header is empty will use the original sender.
  -     * If the requested value is null does nothing.</P>
  +     * Sets the sender and the "From:" header of <I>newMail</I> to <I>sender</I>.
  +     * If the requested value is null does nothing.
        * Is a "setX(Mail, Tx, Mail)" method.
        */
       protected void setSender(Mail newMail, MailAddress sender, Mail originalMail) 
throws MessagingException {
           if (sender != null) {
  -            if (sender == SpecialAddress.SENDER) {
  -                MailAddress newSender = getSafeApparentSender(originalMail);
  -                String newFromHeader = getSafeFromHeader(originalMail);
  -                
  -                if (!newFromHeader.trim().equals("")) {
  -                    newMail.getMessage().setHeader(RFC2822Headers.FROM, 
newFromHeader);
  -                }
  -                
  -                if (newSender != null) {
  -                    ((MailImpl) newMail).setSender(newSender);
  -                }
  -                
  -                // The new code should be compatible with and extend the previous 
code:
  -//                MailAddress originalSender = new MailAddress(((InternetAddress) 
originalMail.getMessage().getFrom()[0]).getAddress());
  -//                newMail.getMessage().setHeader(RFC2822Headers.FROM, 
originalMail.getMessage().getHeader(RFC2822Headers.FROM, ","));
  -//                ((MailImpl) newMail).setSender(originalSender);
  -            } else {
  -                newMail.getMessage().setFrom(sender.toInternetAddress());
  -                ((MailImpl) newMail).setSender(sender);
  -            }
  +            newMail.getMessage().setFrom(sender.toInternetAddress());
  +            ((MailImpl) newMail).setSender(sender);
               
               if (isDebug) {
                   log("sender set to: " + sender);
  @@ -907,44 +886,6 @@
       }
       
       /**
  -     * <P>Gets a safe "apparent" sender using the original "From:" header if 
possible.</P>
  -     * <P>Will use the original "From:" header;
  -     * if this header is empty will use the original "Sender:" header;
  -     * if this header is empty will use the original sender.</P>
  -     */
  -    private MailAddress getSafeApparentSender(Mail originalMail) throws 
MessagingException {
  -        MailAddress sender = null;
  -        InternetAddress from = (InternetAddress) 
originalMail.getMessage().getFrom()[0];
  -        
  -        if (from == null) {
  -            // perhaps this is redundant, but just in case ...
  -            from = originalMail.getSender().toInternetAddress();
  -        }
  -        if (from != null) {
  -            sender = new MailAddress(from.getAddress());
  -        }
  -        
  -        return sender;
  -    }
  -
  -    /**
  -     * <P>Gets a safe "From:" header using the original if possible.</P>
  -     * <P>Will use the original "From:" header;
  -     * if this header is empty will use the original "Sender:" header;
  -     * if this header is empty will use the original sender.</P>
  -     */
  -    private String getSafeFromHeader(Mail originalMail) throws MessagingException {
  -        MailAddress sender = getSafeApparentSender(originalMail);
  -        String fromHeader = 
originalMail.getMessage().getHeader(RFC2822Headers.FROM, ",");
  -        
  -        if (fromHeader.trim().equals("") && sender != null) {
  -            fromHeader = sender.toInternetAddress().toString();
  -        }
  -
  -        return fromHeader;
  -    }
  -
  -    /**
        * Gets the <CODE>subject</CODE> property.
        * Returns a string for the new message subject.
        * Is a "getX()" method.
  @@ -980,7 +921,7 @@
        */
       protected String getSubjectPrefix() throws MessagingException {
           if(getInitParameter("prefix") == null) {
  -            return "";
  +            return null;
           } else {
               return getInitParameter("prefix");
           }
  @@ -1001,18 +942,33 @@
       /**
        * Builds the subject of <I>newMail</I> appending the subject
        * of <I>originalMail</I> to <I>subjectPrefix</I>.
  +     * Is a "setX(Mail, Tx, Mail)" method.
        */
       protected void setSubjectPrefix(Mail newMail, String subjectPrefix, Mail 
originalMail) throws MessagingException {
           String subject = getSubject(originalMail);
  -        if (subject == null) {
  -            subject = originalMail.getMessage().getSubject();
  -        }
  -        if (subject == null) {
  -            subject = "";
  -        }
  -        newMail.getMessage().setSubject(subjectPrefix + subject);
  -        if (isDebug) {
  -            log("subjectPrefix set to: " + subjectPrefix);
  +        if ((subjectPrefix != null && subjectPrefix.length() > 0) || subject != 
null) {
  +            if (subject == null) {
  +                subject = originalMail.getMessage().getSubject();
  +            } else {
  +                // replacing the subject
  +                if (isDebug) {
  +                    log("subject set to: " + subject);
  +                }
  +            }
  +            // Was null in original?
  +            if (subject == null) {
  +                subject = "";
  +            }
  +            
  +            if (subjectPrefix != null) {
  +                subject = subjectPrefix + subject;
  +                // adding a prefix
  +                if (isDebug) {
  +                    log("subjectPrefix set to: " + subjectPrefix);
  +                }
  +            }
  +//            newMail.getMessage().setSubject(subject);
  +            changeSubject(newMail.getMessage(), subject);
           }
       }
   
  @@ -1194,8 +1150,6 @@
               // handle the new message if altered
               buildAlteredMessage(newMail, originalMail);
   
  -            setTo(newMail, getTo(originalMail), originalMail);
  -
           } else {
               // if we need the original, create a copy of this message to redirect
               if (getPassThrough(originalMail)) {
  @@ -1218,6 +1172,8 @@
   
           setRecipients(newMail, getRecipients(originalMail), originalMail);
   
  +        setTo(newMail, getTo(originalMail), originalMail);
  +
           setSubjectPrefix(newMail, getSubjectPrefix(originalMail), originalMail);
   
           if(newMail.getMessage().getHeader(RFC2822Headers.DATE) == null) {
  @@ -1248,9 +1204,9 @@
                                       .append(((MailImpl) originalMail).getName())
                                       .append(". Invalid sender domain for ")
                                       .append(newMail.getSender())
  -                                    .append(". Consider using the Redirect mailet ")
  +                                    .append(". Consider using the Resend mailet ")
                                       .append("using a different sender.");
  -            log(logBuffer.toString());
  +            throw new MessagingException(logBuffer.toString());
           }
   
           if(!getPassThrough(originalMail)) {
  @@ -1330,7 +1286,7 @@
        * Gets the MailAddress corresponding to the existing "Return-Path" header of
        * <I>mail</I>.
        * If empty returns <CODE>SpecialAddress.NULL</CODE>,
  -     * if missing return <CODE>SpecialAddress.SENDER</CODE>.
  +     * if missing return <CODE>null</CODE>.
        */
       protected MailAddress getExistingReturnPath(Mail mail) throws 
MessagingException {
           MailAddress mailAddress = null;
  @@ -1467,11 +1423,25 @@
        */
       protected void buildAlteredMessage(Mail newMail, Mail originalMail) throws 
MessagingException {
   
  -        MimeMessage message = originalMail.getMessage();
  +        MimeMessage originalMessage = originalMail.getMessage();
  +        MimeMessage newMessage = newMail.getMessage();
  +
  +        // Copy the relevant headers
  +        String[] relevantHeaderNames =
  +            {RFC2822Headers.DATE,
  +             RFC2822Headers.FROM,
  +             RFC2822Headers.REPLY_TO,
  +             RFC2822Headers.TO,
  +             RFC2822Headers.SUBJECT,
  +             RFC2822Headers.RETURN_PATH};
  +        Enumeration headerEnum = 
originalMessage.getMatchingHeaderLines(relevantHeaderNames);
  +        while (headerEnum.hasMoreElements()) {
  +            newMessage.addHeaderLine((String) headerEnum.nextElement());
  +        }
   
           StringWriter sout = new StringWriter();
           PrintWriter out   = new PrintWriter(sout, true);
  -        String head = getMessageHeaders(message);
  +        String head = getMessageHeaders(originalMessage);
           boolean all = false;
   
           String messageText = getMessage(originalMail);
  @@ -1494,7 +1464,7 @@
               case BODY: //BODY:
                   out.println("Message:");
                   try {
  -                    out.println(getMessageBody(message));
  +                    out.println(getMessageBody(originalMessage));
                   } catch(Exception e) {
                       out.println("body unavailable");
                   }
  @@ -1530,7 +1500,7 @@
                           break;
                       case BODY: //BODY:
                           try {
  -                            part.setText(getMessageBody(message));
  +                            part.setText(getMessageBody(originalMessage));
                           } catch(Exception e) {
                               part.setText("body unavailable");
                           }
  @@ -1540,15 +1510,15 @@
                               new StringBuffer(1024)
                                   .append(head)
                                   .append("\r\nMessage:\r\n")
  -                                .append(getMessageBody(message));
  +                                .append(getMessageBody(originalMessage));
                           part.setText(textBuffer.toString());
                           break;
                       case MESSAGE: //MESSAGE:
  -                        part.setContent(message, "message/rfc822");
  +                        part.setContent(originalMessage, "message/rfc822");
                           break;
                   }
  -                if ((message.getSubject() != null) && 
(message.getSubject().trim().length() > 0)) {
  -                    part.setFileName(message.getSubject().trim());
  +                if ((originalMessage.getSubject() != null) && 
(originalMessage.getSubject().trim().length() > 0)) {
  +                    part.setFileName(originalMessage.getSubject().trim());
                   } else {
                       part.setFileName("No Subject");
                   }
  @@ -1703,6 +1673,91 @@
               throw new MessagingException("Unexpected init parameters found: "
                                            + arrayToString(bad.toArray()));
           }
  +    }
  +
  +    /**
  +     * It changes the subject of the supplied message to to supplied value 
  +     * but it also tries to preserve the original charset information.
  +     * 
  +     * This method was needed to avoid sending the subject using a charset
  +     * (usually the default charset on the server) which doesn't contain
  +     * the characters in the subject, resulting in the loss of these characters. 
  +     * The most simple method would be to either send it in ASCII unencoded 
  +     * or in UTF-8 if non-ASCII characters are present but unfortunately UTF-8 
  +     * is not yet a MIME standard and not all email clients 
  +     * are supporting it. The optimal method would be to determine the best 
  +     * charset by analyzing the actual characters. That would require much 
  +     * more work (exept if an open source library already exists for this). 
  +     * However there is nothing to stop somebody to add a detection algorithm
  +     * for a specific charset. 
  +     * 
  +     * The current algorithm works correctly if only ASCII characters are 
  +     * added to an existing subject.
  +     * 
  +     * If the new value is ASCII only, then it doesn't apply any encoding to
  +     * the subject header. (This is provided by MimeMessage.setSubject()).
  +     * 
  +     * Possible enhancement:  under java 1.4 java.nio the system can determine if 
the
  +     * suggested charset fits or not (if there is untranslatable
  +     * characters). If the charset doesn't fit the new value, it
  +     * can fall back to UTF-8.
  +     * 
  +     * @param message the message of which subject is changed 
  +     * @param newValue the new (unencoded) value of the subject. It must
  +     *   not be null.
  +     * @throws MessagingException - according to the JavaMail doc most likely
  +     *    this is never thrown
  +     */
  +    public static void changeSubject(MimeMessage message, String newValue)
  +            throws MessagingException
  +    {
  +        String rawSubject = message.getHeader(RFC2822Headers.SUBJECT, null);
  +        String mimeCharset = determineMailHeaderEncodingCharset(rawSubject);
  +        if (mimeCharset == null) { // most likely ASCII
  +            // it uses the system charset or the value of the
  +            // mail.mime.charset property if set  
  +            message.setSubject(newValue);
  +            return;
  +        } else { // original charset determined 
  +            String javaCharset = 
javax.mail.internet.MimeUtility.javaCharset(mimeCharset);
  +            try {
  +                message.setSubject(newValue, javaCharset);
  +            } catch (MessagingException e) {
  +                // known, but unsupported encoding
  +                // this should be logged, the admin may setup a more i18n
  +                // capable JRE, but the log API cannot be accessed from here  
  +                //if (charset != null) log(charset + 
  +                //      " charset unsupported by the JRE, email subject may be 
damaged");
  +                message.setSubject(newValue); // recover
  +            }
  +        }
  +    }
  +     
  +    /**
  +     * It attempts to determine the charset used to encode an "unstructured" 
  +     * RFC 822 header (like Subject). The encoding is specified in RFC 2047.
  +     * If it cannot determine or the the text is not encoded then it returns null.
  +     *
  +     * Here is an example raw text: 
  +     * Subject: =?iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel?=
  +     *
  +     * @param rawText the raw (not decoded) value of the header
  +     * @return the MIME charset name or null if no encoding applied
  +     */
  +    static private String determineMailHeaderEncodingCharset(String rawText)
  +    {
  +        int iEncodingPrefix = rawText.indexOf("=?");
  +        if (iEncodingPrefix == -1) return null;
  +        int iCharsetBegin = iEncodingPrefix + 2; 
  +        int iSecondQuestionMark = rawText.indexOf('?', iCharsetBegin);
  +        if (iSecondQuestionMark == -1) return null;
  +        // safety checks
  +        if (iSecondQuestionMark == iCharsetBegin) return null; // empty charset? 
impossible
  +        int iThirdQuestionMark = rawText.indexOf('?', iSecondQuestionMark + 1);
  +        if (iThirdQuestionMark == -1) return null; // there must be one after 
encoding
  +        if (-1 == rawText.indexOf("?=", iThirdQuestionMark + 1)) return null; // 
closing tag
  +        String mimeCharset = rawText.substring(iCharsetBegin, iSecondQuestionMark);
  +        return mimeCharset;
       }
   
   }
  
  
  
  1.1.2.8   +8 -4      
jakarta-james/src/java/org/apache/james/transport/mailets/Bounce.java
  
  Index: Bounce.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/Bounce.java,v
  retrieving revision 1.1.2.7
  retrieving revision 1.1.2.8
  diff -u -r1.1.2.7 -r1.1.2.8
  --- Bounce.java       27 Jun 2003 14:34:37 -0000      1.1.2.7
  +++ Bounce.java       30 Jun 2003 09:42:07 -0000      1.1.2.8
  @@ -133,7 +133,7 @@
    *   &lt;debug&gt;<I>true or false</I>&lt;/debug&gt;
    * &lt;/mailet&gt;
    * </CODE></PRE>
  - * <P><I>notice</I>, <I>senderAddress</I> and <I>attachStackTrace</I> can be used 
instead of
  + * <P><I>notice</I>, <I>sendingAddress</I> and <I>attachStackTrace</I> can be used 
instead of
    * <I><I>message</I>, <I>sender</I> and <I>attachError</I>; such names are kept for 
backward compatibility.</P>
    *
    * @version CVS $Revision$ $Date$
  @@ -161,6 +161,7 @@
               "attachment",
               "message",
               "notice",
  +            "sender",
               "sendingAddress",
               "prefix",
               "attachError",
  @@ -194,7 +195,7 @@
       /**
        * @return <CODE>SpecialAddress.NULL</CODE> (the meaning of bounce)
        */
  -    protected MailAddress getReturnPath() {
  +    protected MailAddress getReturnPath(Mail originalMail) {
           return SpecialAddress.NULL;
       }
   
  @@ -215,8 +216,11 @@
           if (returnAddress == SpecialAddress.NULL) {
               if (isDebug)
                   log("Processing a bounce request for a message with an empty return 
path.  No bounce will be sent.");
  +            if(!getPassThrough(originalMail)) {
  +                originalMail.setState(Mail.GHOST);
  +            }
               return;
  -        } else if (returnAddress == SpecialAddress.SENDER) {
  +        } else if (returnAddress == null) {
               log("WARNING: Mail to be bounced does not contain a Return-Path 
header.");
           } else {
               if (isDebug)
  
  
  
  1.6.4.9   +2 -2      
jakarta-james/src/java/org/apache/james/transport/mailets/Forward.java
  
  Index: Forward.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/Forward.java,v
  retrieving revision 1.6.4.8
  retrieving revision 1.6.4.9
  diff -u -r1.6.4.8 -r1.6.4.9
  --- Forward.java      27 Jun 2003 14:34:37 -0000      1.6.4.8
  +++ Forward.java      30 Jun 2003 09:42:07 -0000      1.6.4.9
  @@ -204,7 +204,7 @@
        * @return ""
        */
       protected String getSubjectPrefix() throws MessagingException {
  -        return "";
  +        return null;
       }
   
       /**
  
  
  
  1.12.4.6  +1 -94     
jakarta-james/src/java/org/apache/james/transport/mailets/GenericListserv.java
  
  Index: GenericListserv.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/GenericListserv.java,v
  retrieving revision 1.12.4.5
  retrieving revision 1.12.4.6
  diff -u -r1.12.4.5 -r1.12.4.6
  --- GenericListserv.java      29 May 2003 20:31:17 -0000      1.12.4.5
  +++ GenericListserv.java      30 Jun 2003 09:42:07 -0000      1.12.4.6
  @@ -196,90 +196,6 @@
   
           return subject.toString();
       }
  -
  -    /**
  -     * It attempts to determine the charset used to encode an "unstructured" 
  -     * RFC 822 header (like Subject). The encoding is specified in RFC 2047.
  -     * If it cannot determine or the the text is not encoded then it returns null.
  -     *
  -     * Under Java 1.4 it further checks if the encoding is supported under the
  -     * current runtime environment.
  -     * 
  -     * In some cases it returns UTF-8 as a fallback charset. This is not 
  -     * an official MIME standard yet, and most importantly not all email client
  -     * support it, but it is likely better then the server default. 
  -     *
  -     * Here is an example raw text: 
  -     * Subject: =?iso-8859-2?Q?leg=FAjabb_pr=F3ba_l=F5elemmel?=
  -     *
  -     * Possible enhancement:  under java 1.4 java.nio the system can determine if 
the
  -     * suggested charset fits or not (if there is untranslatable
  -     * characters). If the charset doesn't fit the new value, it
  -     * can fall back to UTF-8.
  -     *
  -     * @param rawText the raw (not decoded) value of the header
  -     * @return the java charset name or null if no encoding applied
  -     */
  -    static private String determineMailHeaderEncodingCharset(String rawText)
  -    {
  -        int iEncodingPrefix = rawText.indexOf("=?");
  -        if (iEncodingPrefix == -1) return null;
  -        int iCharsetBegin = iEncodingPrefix + 2; 
  -        int iSecondQuestionMark = rawText.indexOf('?', iCharsetBegin);
  -        if (iSecondQuestionMark == -1) return null;
  -        // safety checks
  -        if (iSecondQuestionMark == iCharsetBegin) return null; // empty charset? 
impossible
  -        int iThirdQuestionMark = rawText.indexOf('?', iSecondQuestionMark + 1);
  -        if (iThirdQuestionMark == -1) return null; // there must be one after 
encoding
  -        if (-1 == rawText.indexOf("?=", iThirdQuestionMark + 1)) return null; // 
closing tag
  -        
  -        String mimeCharset = rawText.substring(iCharsetBegin, iSecondQuestionMark);
  -        String javaCharset = 
javax.mail.internet.MimeUtility.javaCharset(mimeCharset);
  -        
  -        // using reflection for a JRE 1.4 function
  -        if (charsetIsSupportedMethod == null) return javaCharset; // pre 1.4 runtime
  -
  -        try {
  -            String[] arguments = { javaCharset };
  -            Boolean isSupported = (Boolean)charsetIsSupportedMethod.invoke(null, 
arguments);
  -            if (isSupported.booleanValue()) 
  -                return javaCharset;
  -            else 
  -                // UTF-8 must be supported by every JRE, and it is better then 
server default,
  -                // even if a few clients don't support it yet.
  -                // I use UTF-8 instead of UTF8 because there is no java-MIME 
mapping,
  -                // and official MIME code yet, so this will be directly used as a 
MIME
  -                // code, and it is the quasi-standard MIME code (OE uses this).
  -                return "UTF-8"; 
  -        } catch (java.lang.reflect.InvocationTargetException e) {
  -            // it was thrown by Charset.isSupported, illegal charset name
  -            return "UTF-8"; 
  -        } catch (Exception e) {
  -            // impossible
  -            return javaCharset; 
  -        }
  -    }
  -    
  -    /** 
  -     * JRE 1.4 specific method, java.nio.charset.Charset.isSupported(String).
  -     * This field is initialized by the static initialization block and
  -     * is used by the determineMailHeaderEncodingCharset method.
  -     * James doesn't require JRE 1.4 so we must use reflection.
  -     */
  -    static private java.lang.reflect.Method charsetIsSupportedMethod;
  -    
  -    /**
  -     * class initialization, it initializes the charsetIsSupportedMethod member
  -     */
  -    static {
  -        try {
  -            Class charsetClass = Class.forName("java.nio.charset.Charset");
  -            Class[] parameterTypes = { String.class };
  -            charsetIsSupportedMethod = charsetClass.getMethod("isSupported", 
parameterTypes);
  -        } catch (Exception e) {
  -            charsetIsSupportedMethod = null; // pre 1.4 runtime
  -        }
  -    }
       
       /**
        * Processes the message.  Assumes it is the only recipient of this forked 
message.
  @@ -334,21 +250,12 @@
                               .append("] ");
                       prefix = prefixBuffer.toString();
                   }
  -                String rawSubject = message.getHeader(RFC2822Headers.SUBJECT, null);
  -                String charset = determineMailHeaderEncodingCharset(rawSubject);
                   String subj = message.getSubject();
                   if (subj == null) {
                       subj = "";
                   }
                   subj = normalizeSubject(subj, prefix);
  -                try {
  -                    message.setSubject(subj, charset);
  -                } catch (MessagingException e) {
  -                    // known, but unsupported encoding
  -                    if (charset != null) log(charset + 
  -                            " charset unsupported by the JRE, email subject may be 
damaged");
  -                    message.setSubject(subj); // recover
  -                }
  +                AbstractRedirect.changeSubject(message, subj);
               }
   
               //If replies should go to this list, we need to set the header
  
  
  
  1.9.4.10  +3 -2      
jakarta-james/src/java/org/apache/james/transport/mailets/NotifyPostmaster.java
  
  Index: NotifyPostmaster.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/NotifyPostmaster.java,v
  retrieving revision 1.9.4.9
  retrieving revision 1.9.4.10
  diff -u -r1.9.4.9 -r1.9.4.10
  --- NotifyPostmaster.java     27 Jun 2003 14:34:37 -0000      1.9.4.9
  +++ NotifyPostmaster.java     30 Jun 2003 09:42:07 -0000      1.9.4.10
  @@ -129,7 +129,7 @@
    *   &lt;debug&gt;<I>true or false</I>&lt;/debug&gt;
    * &lt;/mailet&gt;
    * </CODE></PRE>
  - * <P><I>notice</I>, <I>senderAddress</I> and <I>attachStackTrace</I> can be used 
instead of
  + * <P><I>notice</I>, <I>sendingAddress</I> and <I>attachStackTrace</I> can be used 
instead of
    * <I><I>message</I>, <I>sender</I> and <I>attachError</I>; such names are kept for 
backward compatibility.</P>
    *
    * @version CVS $Revision$ $Date$
  @@ -156,6 +156,7 @@
               "attachment",
               "message",
               "notice",
  +            "sender",
               "sendingAddress",
               "prefix",
               "attachError",
  
  
  
  1.10.4.11 +3 -2      
jakarta-james/src/java/org/apache/james/transport/mailets/NotifySender.java
  
  Index: NotifySender.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/NotifySender.java,v
  retrieving revision 1.10.4.10
  retrieving revision 1.10.4.11
  diff -u -r1.10.4.10 -r1.10.4.11
  --- NotifySender.java 27 Jun 2003 14:34:37 -0000      1.10.4.10
  +++ NotifySender.java 30 Jun 2003 09:42:07 -0000      1.10.4.11
  @@ -128,7 +128,7 @@
    *   &lt;debug&gt;<I>true or false</I>&lt;/debug&gt;
    * &lt;/mailet&gt;
    * </CODE></PRE>
  - * <P><I>notice</I>, <I>senderAddress</I> and <I>attachStackTrace</I> can be used 
instead of
  + * <P><I>notice</I>, <I>sendingAddress</I> and <I>attachStackTrace</I> can be used 
instead of
    * <I><I>message</I>, <I>sender</I> and <I>attachError</I>; such names are kept for 
backward compatibility.</P>
    *
    * @version CVS $Revision$ $Date$
  @@ -155,6 +155,7 @@
               "attachment",
               "message",
               "notice",
  +            "sender",
               "sendingAddress",
               "prefix",
               "attachError",
  
  
  
  1.18.4.14 +58 -17    
jakarta-james/src/java/org/apache/james/transport/mailets/Redirect.java
  
  Index: Redirect.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/Redirect.java,v
  retrieving revision 1.18.4.13
  retrieving revision 1.18.4.14
  diff -u -r1.18.4.13 -r1.18.4.14
  --- Redirect.java     27 Jun 2003 14:34:37 -0000      1.18.4.13
  +++ Redirect.java     30 Jun 2003 09:42:07 -0000      1.18.4.14
  @@ -90,11 +90,13 @@
    * <P>A mailet providing configurable redirection services.</P>
    * <P>Can produce listserver, forward and notify behaviour, with the original
    * message intact, attached, appended or left out altogether.</P>
  - * <P>It is kept only for compatibility, use instead [EMAIL PROTECTED] Resend}.
  - * It differs from <CODE>Resend</CODE> because (i) some defaults are different,
  - * notably for the following parameters: <I>&lt;recipients&gt;</I>, 
<I>&lt;to&gt;</I> and <I>&lt;inline&gt;</I>;
  - * (ii) because it allows the use of the <I>&lt;static&gt;</I> parameter;
  - * (iii) because it lacks the <I>&lt;subject&gt;</I> parameter.</P>
  + * <P>It differs from [EMAIL PROTECTED] Resend} because
  + * (i) some defaults are different,
  + * notably for the following parameters: <I>&lt;recipients&gt;</I>, 
<I>&lt;to&gt;</I>,
  + * <I>&lt;returnPath&gt;</I> and <I>&lt;inline&gt;</I>;
  + * (ii) because it allows the use of the <I>&lt;static&gt;</I> parameter;.<BR>
  + * Use <CODE>Resend</CODE> if you need full control, <CODE>Redirect</CODE> if
  + * the more automatic behaviour of some parameters is appropriate.</P>
    * <P>This built in functionality is controlled by the configuration as laid out 
below.
    * In the table please note that the parameters controlling message headers
    * accept the <B>&quot;unaltered&quot;</B> value, whose meaning is to keep the 
associated
  @@ -127,10 +129,9 @@
    * <TR valign=top>
    * <TD width="20%">&lt;sender&gt;</TD>
    * <TD width="80%">
  - * A single email address to appear in the From: header and become the sender.<BR>
  + * A single email address to appear in the From: and Return-Path: headers and 
become the sender.<BR>
    * It can include constants &quot;sender&quot;, &quot;postmaster&quot; and 
&quot;unaltered&quot;;
  - * if &quot;sender&quot; is specified then it will follow a safe procedure from the 
  - * original From: header (see [EMAIL PROTECTED] AbstractRedirect#setSender} and 
[EMAIL PROTECTED] AbstractRedirect#getSender(Mail)}).<BR>
  + * &quot;sender&quot; is equivalent to &quot;unaltered&quot;.<BR>
    * Default: &quot;unaltered&quot;.
    * </TD>
    * </TR>
  @@ -209,26 +210,34 @@
    * <TD width="80%">
    * A single email address to appear in the Reply-To: header.<BR>
    * It can include constants &quot;sender&quot;, &quot;postmaster&quot; 
&quot;null&quot; and &quot;unaltered&quot;;
  - * if &quot;sender&quot; is specified then it will follow a safe procedure from the 
  - * original From: header (see [EMAIL PROTECTED] AbstractRedirect#setReplyTo} and 
[EMAIL PROTECTED] AbstractRedirect#getReplyTo(Mail)});
    * if &quot;null&quot; is specified it will remove this header.<BR>
    * Default: &quot;unaltered&quot;.
    * </TD>
    * </TR>
  + * </TR>
    * <TR valign=top>
    * <TD width="20%">&lt;returnPath&gt;</TD>
    * <TD width="80%">
    * A single email address to appear in the Return-Path: header.<BR>
  - * It can include constants &quot;sender&quot;, &quot;postmaster&quot; 
&quot;null&quot;and &quot;unaltered&quot;;
  + * It can include constants &quot;sender&quot;, &quot;postmaster&quot; and 
&quot;null&quot;;
    * if &quot;null&quot; is specified then it will set it to <>, meaning &quot;null 
return path&quot;.<BR>
  - * Default: &quot;unaltered&quot;.
  + * Notice: the &quot;unaltered&quot; value is <I>not allowed</I>.<BR>
  + * Default: the value of the <I>&lt;sender&gt;</I> parameter, if set, otherwise 
remains unaltered.
  + * </TD>
  + * </TR>
  + * <TR valign=top>
  + * <TD width="20%">&lt;subject&gt;</TD>
  + * <TD width="80%">
  + * An optional string to use as the subject.<BR>
  + * Default: keep the original message subject.
    * </TD>
    * </TR>
    * <TR valign=top>
    * <TD width="20%">&lt;prefix&gt;</TD>
    * <TD width="80%">
    * An optional subject prefix prepended to the original message
  - * subject, for example: <I>[Undeliverable mail]</I>.<BR>
  + * subject, or to a new subject specified with the <I>&lt;subject&gt;</I> 
parameter.<BR>
  + * For example: <I>[Undeliverable mail]</I>.<BR>
    * Default: &quot;&quot;.
    * </TD>
    * </TR>
  @@ -323,7 +332,7 @@
               "replyto",
               "returnPath",
               "sender",
  -//            "subject",
  +            "subject",
               "prefix",
               "attachError",
               "isReply"
  @@ -432,10 +441,42 @@
       }
   
       /**
  -     * @return null
  +     * @return the <CODE>returnPath</CODE> init parameter 
  +     * or the postmaster address
  +     * or <CODE>SpecialAddress.SENDER</CODE>
  +     * or <CODE>SpecialAddress.NULL</CODE>
  +     * or <CODE>null</CODE> if missing
        */
  -    protected String getSubject() {
  +    protected MailAddress getReturnPath() throws MessagingException {
  +        String addressString = getInitParameter("returnPath");
  +        if(addressString != null) {
  +            MailAddress specialAddress = getSpecialAddress(addressString,
  +                                            new String[] {"postmaster", "sender", 
"null"});
  +            if (specialAddress != null) {
  +                return specialAddress;
  +            }
  +
  +            try {
  +                return new MailAddress(addressString);
  +            } catch(Exception e) {
  +                throw new MessagingException("Exception thrown in getReturnPath() 
parsing: " + addressString, e);
  +            }
  +        }
  +
           return null;
  +    }
  +
  +    /**
  +     * @return [EMAIL PROTECTED] AbstractRedirect#getReturnPath()};
  +     * if null return [EMAIL PROTECTED] AbstractRedirect#getSender(Mail)},
  +     * meaning the new requested sender if any
  +     */
  +    protected MailAddress getReturnPath(Mail originalMail) throws 
MessagingException {
  +        MailAddress returnPath = super.getReturnPath(originalMail);
  +        if (returnPath == null) {
  +            returnPath = getSender(originalMail);
  +        }
  +        return returnPath;
       }
   
       /* ******************************************************************** */
  
  
  
  1.1.2.2   +7 -8      
jakarta-james/src/java/org/apache/james/transport/mailets/Resend.java
  
  Index: Resend.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-james/src/java/org/apache/james/transport/mailets/Resend.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- Resend.java       27 Jun 2003 14:34:38 -0000      1.1.2.1
  +++ Resend.java       30 Jun 2003 09:42:07 -0000      1.1.2.2
  @@ -90,8 +90,10 @@
    * <P>A mailet providing configurable redirection services.</P>
    * <P>Can produce listserver, forward and notify behaviour, with the original
    * message intact, attached, appended or left out altogether.
  - * Should be used as a replacement to [EMAIL PROTECTED] Redirect}, as defaults are 
more consistent,
  - * and has new options available.</P>
  + * Can be used as a replacement to [EMAIL PROTECTED] Redirect}, having more 
consistent defaults,
  + * and new options available.<BR>
  + * Use <CODE>Resend</CODE> if you need full control, <CODE>Redirect</CODE> if
  + * the more automatic behaviour of some parameters is appropriate.</P>
    * <P>This built in functionality is controlled by the configuration as laid out 
below.
    * In the table please note that the parameters controlling message headers
    * accept the <B>&quot;unaltered&quot;</B> value, whose meaning is to keep the 
associated
  @@ -121,8 +123,7 @@
    * <TD width="80%">
    * A single email address to appear in the From: header and become the sender.<BR>
    * It can include constants &quot;sender&quot;, &quot;postmaster&quot; and 
&quot;unaltered&quot;;
  - * if &quot;sender&quot; is specified then it will follow a safe procedure from the 
  - * original From: header (see [EMAIL PROTECTED] AbstractRedirect#setSender} and 
[EMAIL PROTECTED] AbstractRedirect#getSender(Mail)}).<BR>
  + * &quot;sender&quot; is equivalent to &quot;unaltered&quot;.<BR>
    * Default: &quot;unaltered&quot;.
    * </TD>
    * </TR>
  @@ -201,8 +202,6 @@
    * <TD width="80%">
    * A single email address to appear in the Reply-To: header.<BR>
    * It can include constants &quot;sender&quot;, &quot;postmaster&quot; 
&quot;null&quot; and &quot;unaltered&quot;;
  - * if &quot;sender&quot; is specified then it will follow a safe procedure from the 
  - * original From: header (see [EMAIL PROTECTED] AbstractRedirect#setReplyTo} and 
[EMAIL PROTECTED] AbstractRedirect#getReplyTo(Mail)});
    * if &quot;null&quot; is specified it will remove this header.<BR>
    * Default: &quot;unaltered&quot;.
    * </TD>
  @@ -211,7 +210,7 @@
    * <TD width="20%">&lt;returnPath&gt;</TD>
    * <TD width="80%">
    * A single email address to appear in the Return-Path: header.<BR>
  - * It can include constants &quot;sender&quot;, &quot;postmaster&quot; 
&quot;null&quot;and &quot;unaltered&quot;;
  + * It can include constants &quot;sender&quot;, &quot;postmaster&quot; 
&quot;null&quot; and &quot;unaltered&quot;;
    * if &quot;null&quot; is specified then it will set it to <>, meaning &quot;null 
return path&quot;.<BR>
    * Default: &quot;unaltered&quot;.
    * </TD>
  
  
  

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

Reply via email to