You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by da...@apache.org on 2002/07/28 13:46:41 UTC

cvs commit: jakarta-james/src/java/org/apache/james/transport/mailets NotifyPostmaster.java Redirect.java NotifySender.java

danny       2002/07/28 04:46:41

  Modified:    src/java/org/apache/james/core MimeMessageWrapper.java
               src/java/org/apache/james/util RFC822DateFormat.java
                        RFC822Date.java
               src/java/org/apache/james/nntpserver NNTPHandler.java
               src/java/org/apache/james/transport/mailets
                        NotifyPostmaster.java Redirect.java
                        NotifySender.java
  Added:       src/java/org/apache/james/util RFC2980DateFormat.java
                        RFC977DateFormat.java SynchronizedDateFormat.java
                        SimplifiedDateFormat.java
  Log:
  Date format synchronisation patch supplied by Peter Goldsein, cures potential problem from un-thread-safe SimpleDateFormat
  
  Revision  Changes    Path
  1.10      +4 -5      jakarta-james/src/java/org/apache/james/core/MimeMessageWrapper.java
  
  Index: MimeMessageWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/core/MimeMessageWrapper.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- MimeMessageWrapper.java	18 Apr 2002 14:49:14 -0000	1.9
  +++ MimeMessageWrapper.java	28 Jul 2002 11:46:40 -0000	1.10
  @@ -16,6 +16,8 @@
   import java.util.Enumeration;
   import java.util.Vector;
   
  +import org.apache.james.util.RFC822DateFormat;
  +
   /**
    * This object wraps a MimeMessage, only loading the underlying MimeMessage
    * object when needed.  Also tracks if changes were made to reduce
  @@ -42,7 +44,7 @@
       /**
        * How to format a mail date
        */
  -    MailDateFormat mailDateFormat = new MailDateFormat();
  +    RFC822DateFormat mailDateFormat = new RFC822DateFormat();
   
       public MimeMessageWrapper(MimeMessageSource source) {
           super(javax.mail.Session.getDefaultInstance(System.getProperties(), null));
  @@ -346,10 +348,7 @@
           String header = getHeader("Date", null);
           if(header != null) {
               try {
  -                synchronized(mailDateFormat) {
  -                    Date date = mailDateFormat.parse(header);
  -                    return date;
  -                }
  +                return mailDateFormat.parse(header);
               } catch(ParseException _ex) {
                   return null;
               }
  
  
  
  1.4       +18 -39    jakarta-james/src/java/org/apache/james/util/RFC822DateFormat.java
  
  Index: RFC822DateFormat.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/util/RFC822DateFormat.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- RFC822DateFormat.java	4 Oct 2001 15:17:49 -0000	1.3
  +++ RFC822DateFormat.java	28 Jul 2002 11:46:40 -0000	1.4
  @@ -7,60 +7,39 @@
    */
   package org.apache.james.util;
   
  -import java.text.DateFormat;
  -import java.text.DecimalFormat;
  -import java.text.SimpleDateFormat;
   import java.util.Date;
  -import java.util.Locale;
  -import java.util.TimeZone;
  +import javax.mail.internet.MailDateFormat;
   
   /**
  - * I suppose I could access some of the special messages within Sun's implementation of the JavaMail
  - * API, but I've always been told not to do that.  This class has one static method that takes a
  - * java.util.Date object and returns a nicely formatted String version of this, formatted as per the
  - * RFC822 mail date format.
  + * A thread safe wrapper for the <code>javax.mail.internet.MailDateFormat</code> class.
  + *
    * @author Serge Knystautas <se...@lokitech.com>
  + * @author Peter M. Goldstein <fa...@alum.mit.edu>
    */
  -public class RFC822DateFormat {
  -    private static DateFormat df;
  -    private static DecimalFormat tz;
  -    private static TimeZone defaultTZ;
  +public class RFC822DateFormat extends SynchronizedDateFormat {
  +    private static RFC822DateFormat instance; 
   
       static {
  -        df = new SimpleDateFormat("EE, d MMM yyyy HH:mm:ss", Locale.ENGLISH);
  -        tz = new DecimalFormat("00");
  -        defaultTZ = TimeZone.getDefault();
  +        instance = new RFC822DateFormat();
       }
   
       /**
  -     * SimpleDateFormat will handle most of this for us, but the
  -     * timezone won't match, so we do that manually
  +     * This static method allows us to format RFC822 dates without
  +     * explicitly instantiating an RFC822DateFormat object.
        *
        * @return java.lang.String
        * @param d Date
  +     *
  +     * @deprecated This method is not necessary and is preserved for API
  +     *             backwards compatibility.  Users of this class should
  +     *             instantiate an instance and use it as they would any
  +     *             other DateFormat object.
        */
       public static String toString(Date d) {
  -        StringBuffer sb = new StringBuffer(df.format(d));
  -
  -        sb.append(' ');
  -
  -        int min = TimeZone.getDefault().getRawOffset() / 1000 / 60;
  -
  -        if (defaultTZ.useDaylightTime() && defaultTZ.inDaylightTime(d)) {
  -            min += 60;
  -        }
  -
  -        if (min >= 0) {
  -            sb.append('+');
  -        } else {
  -            sb.append('-');
  -        }
  -
  -        min = Math.abs(min);
  -
  -        sb.append(tz.format(min / 60));
  -        sb.append(tz.format(min % 60));
  +        return instance.format(d);
  +    }
   
  -        return sb.toString();
  +    public RFC822DateFormat() {
  +        super(new MailDateFormat());
       }
   }
  
  
  
  1.4       +30 -45    jakarta-james/src/java/org/apache/james/util/RFC822Date.java
  
  Index: RFC822Date.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/util/RFC822Date.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- RFC822Date.java	18 Jan 2002 02:48:39 -0000	1.3
  +++ RFC822Date.java	28 Jul 2002 11:46:40 -0000	1.4
  @@ -7,8 +7,6 @@
    */
   package org.apache.james.util;
   
  -import java.text.DateFormat;
  -import java.text.DecimalFormat;
   import java.text.ParseException;
   import java.text.SimpleDateFormat;
   import java.util.Date;
  @@ -25,22 +23,23 @@
    * example - convert to timezone: String yourdate = new RFC822Date("3 Oct 2001 08:32:44 -0000", "GMT+02:00").toString()<br>
    * example - convert to local timezone: String mydate = new RFC822Date("3 Oct 2001 08:32:44 -0000").toString()<br>
    * @author Danny Angus (danny) <Da...@thought.co.uk><br>
  + * @author Peter M. Goldstein <fa...@alum.mit.edu><br>
  + *
  + * @deprecated Use java.util.Date in combination with org.apache.james.util.RFC822DateFormat.
    */
   public class RFC822Date {
  -    private static DateFormat df;
  +    private static SimpleDateFormat df;
       private static SimpleDateFormat dx;
       private static SimpleDateFormat dy;
       private static SimpleDateFormat dz;
  -    private static DecimalFormat tz;
  -    private TimeZone defaultTZ;
       private Date d;
  +    private RFC822DateFormat rfc822Format = new RFC822DateFormat();
      
       static {
           df = new SimpleDateFormat("EE, d MMM yyyy HH:mm:ss", Locale.US);
           dx = new SimpleDateFormat("EE, d MMM yyyy HH:mm:ss zzzzz", Locale.US);
           dy = new SimpleDateFormat("EE d MMM yyyy HH:mm:ss zzzzz", Locale.US);
   	  	dz = new SimpleDateFormat("d MMM yyyy HH:mm:ss zzzzz", Locale.US);
  -	  	tz = new DecimalFormat("00"); 
   	  }   
      
      /**
  @@ -48,9 +47,8 @@
   	* using this machines system timezone<br>
   	* 
   	*/
  -public RFC822Date(){
  +    public RFC822Date(){
       	d = new Date();
  -    	defaultTZ = TimeZone.getDefault();
       }
       
      /**
  @@ -58,9 +56,8 @@
   	* and this machines system timezone<br>
   	* @param da java.util.Date, A date object
   	*/
  -    public RFC822Date(Date da){
  +    public RFC822Date(Date da) {
       	d = da;
  -    	defaultTZ = TimeZone.getDefault();
       }
       
      /**
  @@ -77,7 +74,6 @@
   	*/
       public RFC822Date(Date da, String useTZ){
       	d = da;
  -    	defaultTZ = TimeZone.getTimeZone(useTZ);
       }
   
   	/**
  @@ -89,7 +85,6 @@
   	*/
   	public RFC822Date(String rfcdate) {
   		setDate(rfcdate);
  -		defaultTZ = TimeZone.getDefault();
   	}
   	/**
   	* creates object from 
  @@ -100,7 +95,7 @@
   	*/	
   	public RFC822Date(String rfcdate, String useTZ)  {
   		setDate(rfcdate);
  -		defaultTZ = TimeZone.getTimeZone(useTZ);
  +		setTimeZone(useTZ);
   	}	
   
       public void setDate(Date da){
  @@ -116,17 +111,21 @@
    * @param rfcdate java.lang.String - date in RFC822 format
    */
       public void setDate(String rfcdate)  {
  -    	String exceptions;
  -    	int exceptionoff;
  -		try{
  -			d= dx.parse(rfcdate);
  -		}catch(ParseException  e){
  -			try{
  -				d= dz.parse(rfcdate);
  -			}catch(ParseException  f){
  -				try{
  -					d= dy.parse(rfcdate);
  -				}catch(ParseException  g){
  +		try {
  +			synchronized (dx) {
  +			    d= dx.parse(rfcdate);
  +			}
  +		} catch(ParseException e) {
  +			try {
  +				synchronized (dz) {
  +					d= dz.parse(rfcdate);
  +				}
  +			} catch(ParseException f) {
  +				try {
  +					synchronized (dy) {
  +						d = dy.parse(rfcdate);
  +					}
  +				} catch(ParseException g) {
   					d = new Date();
   				}
   			}
  @@ -135,12 +134,12 @@
       	
       }
    
  -    public void setTimeZone(TimeZone useTZ){
  -    	defaultTZ = useTZ;
  +    public void setTimeZone(TimeZone useTZ) {
  +        rfc822Format.setTimeZone(useTZ);
       }
       
  -    public void setTimeZone(String useTZ){
  -    	defaultTZ = TimeZone.getTimeZone(useTZ);
  +    public void setTimeZone(String useTZ) {
  +    	setTimeZone(TimeZone.getTimeZone(useTZ));
       }
       
   
  @@ -148,7 +147,7 @@
        * returns the java.util.Date object this RFC822Date represents.
        * @return java.util.Date - the java.util.Date object this RFC822Date represents.
        */
  -    public Date getDate(){
  +    public Date getDate() {
       	return d;
       }
   
  @@ -158,21 +157,7 @@
        * @return java.lang.String - date as a string formated for RFC822 compliance
        * 
        */
  -    public  String toString() {
  -        StringBuffer sb = new StringBuffer(df.format(d));
  -        sb.append(' ');
  -        int min = defaultTZ.getRawOffset() / 1000 / 60;
  -        if (defaultTZ.useDaylightTime() && defaultTZ.inDaylightTime(d)) {
  -            min += 60;
  -        }
  -        if (min >= 0) {
  -            sb.append('+');
  -        } else {
  -            sb.append('-');
  -        }
  -        min = Math.abs(min);
  -        sb.append(tz.format(min / 60));
  -        sb.append(tz.format(min % 60));
  -        return sb.toString();
  +    public String toString() {
  +        return rfc822Format.format(d);
       }
   }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/james/util/RFC2980DateFormat.java
  
  Index: RFC2980DateFormat.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.util;
  
  import java.util.Locale;
  
  /**
   * A thread-safe date formatting class to produce dates formatted in accord with the 
   * specifications of section 3.2 of RFC 2980.
   *
   * @author Peter M. Goldstein <fa...@alum.mit.edu>
   */
  public class RFC2980DateFormat extends SynchronizedDateFormat {
  
      public RFC2980DateFormat() {
          super("yyyyMMddHHmmss", Locale.ENGLISH);
      }
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/james/util/RFC977DateFormat.java
  
  Index: RFC977DateFormat.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.util;
  
  import java.text.DateFormat;
  import java.text.ParseException;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import java.util.Locale;
  import java.util.TimeZone;
  
  /**
   * A thread-safe date formatting class to produce dates formatted in accord with the 
   * specifications of RFC 977.
   *
   * @author Peter M. Goldstein <fa...@alum.mit.edu>
   */
  public class RFC977DateFormat implements SimplifiedDateFormat {
      private final SynchronizedDateFormat internalLongDateFormat;
      private final SynchronizedDateFormat internalShortDateFormat;
  
      public RFC977DateFormat() {
          internalLongDateFormat = new SynchronizedDateFormat("yyyyMMdd HHmmss", Locale.ENGLISH);
          internalShortDateFormat = new SynchronizedDateFormat("yyMMdd HHmmss", Locale.ENGLISH);
      }
  
      /**
       * This method returns the long form of the RFC977 Date 
       *
       * @return java.lang.String
       * @param d Date
       */
      public String format(Date d) {
          return internalLongDateFormat.format(d);
      }
  
      /**
       * Parses text from the beginning of the given string to produce a date.
       * The method may not use the entire text of the given string.
       * <p>
       * This method is designed to be thread safe, so we wrap our delegated
       * parse method in an appropriate synchronized block.
       *
       * @param source A <code>String</code> whose beginning should be parsed.
       * @return A <code>Date</code> parsed from the string.
       * @exception ParseException if the beginning of the specified string
       *            cannot be parsed.
       */
      public Date parse(String source) throws ParseException {
          source = source.trim();
          if (source.indexOf(' ') == 6) {
              return internalShortDateFormat.parse(source);
          } else {
              return internalLongDateFormat.parse(source);
          }
      }
  
      /**
       * Sets the time zone of this SynchronizedDateFormat object.
       * @param zone the given new time zone.
       */
      public void setTimeZone(TimeZone zone) {
          synchronized(this) {
              internalShortDateFormat.setTimeZone(zone);
              internalLongDateFormat.setTimeZone(zone);
          }
      }
  
      /**
       * Gets the time zone.
       * @return the time zone associated with this SynchronizedDateFormat.
       */
      public TimeZone getTimeZone() {
          synchronized(this) {
              return internalShortDateFormat.getTimeZone();
          }
      }
  
      /**
       * Specify whether or not date/time parsing is to be lenient.  With
       * lenient parsing, the parser may use heuristics to interpret inputs that
       * do not precisely match this object's format.  With strict parsing,
       * inputs must match this object's format.
       * @param lenient when true, parsing is lenient
       * @see java.util.Calendar#setLenient
       */
      public void setLenient(boolean lenient)
      {
          synchronized(this) {
              internalShortDateFormat.setLenient(lenient);
              internalLongDateFormat.setLenient(lenient);
          }
      }
  
      /**
       * Tell whether date/time parsing is to be lenient.
       * @return whether this SynchronizedDateFormat is lenient.
       */
      public boolean isLenient()
      {
          synchronized(this) {
              return internalShortDateFormat.isLenient();
          }
      }
  
  
      /**
       * Overrides equals
       */
      public boolean equals(Object obj) {
          if (this == obj) {
              return true;
          }
          if (!(obj instanceof RFC977DateFormat)) {
              return false;
          }
          RFC977DateFormat theOtherRFC977DateFormat = (RFC977DateFormat)obj;
          synchronized (this) {
              return ((internalShortDateFormat.equals(theOtherRFC977DateFormat.internalShortDateFormat)) &&
                      (internalLongDateFormat.equals(theOtherRFC977DateFormat.internalLongDateFormat)));
          }
      }
  
      /**
       * Overrides hashCode
       */
      public int hashCode() {
          return (int)(internalLongDateFormat.hashCode() & internalShortDateFormat.hashCode());
      }
  
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/james/util/SynchronizedDateFormat.java
  
  Index: SynchronizedDateFormat.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.util;
  
  import java.text.ParseException;
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import java.util.Locale;
  import java.util.TimeZone;
  
  /**
   * This class is designed to be a synchronized wrapper for a 
   * <code>java.text.DateFormat</code> subclass.  In general,
   * these subclasses (most notably the <code>java.text.SimpleDateFormat</code>
   * classes are not thread safe, so we need to synchronize on the 
   * internal DateFormat for all delegated calls.   
   *
   * @author Peter M. Goldstein <fa...@alum.mit.edu>
   */
  public class SynchronizedDateFormat implements SimplifiedDateFormat {
      private final DateFormat internalDateFormat;
  
      public SynchronizedDateFormat(String pattern, Locale locale) {
          internalDateFormat = new SimpleDateFormat(pattern, locale);
      }
  
      protected SynchronizedDateFormat(DateFormat theDateFormat) {
          internalDateFormat = theDateFormat;
      }
  
      /**
       * SimpleDateFormat will handle most of this for us, but we
       * want to ensure thread safety, so we wrap the call in a
       * synchronized block.
       *
       * @return java.lang.String
       * @param d Date
       */
      public String format(Date d) {
          synchronized (internalDateFormat) {
             return internalDateFormat.format(d);
          }
      }
  
      /**
       * Parses text from the beginning of the given string to produce a date.
       * The method may not use the entire text of the given string.
       * <p>
       * This method is designed to be thread safe, so we wrap our delegated
       * parse method in an appropriate synchronized block.
       *
       * @param source A <code>String</code> whose beginning should be parsed.
       * @return A <code>Date</code> parsed from the string.
       * @exception ParseException if the beginning of the specified string
       *            cannot be parsed.
       */
      public Date parse(String source) throws ParseException {
          synchronized (internalDateFormat) {
              return internalDateFormat.parse(source);
          }
      }
  
      /**
       * Sets the time zone of this SynchronizedDateFormat object.
       * @param zone the given new time zone.
       */
      public void setTimeZone(TimeZone zone) {
          synchronized(internalDateFormat) {
              internalDateFormat.setTimeZone(zone);
          }
      }
  
      /**
       * Gets the time zone.
       * @return the time zone associated with this SynchronizedDateFormat.
       */
      public TimeZone getTimeZone() {
          synchronized(internalDateFormat) {
              return internalDateFormat.getTimeZone();
          }
      }
  
      /**
       * Specify whether or not date/time parsing is to be lenient.  With
       * lenient parsing, the parser may use heuristics to interpret inputs that
       * do not precisely match this object's format.  With strict parsing,
       * inputs must match this object's format.
       * @param lenient when true, parsing is lenient
       * @see java.util.Calendar#setLenient
       */
      public void setLenient(boolean lenient)
      {
          synchronized(internalDateFormat) {
              internalDateFormat.setLenient(lenient);
          }
      }
  
      /**
       * Tell whether date/time parsing is to be lenient.
       * @return whether this SynchronizedDateFormat is lenient.
       */
      public boolean isLenient()
      {
          synchronized(internalDateFormat) {
              return internalDateFormat.isLenient();
          }
      }
  
      /**
       * Overrides hashCode
       */
      public int hashCode() {
          synchronized(internalDateFormat) {
              return internalDateFormat.hashCode();
          }
      }
  
      /**
       * Overrides equals
       */
      public boolean equals(Object obj) {
          if (this == obj) {
              return true;
          }
          if (obj == null || getClass() != obj.getClass()) {
              return false;
          }
          synchronized(internalDateFormat) {
              return internalDateFormat.equals(obj);
          }
      }
  
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/james/util/SimplifiedDateFormat.java
  
  Index: SimplifiedDateFormat.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.util;
  
  import java.text.ParseException;
  import java.util.Date;
  import java.util.Locale;
  import java.util.TimeZone;
  
  /**
   * This interface is designed to provide a simplified subset of the
   * methods provided by the <code>java.text.DateFormat</code> class.
   *
   * This interface is necessary because of the difficulty in writing
   * thread safe classes that inherit from <code>java.text.DateFormat</code>.
   * This difficulty leads us to approach the problem using composition
   * rather than inheritance.  In general classes that implement this
   * interface will delegate these calls to an internal DateFormat object.
   *    
   * @author Peter M. Goldstein <fa...@alum.mit.edu>
   */
  public interface SimplifiedDateFormat {
  
      /**
       * Formats a Date into a date/time string.
       * @param date the time value to be formatted into a time string.
       * @return the formatted time string.
       */
      public String format(Date d);
  
      /**
       * Parses text from the beginning of the given string to produce a date.
       * The method may not use the entire text of the given string.
       *
       * @param source A <code>String</code> whose beginning should be parsed.
       * @return A <code>Date</code> parsed from the string.
       * @exception ParseException if the beginning of the specified string
       *            cannot be parsed.
       */
      public Date parse(String source) throws ParseException;
  
      /**
       * Sets the time zone of this SimplifiedDateFormat object.
       * @param zone the given new time zone.
       */
      public void setTimeZone(TimeZone zone);
  
      /**
       * Gets the time zone.
       * @return the time zone associated with this SimplifiedDateFormat.
       */
      public TimeZone getTimeZone();
  
      /**
       * Specify whether or not date/time parsing is to be lenient.  With
       * lenient parsing, the parser may use heuristics to interpret inputs that
       * do not precisely match this object's format.  With strict parsing,
       * inputs must match this object's format.
       * @param lenient when true, parsing is lenient
       * @see java.util.Calendar#setLenient
       */
      public void setLenient(boolean lenient);
  
      /**
       * Tell whether date/time parsing is to be lenient.
       * @return whether this SimplifiedDateFormat is lenient.
       */
      public boolean isLenient();
  }
  
  
  
  
  1.13      +14 -11    jakarta-james/src/java/org/apache/james/nntpserver/NNTPHandler.java
  
  Index: NNTPHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/nntpserver/NNTPHandler.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- NNTPHandler.java	27 Jul 2002 08:16:25 -0000	1.12
  +++ NNTPHandler.java	28 Jul 2002 11:46:41 -0000	1.13
  @@ -21,6 +21,9 @@
   import org.apache.james.nntpserver.repository.NNTPGroup;
   import org.apache.james.nntpserver.repository.NNTPLineReaderImpl;
   import org.apache.james.nntpserver.repository.NNTPRepository;
  +import org.apache.james.util.RFC977DateFormat;
  +import org.apache.james.util.RFC2980DateFormat;
  +import org.apache.james.util.SimplifiedDateFormat;
   
   import java.io.BufferedReader;
   import java.io.IOException;
  @@ -29,13 +32,12 @@
   import java.net.Socket;
   import java.text.DateFormat;
   import java.text.ParseException;
  -import java.text.SimpleDateFormat;
   import java.util.*;
   
   /**
    * The NNTP protocol is defined by RFC 977.
  - * This implementation is based on IETF draft 13, posted on 2nd April '2001.
  - * URL: http://www.ietf.org/internet-drafts/draft-ietf-nntpext-base-13.txt
  + * This implementation is based on IETF draft 15, posted on 15th July '2002
  + * URL: http://www.ietf.org/internet-drafts/draft-ietf-nntpext-base-15.txt
    *
    * Common NNTP extensions are in RFC 2980.
    *
  @@ -239,9 +241,9 @@
       private void doNEWGROUPS(StringTokenizer tok) {
           // see section 11.3
           // there seeem to be few differences.
  -        // draft-ietf-nntpext-base-13.txt mentions 231 in section 11.3.1, 
  +        // draft-ietf-nntpext-base-15.txt mentions 231 in section 11.3.1, 
           // but examples have response code 230. rfc977 has 231 response code.
  -        // both draft-ietf-nntpext-base-13.txt and rfc977 have only group names 
  +        // both draft-ietf-nntpext-base-15.txt and rfc977 have only group names 
           // in response lines, but INN sends 
           // '<group name> <last article> <first article> <posting allowed>'
           // NOTE: following INN over either document.
  @@ -265,9 +267,11 @@
           String time = tok.nextToken();
           boolean  utc = ( tok.hasMoreTokens() );
           Date d = new Date();
  -        DateFormat df = ( date.length() == 8 ) ? DF_DATEFROM_LONG : DF_DATEFROM_SHORT;
           try {
  -            Date dt = df.parse(date+" "+time);
  +            StringBuffer dateStringBuffer = new StringBuffer(date);
  +            dateStringBuffer.append(" ");
  +            dateStringBuffer.append(time);
  +            Date dt = DF_RFC977.parse(dateStringBuffer.toString());
               if ( utc )
                   dt = new Date(dt.getTime()+UTC_OFFSET);
               return dt;
  @@ -282,17 +286,16 @@
       }
   
       // used to calculate DATE from - see 11.3
  -    public static final DateFormat DF_DATEFROM_LONG = new SimpleDateFormat("yyyyMMdd HHmmss");
  -    public static final DateFormat DF_DATEFROM_SHORT = new SimpleDateFormat("yyMMdd HHmmss");
  +    public static final SimplifiedDateFormat DF_RFC977 = new RFC977DateFormat();
   
       // Date format for the DATE keyword - see 11.1.1
  -    public static final DateFormat DF_DATE = new SimpleDateFormat("yyyyMMddHHmmss");
  +    public static final SimplifiedDateFormat DF_RFC2980 = new RFC2980DateFormat();
       public static final long UTC_OFFSET = Calendar.getInstance().get(Calendar.ZONE_OFFSET);
       private void doDATE() {
           //Calendar c = Calendar.getInstance();
           //long UTC_OFFSET = c.get(c.ZONE_OFFSET) + c.get(c.DST_OFFSET);
           Date dt = new Date(System.currentTimeMillis()-UTC_OFFSET);
  -        String dtStr = DF_DATE.format(new Date(dt.getTime() - UTC_OFFSET));
  +        String dtStr = DF_RFC2980.format(new Date(dt.getTime() - UTC_OFFSET));
           writer.println("111 "+dtStr);
       }
       private void doQUIT() {
  
  
  
  1.5       +5 -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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- NotifyPostmaster.java	18 Jan 2002 02:48:38 -0000	1.4
  +++ NotifyPostmaster.java	28 Jul 2002 11:46:41 -0000	1.5
  @@ -7,7 +7,7 @@
    */
   package org.apache.james.transport.mailets;
   
  -import org.apache.james.util.RFC822Date;
  +import org.apache.james.util.RFC822DateFormat;
   import org.apache.mailet.GenericMailet;
   import org.apache.mailet.Mail;
   import org.apache.mailet.MailAddress;
  @@ -24,6 +24,7 @@
   import java.io.IOException;
   import java.io.PrintWriter;
   import java.io.StringWriter;
  +import java.util.Date;
   import java.util.HashSet;
   import java.util.Iterator;
   import java.util.Set;
  @@ -49,6 +50,8 @@
       boolean attachStackTrace = false;
       String noticeText = null;
   
  +    private RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();
  +
       public void init() throws MessagingException {
           if (getInitParameter("sendingAddress") == null) {
               notifier = getMailetContext().getPostmaster();
  @@ -175,7 +178,7 @@
   
           //Set additional headers
           if (reply.getHeader("Date")==null){
  -            reply.setHeader("Date",new RFC822Date().toString());
  +            reply.setHeader("Date", rfc822DateFormat.format(new Date()));
           }
           String subject = message.getSubject();
           if (subject == null) {
  
  
  
  1.5       +567 -551  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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Redirect.java	18 Jun 2002 21:49:53 -0000	1.4
  +++ Redirect.java	28 Jul 2002 11:46:41 -0000	1.5
  @@ -1,551 +1,567 @@
  -/*
  - * Copyright (C) The Apache Software Foundation. All rights reserved.
  - *
  - * This software is published under the terms of the Apache Software License
  - * version 1.1, a copy of which has been included with this distribution in
  - * the LICENSE file.
  - */
  -package org.apache.james.transport.mailets;
  -
  -import java.io.PrintWriter;
  -import java.io.StringWriter;
  -
  -import java.util.Collection;
  -import java.util.Enumeration;
  -import java.util.HashSet;
  -import java.util.StringTokenizer;
  -
  -import javax.mail.Message;
  -import javax.mail.MessagingException;
  -import javax.mail.Session;
  -import javax.mail.internet.InternetAddress;
  -import javax.mail.internet.MimeBodyPart;
  -import javax.mail.internet.MimeMessage;
  -import javax.mail.internet.MimeMultipart;
  -
  -import org.apache.james.util.RFC822Date;
  -
  -import org.apache.mailet.GenericMailet;
  -import org.apache.mailet.Mail;
  -import org.apache.mailet.MailAddress;
  -
  -
  -/**
  -*<P>A mailet providing configurable redirection services<BR>
  -*This mailet can produce listserver, forward and notify behaviour, with the original
  -*message intact, attached, appended or left out altogether.<BR>
  -*This built in functionality is controlled by the configuration as laid out below.</P>
  -*<P>However it is also designed to be easily subclassed to make authoring redirection
  -*mailets simple. <BR>
  -*By extending it and overriding one or more of these methods new behaviour can
  -*be quickly created without the author having to address any other issue than
  -*the relevant one:</P>
  -*<UL>
  -*<LI>attachError() , should error messages be appended to the message</LI>
  -*<LI>getAttachementType(), what should be attached to the message</LI>
  -*<LI>getInLineType(), what should be included in the message</LI>
  -*<LI>getMessage(), The text of the message itself</LI>
  -*<LI>getRecipients(), the recipients the mail is sent to</LI>
  -*<LI>getReplyTo(), where replys to this message will be sent</LI>
  -*<LI>getSender(), who the mail is from</LI>
  -*<LI>getSubjectPrefix(), a prefix to be added to the message subject</LI>
  -*<LI>getTo(), a list of people to whom the mail is *apparently* sent</LI>
  -*<LI>getPassThrough(), should this mailet GHOST the original message.</LI>
  -*<LI>isStatic(), should this mailet run the get methods for every mail, or just
  -*once. </LI>
  -*</UL>
  -*<P>The configuration parameters are:</P>
  -*<TABLE width="75%" border="0" cellspacing="2" cellpadding="2">
  -*<TR>
  -*<TD width="20%">&lt;recipients&gt;</TD>
  -*<TD width="80%">A comma delimited list of email addresses for recipients of
  -*this message, it will use the &quot;to&quot; list if not specified. These
  -*addresses will only appear in the To: header if no &quot;to&quot; list is
  -*supplied.</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;to&gt;</TD>
  -*<TD width="80%">A comma delimited list of addresses to appear in the To: header,
  -*the email will only be delivered to these addresses if they are in the recipients
  -*list.<BR>
  -*The recipients list will be used if this is not supplied</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;sender&gt;</TD>
  -*<TD width="80%">A single email address to appear in the From: header <BR>
  -*It can include constants &quot;sender&quot; and &quot;postmaster&quot;</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;message&gt;</TD>
  -*<TD width="80%">A text message to be the body of the email. Can be omitted.</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;inline&gt;</TD>
  -*<TD width="80%">
  -*<P>One of the following items:</P>
  -*<UL>
  -*<LI>unaltered &nbsp;&nbsp;&nbsp;&nbsp;The original message is the new
  -* message, for forwarding/aliasing</LI>
  -*<LI>heads&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The
  -* headers of the original message are appended to the message</LI>
  -*<LI>body&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The
  -* body of the original is appended to the new message</LI>
  -*<LI>all&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Both
  -* headers and body are appended</LI>
  -*<LI>none&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Neither
  -* body nor headers are appended</LI>
  -*</UL>
  -*</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;attachment&gt;</TD>
  -*<TD width="80%">
  -*<P>One of the following items:</P>
  -*<UL>
  -*<LI>heads&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The headers of the original
  -* are attached as text</LI>
  -*<LI>body&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The body of the original
  -* is attached as text</LI>
  -*<LI>all&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Both
  -* headers and body are attached as a single text file</LI>
  -*<LI>none&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nothing is attached</LI>
  -*<LI>message &nbsp;The original message is attached as type message/rfc822,
  -* this means that it can, in many cases, be opened, resent, fw'd, replied
  -* to etc by email client software.</LI>
  -*</UL>
  -*</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;passThrough&gt;</TD>
  -*<TD width="80%">TRUE or FALSE, if true the original message continues in the
  -*mailet processor after this mailet is finished. False causes the original
  -*to be stopped.</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;attachError&gt;</TD>
  -*<TD width="80%">TRUE or FALSE, if true any error message available to the
  -*mailet is appended to the message body (except in the case of inline ==
  -*unaltered)</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;replyto&gt;</TD>
  -*<TD width="80%">A single email address to appear in the Rely-To: header, can
  -*also be &quot;sender&quot; or &quot;postmaster&quot;, this header is not
  -*set if this is omited.</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;prefix&gt;</TD>
  -*<TD width="80%">An optional subject prefix prepended to the original message
  -*subject, for example..<BR>
  -*Undeliverable mail:</TD>
  -*</TR>
  -*<TR>
  -*<TD width="20%">&lt;static&gt;</TD>
  -*<TD width="80%">
  -*<P>TRUE or FALSE, if this is true it hints to the mailet that none of the
  -*parameters are set dynamically, and therefore they can be set once in
  -*the init method.<BR>
  -*False tells the mailet to call all the &quot;getters&quot; for every mail
  -*processed.</P>
  -*<P>This defaults to false.<BR>
  -*It should be TRUE in all cases, except where one of the getter methods
  -*has been overriden to provide dynamic values, such as a listserve which
  -*might override getRecipients() to get a list from a users repository.</P>
  -*</TD>
  -*</TR>
  -*</TABLE>
  -*
  -*<P>Example:</P>
  -*<P> &lt;mailet match=&quot;RecipientIs=test@localhost&quot; class=&quot;Redirect&quot;&gt;<BR>
  -*&lt;recipients&gt;x@localhost, y@localhost, z@localhost&lt;/recipients&gt;<BR>
  -*&lt;to&gt;list@localhost&lt;/to&gt;<BR>
  -*&lt;sender&gt;owner@localhost&lt;/sender&gt;<BR>
  -*&lt;message&gt;sent on from James&lt;/message&gt;<BR>
  -*&lt;inline&gt;unaltered&lt;/inline&gt;<BR>
  -*&lt;passThrough&gt;FALSE&lt;/passThrough&gt;<BR>
  -*&lt;replyto&gt;postmaster&lt;/replyto&gt;<BR>
  -*&lt;prefix&gt;[test mailing]&lt;/prefix&gt;<BR>
  -*&lt;static&gt;TRUE&lt;/static&gt;<BR>
  -*&lt;passThrough&gt;FALSE&lt;/passThrough&gt;<BR>
  -*&lt;/mailet&gt;<BR>
  -*</P>
  -*<P>and:</P>
  -*<P> &lt;mailet match=&quot;All&quot; class=&quot;Redirect&quot;&gt;<BR>
  -*&lt;recipients&gt;x@localhost&lt;/recipients&gt;<BR>
  -*&lt;sender&gt;postmaster&lt;/sender&gt;<BR>
  -*&lt;message&gt;Message marked as spam:<BR>
  -*&lt;/message&gt;<BR>
  -*&lt;inline&gt;heads&lt;/inline&gt;<BR>
  -*&lt;attachment&gt;message&lt;/attachment&gt;<BR>
  -*&lt;passThrough&gt;FALSE&lt;/passThrough&gt;<BR>
  -*&lt;attachError&gt;TRUE&lt;/attachError&gt;<BR>
  -*&lt;replyto&gt;postmaster&lt;/replyto&gt;<BR>
  -*&lt;prefix&gt;[spam notification]&lt;/prefix&gt;<BR>
  -*&lt;static&gt;TRUE&lt;/static&gt;<BR>
  -*&lt;passThrough&gt;FALSE&lt;/passThrough&gt;<BR>
  -*&lt;/mailet&gt;</P>
  - *
  - * @author  Danny Angus   <da...@thought.co.uk>
  - *
  - */
  -public class Redirect extends GenericMailet {
  -    private static int ALL                 = 3;
  -    private static int BODY                = 2;
  -    private static int HEADS               = 1;
  -    private static int MESSAGE             = 5;
  -    private static int NONE                = 4;
  -    private static int UNALTERED           = 0;
  -    private InternetAddress[] apparentlyTo;
  -    private String messageText;
  -    private Collection recipients;
  -    private MailAddress replyTo;
  -    private MailAddress sender;
  -
  -    /**
  -*     returns one of these values to indicate how to attach the original message
  -*<ul>
  -*    <li>BODY : original message body is attached as plain text to the new message</li>
  -*    <li>HEADS : original message headers are attached as plain text to the new message</li>
  -*    <li>ALL : original is attached as plain text with all headers</li>
  -*    <li>MESSAGE : original message is attached as type message/rfc822, a complete mail message.</li>
  -*    <li>NONE : original is not attached</li>
  -*</ul>
  -*
  -*/
  -    public int getAttachmentType() {
  -        if(getInitParameter("attachment") == null) {
  -            return NONE;
  -        } else {
  -            return getTypeCode(getInitParameter("attachment"));
  -        }
  -    }
  -
  -    /**
  -* returns one of these values to indicate how to append the original message
  -*<ul>
  -*    <li>UNALTERED : original message is the new message body</li>
  -*    <li>BODY : original message body is appended to the new message</li>
  -*    <li>HEADS : original message headers are appended to the new message</li>
  -*    <li>ALL : original is appended with all headers</li>
  -*    <li>NONE : original is not appended</li>
  -*</ul>
  -*/
  -    public int getInLineType() {
  -        if(getInitParameter("inline") == null) {
  -            return BODY;
  -        } else {
  -            return getTypeCode(getInitParameter("inline"));
  -        }
  -    }
  -
  -    /**
  -     * Add Description
  -     *
  -     * @return Document return!
  -     */
  -    public String getMailetInfo() {
  -        return "Resend Mailet";
  -    }
  -
  -    /**
  -* must return either an empty string, or a message to which the redirect can be attached/appended
  -*/
  -    public String getMessage() {
  -        if(getInitParameter("message") == null) {
  -            return "";
  -        } else {
  -            return getInitParameter("message");
  -        }
  -    }
  -
  -    /**
  -* return true to allow thie original message to continue through the processor, false to GHOST it
  -*/
  -    public boolean getPassThrough() {
  -        if(getInitParameter("passThrough") == null) {
  -            return false;
  -        } else {
  -            return new Boolean(getInitParameter("passThrough")).booleanValue();
  -        }
  -    }
  -
  -    /**
  -* must return a Collection of recipient MailAddress'es
  -*/
  -    public Collection getRecipients() {
  -        Collection newRecipients           = new HashSet();
  -        String addressList                 = (getInitParameter("recipients") == null)
  -                                                 ? getInitParameter("to")
  -                                                 : getInitParameter("recipients");
  -        StringTokenizer st                 = new StringTokenizer(addressList, ",", false);
  -        while(st.hasMoreTokens()) {
  -            try {
  -                newRecipients.add(new MailAddress(st.nextToken()));
  -            } catch(Exception e) {
  -                log("add recipient failed in getRecipients");
  -            }
  -        }
  -        return newRecipients;
  -    }
  -
  -    /**
  -* return the reply to address as a string
  -*/
  -    public MailAddress getReplyTo() {
  -        String sr = getInitParameter("replyto");
  -        if(sr != null) {
  -            MailAddress rv;
  -            if(sr.compareTo("postmaster") == 0) {
  -                rv = getMailetContext().getPostmaster();
  -                return rv;
  -            }
  -            if(sr.compareTo("sender") == 0) {
  -                return null;
  -            }
  -            try {
  -                rv = new MailAddress(sr);
  -                return rv;
  -            } catch(Exception e) {
  -                log("Parse error in getReplyTo " + sr);
  -            }
  -        }
  -        return null;
  -    }
  -
  -    /**
  -* returns the senders address, as a MailAddress
  -*/
  -    public MailAddress getSender() {
  -        String sr = getInitParameter("sender");
  -        if(sr != null) {
  -            MailAddress rv;
  -            if(sr.compareTo("postmaster") == 0) {
  -                rv = getMailetContext().getPostmaster();
  -                return rv;
  -            }
  -            if(sr.compareTo("sender") == 0) {
  -                return null;
  -            }
  -            try {
  -                rv = new MailAddress(sr);
  -                return rv;
  -            } catch(Exception e) {
  -                log("Parse error in getSender " + sr);
  -            }
  -        }
  -        return null;
  -    }
  -
  -    /**
  -* return true to reduce calls to getTo, getSender, getRecipients, getReplyTo amd getMessage
  -* where these values don't change (eg hard coded, or got at startup from the mailet config)<br>
  -* return false where any of these methods generate their results dynamically eg in response to the message being processed,
  -* or by refrence to a repository of users
  -*/
  -    public boolean isStatic() {
  -        if(getInitParameter("static") == null) {
  -            return false;
  -        }
  -        return new Boolean(getInitParameter("static")).booleanValue();
  -    }
  -
  -    /**
  -* return a prefix for the message subject
  -*/
  -    public String getSubjectPrefix() {
  -        if(getInitParameter("prefix") == null) {
  -            return "";
  -        } else {
  -            return getInitParameter("prefix");
  -        }
  -    }
  -
  -    /**
  -* returns an array of InternetAddress 'es for the To: header
  -*/
  -    public InternetAddress[] getTo() {
  -        String addressList        = (getInitParameter("to") == null)
  -                                        ? getInitParameter("recipients") : getInitParameter("to");
  -        StringTokenizer rec       = new StringTokenizer(addressList, ",");
  -        int tokensn               = rec.countTokens();
  -        InternetAddress[] iaarray = new InternetAddress[tokensn];
  -        String tokenx             = "";
  -        for(int i = 0; i < tokensn; ++i) {
  -            try {
  -                tokenx     = rec.nextToken();
  -                iaarray[i] = new InternetAddress(tokenx);
  -            } catch(Exception e) {
  -                log("Internet address exception in getTo()");
  -            }
  -        }
  -        return iaarray;
  -    }
  -
  -    /**
  -* return true to append a description of any error to the main body part
  -* if getInlineType does not return "UNALTERED"
  -*/
  -    public boolean attachError() {
  -        if(getInitParameter("attachError") == null) {
  -            return false;
  -        } else {
  -            return new Boolean(getInitParameter("attachError")).booleanValue();
  -        }
  -    }
  -
  -    /**
  -* init will setup static values for sender, recipients, message text, and reply to
  -* <br> if isStatic() returns true
  -* it calls getSender(), getReplyTo(), getMessage(), and getRecipients() and getTo()
  -*
  -*/
  -    public void init() throws MessagingException {
  -        log("redirect init");
  -        if(isStatic()) {
  -            sender       = (getSender() == null) ? getMailetContext().getPostmaster() : getSender();
  -            replyTo      = (getReplyTo() == null) ? getMailetContext().getPostmaster() : getReplyTo();
  -            messageText  = getMessage();
  -            recipients   = getRecipients();
  -            apparentlyTo = getTo();
  -            log("static, sender=" + sender + ", replyTo=" + replyTo + ", message=" + messageText +
  -                " ");
  -        }
  -    }
  -
  -    /**
  -*
  -* Service does the hard work,and redirects the mail in the form specified
  -*
  -*
  -*/
  -    public void service(Mail mail) throws MessagingException {
  -        if(!isStatic()) {
  -            sender       = getSender();
  -            replyTo      = getReplyTo();
  -            messageText  = getMessage();
  -            recipients   = getRecipients();
  -            apparentlyTo = getTo();
  -        }
  -        MimeMessage message = mail.getMessage();
  -        MimeMessage reply   = new MimeMessage(Session.getDefaultInstance(System.getProperties(),
  -                                                                         null));
  -        //Create the message
  -        if(getInLineType() != UNALTERED) {
  -            log("alter message inline=:" + getInLineType());
  -            StringWriter sout = new StringWriter();
  -            PrintWriter out   = new PrintWriter(sout, true);
  -            Enumeration heads = message.getAllHeaderLines();
  -            String head       = "";
  -            while(heads.hasMoreElements()) {
  -                head += (heads.nextElement().toString() + "\n");
  -            }
  -            boolean all = false;
  -            if(messageText != null) {
  -                out.println(messageText);
  -            }
  -            switch(getInLineType()) {
  -                case 3: //ALL:
  -                    all = true;
  -                case 1: //HEADS:
  -                    out.println("Message Headers:");
  -                    out.println(head);
  -                    if(!all) {
  -                        break;
  -                    }
  -                case 2: //BODY:
  -                    out.println("Message:");
  -                    try {
  -                        out.println(message.getContent().toString());
  -                    } catch(Exception e) {
  -                        out.println("body unavailable");
  -                    }
  -                    break;
  -                default:
  -                case 4: //NONE:
  -                    break;
  -            }
  -            MimeMultipart multipart = new MimeMultipart();
  -            //Add message as the first mime body part
  -            MimeBodyPart part       = new MimeBodyPart();
  -            part.setText(sout.toString());
  -            part.setDisposition("inline");
  -            multipart.addBodyPart(part);
  -            if(getAttachmentType() != NONE) {
  -                part = new MimeBodyPart();
  -                switch(getAttachmentType()) {
  -                    case 1: //HEADS:
  -                        part.setText(head);
  -                        break;
  -                    case 2: //BODY:
  -                        try {
  -                            part.setText(message.getContent().toString());
  -                        } catch(Exception e) {
  -                            part.setText("body unavailable");
  -                        }
  -                        break;
  -                    case 3: //ALL:
  -                        part.setText(head + "\n\n" + message.toString());
  -                        break;
  -                    case 5: //MESSAGE:
  -                        part.setContent(message, "message/rfc822");
  -                        break;
  -                }
  -                part.setDisposition("Attachment");
  -                multipart.addBodyPart(part);
  -            }
  -            reply.setContent(multipart);
  -            reply.setHeader("Content-Type", multipart.getContentType());
  -        } else {
  -            log("message resent unaltered:");
  -            reply = message;
  -        }
  -        //Set additional headers
  -        reply.setSubject(getSubjectPrefix() + message.getSubject());
  -        if(reply.getHeader("Date") == null) {
  -            reply.setHeader("Date", new RFC822Date().toString());
  -        }
  -        reply.setRecipients(Message.RecipientType.TO, apparentlyTo);
  -        if(replyTo != null) {
  -            InternetAddress[] iart = new InternetAddress[1];
  -            iart[0] = replyTo.toInternetAddress();
  -            reply.setReplyTo(iart);
  -        }
  -        if(sender == null) {
  -            reply.setHeader("From", message.getHeader("From", ","));
  -        } else {
  -            reply.setFrom(sender.toInternetAddress());
  -        }
  -        //Send it off...
  -        getMailetContext().sendMail(sender, recipients, reply);
  -        if(!getPassThrough()) {
  -            mail.setState(Mail.GHOST);
  -        }
  -    }
  -
  -    /**
  -* A private method to convert types from string to int.
  -*/
  -    private int getTypeCode(String param) {
  -        int code;
  -        param = param.toLowerCase();
  -        if(param.compareTo("unaltered") == 0) {
  -            return 0;
  -        }
  -        if(param.compareTo("heads") == 0) {
  -            return 1;
  -        }
  -        if(param.compareTo("body") == 0) {
  -            return 2;
  -        }
  -        if(param.compareTo("all") == 0) {
  -            return 3;
  -        }
  -        if(param.compareTo("none") == 0) {
  -            return 4;
  -        }
  -        if(param.compareTo("message") == 0) {
  -            return 5;
  -        }
  -        return 4;
  -    }
  -}
  \ No newline at end of file
  +/*
  + * Copyright (C) The Apache Software Foundation. All rights reserved.
  + *
  + * This software is published under the terms of the Apache Software License
  + * version 1.1, a copy of which has been included with this distribution in
  + * the LICENSE file.
  + */
  +package org.apache.james.transport.mailets;
  +
  +import java.io.PrintWriter;
  +import java.io.StringWriter;
  +
  +import java.util.Collection;
  +import java.util.Date;
  +import java.util.Enumeration;
  +import java.util.HashSet;
  +import java.util.StringTokenizer;
  +
  +import javax.mail.Message;
  +import javax.mail.MessagingException;
  +import javax.mail.Session;
  +import javax.mail.internet.InternetAddress;
  +import javax.mail.internet.MimeBodyPart;
  +import javax.mail.internet.MimeMessage;
  +import javax.mail.internet.MimeMultipart;
  +
  +import org.apache.james.util.RFC822DateFormat;
  +
  +import org.apache.mailet.GenericMailet;
  +import org.apache.mailet.Mail;
  +import org.apache.mailet.MailAddress;
  +
  +
  +/**
  +*<P>A mailet providing configurable redirection services<BR>
  +*This mailet can produce listserver, forward and notify behaviour, with the original
  +*message intact, attached, appended or left out altogether.<BR>
  +*This built in functionality is controlled by the configuration as laid out below.</P>
  +*<P>However it is also designed to be easily subclassed to make authoring redirection
  +*mailets simple. <BR>
  +*By extending it and overriding one or more of these methods new behaviour can
  +*be quickly created without the author having to address any other issue than
  +*the relevant one:</P>
  +*<UL>
  +*<LI>attachError() , should error messages be appended to the message</LI>
  +*<LI>getAttachementType(), what should be attached to the message</LI>
  +*<LI>getInLineType(), what should be included in the message</LI>
  +*<LI>getMessage(), The text of the message itself</LI>
  +*<LI>getRecipients(), the recipients the mail is sent to</LI>
  +*<LI>getReplyTo(), where replys to this message will be sent</LI>
  +*<LI>getSender(), who the mail is from</LI>
  +*<LI>getSubjectPrefix(), a prefix to be added to the message subject</LI>
  +*<LI>getTo(), a list of people to whom the mail is *apparently* sent</LI>
  +*<LI>getPassThrough(), should this mailet GHOST the original message.</LI>
  +*<LI>isStatic(), should this mailet run the get methods for every mail, or just
  +*once. </LI>
  +*</UL>
  +*<P>The configuration parameters are:</P>
  +*<TABLE width="75%" border="0" cellspacing="2" cellpadding="2">
  +*<TR>
  +*<TD width="20%">&lt;recipients&gt;</TD>
  +*<TD width="80%">A comma delimited list of email addresses for recipients of
  +*this message, it will use the &quot;to&quot; list if not specified. These
  +*addresses will only appear in the To: header if no &quot;to&quot; list is
  +*supplied.</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;to&gt;</TD>
  +*<TD width="80%">A comma delimited list of addresses to appear in the To: header,
  +*the email will only be delivered to these addresses if they are in the recipients
  +*list.<BR>
  +*The recipients list will be used if this is not supplied</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;sender&gt;</TD>
  +*<TD width="80%">A single email address to appear in the From: header <BR>
  +*It can include constants &quot;sender&quot; and &quot;postmaster&quot;</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;message&gt;</TD>
  +*<TD width="80%">A text message to be the body of the email. Can be omitted.</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;inline&gt;</TD>
  +*<TD width="80%">
  +*<P>One of the following items:</P>
  +*<UL>
  +*<LI>unaltered &nbsp;&nbsp;&nbsp;&nbsp;The original message is the new
  +* message, for forwarding/aliasing</LI>
  +*<LI>heads&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The
  +* headers of the original message are appended to the message</LI>
  +*<LI>body&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The
  +* body of the original is appended to the new message</LI>
  +*<LI>all&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Both
  +* headers and body are appended</LI>
  +*<LI>none&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Neither
  +* body nor headers are appended</LI>
  +*</UL>
  +*</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;attachment&gt;</TD>
  +*<TD width="80%">
  +*<P>One of the following items:</P>
  +*<UL>
  +*<LI>heads&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The headers of the original
  +* are attached as text</LI>
  +*<LI>body&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The body of the original
  +* is attached as text</LI>
  +*<LI>all&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Both
  +* headers and body are attached as a single text file</LI>
  +*<LI>none&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nothing is attached</LI>
  +*<LI>message &nbsp;The original message is attached as type message/rfc822,
  +* this means that it can, in many cases, be opened, resent, fw'd, replied
  +* to etc by email client software.</LI>
  +*</UL>
  +*</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;passThrough&gt;</TD>
  +*<TD width="80%">TRUE or FALSE, if true the original message continues in the
  +*mailet processor after this mailet is finished. False causes the original
  +*to be stopped.</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;attachError&gt;</TD>
  +*<TD width="80%">TRUE or FALSE, if true any error message available to the
  +*mailet is appended to the message body (except in the case of inline ==
  +*unaltered)</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;replyto&gt;</TD>
  +*<TD width="80%">A single email address to appear in the Rely-To: header, can
  +*also be &quot;sender&quot; or &quot;postmaster&quot;, this header is not
  +*set if this is omited.</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;prefix&gt;</TD>
  +*<TD width="80%">An optional subject prefix prepended to the original message
  +*subject, for example..<BR>
  +*Undeliverable mail:</TD>
  +*</TR>
  +*<TR>
  +*<TD width="20%">&lt;static&gt;</TD>
  +*<TD width="80%">
  +*<P>TRUE or FALSE, if this is true it hints to the mailet that none of the
  +*parameters are set dynamically, and therefore they can be set once in
  +*the init method.<BR>
  +*False tells the mailet to call all the &quot;getters&quot; for every mail
  +*processed.</P>
  +*<P>This defaults to false.<BR>
  +*It should be TRUE in all cases, except where one of the getter methods
  +*has been overriden to provide dynamic values, such as a listserve which
  +*might override getRecipients() to get a list from a users repository.</P>
  +*</TD>
  +*</TR>
  +*</TABLE>
  +*
  +*<P>Example:</P>
  +*<P> &lt;mailet match=&quot;RecipientIs=test@localhost&quot; class=&quot;Redirect&quot;&gt;<BR>
  +*&lt;recipients&gt;x@localhost, y@localhost, z@localhost&lt;/recipients&gt;<BR>
  +*&lt;to&gt;list@localhost&lt;/to&gt;<BR>
  +*&lt;sender&gt;owner@localhost&lt;/sender&gt;<BR>
  +*&lt;message&gt;sent on from James&lt;/message&gt;<BR>
  +*&lt;inline&gt;unaltered&lt;/inline&gt;<BR>
  +*&lt;passThrough&gt;FALSE&lt;/passThrough&gt;<BR>
  +*&lt;replyto&gt;postmaster&lt;/replyto&gt;<BR>
  +*&lt;prefix&gt;[test mailing]&lt;/prefix&gt;<BR>
  +*&lt;static&gt;TRUE&lt;/static&gt;<BR>
  +*&lt;passThrough&gt;FALSE&lt;/passThrough&gt;<BR>
  +*&lt;/mailet&gt;<BR>
  +*</P>
  +*<P>and:</P>
  +*<P> &lt;mailet match=&quot;All&quot; class=&quot;Redirect&quot;&gt;<BR>
  +*&lt;recipients&gt;x@localhost&lt;/recipients&gt;<BR>
  +*&lt;sender&gt;postmaster&lt;/sender&gt;<BR>
  +*&lt;message&gt;Message marked as spam:<BR>
  +*&lt;/message&gt;<BR>
  +*&lt;inline&gt;heads&lt;/inline&gt;<BR>
  +*&lt;attachment&gt;message&lt;/attachment&gt;<BR>
  +*&lt;passThrough&gt;FALSE&lt;/passThrough&gt;<BR>
  +*&lt;attachError&gt;TRUE&lt;/attachError&gt;<BR>
  +*&lt;replyto&gt;postmaster&lt;/replyto&gt;<BR>
  +*&lt;prefix&gt;[spam notification]&lt;/prefix&gt;<BR>
  +*&lt;static&gt;TRUE&lt;/static&gt;<BR>
  +*&lt;passThrough&gt;FALSE&lt;/passThrough&gt;<BR>
  +*&lt;/mailet&gt;</P>
  + *
  + * @author  Danny Angus   <da...@thought.co.uk>
  + *
  + */
  +public class Redirect extends GenericMailet {
  +    private static final int UNALTERED           = 0;
  +    private static final int HEADS               = 1;
  +    private static final int BODY                = 2;
  +    private static final int ALL                 = 3;
  +    private static final int NONE                = 4;
  +    private static final int MESSAGE             = 5;
  +    private InternetAddress[] apparentlyTo;
  +    private String messageText;
  +    private Collection recipients;
  +    private MailAddress replyTo;
  +    private MailAddress sender;
  +
  +    private RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();
  +
  +    /**
  +     *     returns one of these values to indicate how to attach the original message
  +     *<ul>
  +     *    <li>BODY : original message body is attached as plain text to the new message</li>
  +     *    <li>HEADS : original message headers are attached as plain text to the new message</li>
  +     *    <li>ALL : original is attached as plain text with all headers</li>
  +     *    <li>MESSAGE : original message is attached as type message/rfc822, a complete mail message.</li>
  +     *    <li>NONE : original is not attached</li>
  +     *</ul>
  +     *
  +     */
  +    public int getAttachmentType() {
  +        if(getInitParameter("attachment") == null) {
  +            return NONE;
  +        } else {
  +            return getTypeCode(getInitParameter("attachment"));
  +        }
  +    }
  +
  +    /**
  +* returns one of these values to indicate how to append the original message
  +*<ul>
  +*    <li>UNALTERED : original message is the new message body</li>
  +*    <li>BODY : original message body is appended to the new message</li>
  +*    <li>HEADS : original message headers are appended to the new message</li>
  +*    <li>ALL : original is appended with all headers</li>
  +*    <li>NONE : original is not appended</li>
  +*</ul>
  +*/
  +    public int getInLineType() {
  +        if(getInitParameter("inline") == null) {
  +            return BODY;
  +        } else {
  +            return getTypeCode(getInitParameter("inline"));
  +        }
  +    }
  +
  +    /**
  +     * Add Description
  +     *
  +     * @return Document return!
  +     */
  +    public String getMailetInfo() {
  +        return "Resend Mailet";
  +    }
  +
  +    /**
  +* must return either an empty string, or a message to which the redirect can be attached/appended
  +*/
  +    public String getMessage() {
  +        if(getInitParameter("message") == null) {
  +            return "";
  +        } else {
  +            return getInitParameter("message");
  +        }
  +    }
  +
  +    /**
  +* return true to allow thie original message to continue through the processor, false to GHOST it
  +*/
  +    public boolean getPassThrough() {
  +        if(getInitParameter("passThrough") == null) {
  +            return false;
  +        } else {
  +            return new Boolean(getInitParameter("passThrough")).booleanValue();
  +        }
  +    }
  +
  +    /**
  +* must return a Collection of recipient MailAddress'es
  +*/
  +    public Collection getRecipients() {
  +        Collection newRecipients           = new HashSet();
  +        String addressList                 = (getInitParameter("recipients") == null)
  +                                                 ? getInitParameter("to")
  +                                                 : getInitParameter("recipients");
  +        StringTokenizer st                 = new StringTokenizer(addressList, ",", false);
  +        while(st.hasMoreTokens()) {
  +            try {
  +                newRecipients.add(new MailAddress(st.nextToken()));
  +            } catch(Exception e) {
  +                log("add recipient failed in getRecipients");
  +            }
  +        }
  +        return newRecipients;
  +    }
  +
  +    /**
  +* return the reply to address as a string
  +*/
  +    public MailAddress getReplyTo() {
  +        String sr = getInitParameter("replyto");
  +        if(sr != null) {
  +            MailAddress rv;
  +            if(sr.compareTo("postmaster") == 0) {
  +                rv = getMailetContext().getPostmaster();
  +                return rv;
  +            }
  +            if(sr.compareTo("sender") == 0) {
  +                return null;
  +            }
  +            try {
  +                rv = new MailAddress(sr);
  +                return rv;
  +            } catch(Exception e) {
  +                log("Parse error in getReplyTo " + sr);
  +            }
  +        }
  +        return null;
  +    }
  +
  +    /**
  +* returns the senders address, as a MailAddress
  +*/
  +    public MailAddress getSender() {
  +        String sr = getInitParameter("sender");
  +        if(sr != null) {
  +            MailAddress rv;
  +            if(sr.compareTo("postmaster") == 0) {
  +                rv = getMailetContext().getPostmaster();
  +                return rv;
  +            }
  +            if(sr.compareTo("sender") == 0) {
  +                return null;
  +            }
  +            try {
  +                rv = new MailAddress(sr);
  +                return rv;
  +            } catch(Exception e) {
  +                log("Parse error in getSender " + sr);
  +            }
  +        }
  +        return null;
  +    }
  +
  +    /**
  +* return true to reduce calls to getTo, getSender, getRecipients, getReplyTo amd getMessage
  +* where these values don't change (eg hard coded, or got at startup from the mailet config)<br>
  +* return false where any of these methods generate their results dynamically eg in response to the message being processed,
  +* or by refrence to a repository of users
  +*/
  +    public boolean isStatic() {
  +        if(getInitParameter("static") == null) {
  +            return false;
  +        }
  +        return new Boolean(getInitParameter("static")).booleanValue();
  +    }
  +
  +    /**
  +* return a prefix for the message subject
  +*/
  +    public String getSubjectPrefix() {
  +        if(getInitParameter("prefix") == null) {
  +            return "";
  +        } else {
  +            return getInitParameter("prefix") + " ";
  +        }
  +    }
  +
  +    /**
  +* returns an array of InternetAddress 'es for the To: header
  +*/
  +    public InternetAddress[] getTo() {
  +        String addressList        = (getInitParameter("to") == null)
  +                                        ? getInitParameter("recipients") : getInitParameter("to");
  +        StringTokenizer rec       = new StringTokenizer(addressList, ",");
  +        int tokensn               = rec.countTokens();
  +        InternetAddress[] iaarray = new InternetAddress[tokensn];
  +        String tokenx             = "";
  +        for(int i = 0; i < tokensn; ++i) {
  +            try {
  +                tokenx     = rec.nextToken();
  +                iaarray[i] = new InternetAddress(tokenx);
  +            } catch(Exception e) {
  +                log("Internet address exception in getTo()");
  +            }
  +        }
  +        return iaarray;
  +    }
  +
  +    /**
  +* return true to append a description of any error to the main body part
  +* if getInlineType does not return "UNALTERED"
  +*/
  +    public boolean attachError() {
  +        if(getInitParameter("attachError") == null) {
  +            return false;
  +        } else {
  +            return new Boolean(getInitParameter("attachError")).booleanValue();
  +        }
  +    }
  +
  +    /**
  +* init will setup static values for sender, recipients, message text, and reply to
  +* <br> if isStatic() returns true
  +* it calls getSender(), getReplyTo(), getMessage(), and getRecipients() and getTo()
  +*
  +*/
  +    public void init() throws MessagingException {
  +        log("redirect init");
  +        if(isStatic()) {
  +            sender       = (getSender() == null) ? getMailetContext().getPostmaster() : getSender();
  +            replyTo      = (getReplyTo() == null) ? getMailetContext().getPostmaster() : getReplyTo();
  +            messageText  = getMessage();
  +            recipients   = getRecipients();
  +            apparentlyTo = getTo();
  +            StringBuffer logBuffer = new StringBuffer("static, sender=");
  +            logBuffer.append(sender);
  +            logBuffer.append(", replyTo=");
  +            logBuffer.append(replyTo);
  +            logBuffer.append(", message=");
  +            logBuffer.append(messageText);
  +            logBuffer.append(" ");
  +            log(logBuffer.toString());
  +        }
  +    }
  +
  +    /**
  +*
  +* Service does the hard work,and redirects the mail in the form specified
  +*
  +*
  +*/
  +    public void service(Mail mail) throws MessagingException {
  +        if(!isStatic()) {
  +            sender       = getSender();
  +            replyTo      = getReplyTo();
  +            messageText  = getMessage();
  +            recipients   = getRecipients();
  +            apparentlyTo = getTo();
  +        }
  +        MimeMessage message = mail.getMessage();
  +        MimeMessage reply   = new MimeMessage(Session.getDefaultInstance(System.getProperties(),
  +                                                                         null));
  +        //Create the message
  +        if(getInLineType() != UNALTERED) {
  +            log("alter message inline=:" + getInLineType());
  +            StringWriter sout = new StringWriter();
  +            PrintWriter out   = new PrintWriter(sout, true);
  +            Enumeration heads = message.getAllHeaderLines();
  +            String head       = "";
  +            StringBuffer headBuffer = new StringBuffer();
  +            while(heads.hasMoreElements()) {
  +                headBuffer.append(heads.nextElement().toString());
  +                headBuffer.append("\n");
  +            }
  +            head = headBuffer.toString();
  +            boolean all = false;
  +            if(messageText != null) {
  +                out.println(messageText);
  +            }
  +            switch(getInLineType()) {
  +                case ALL: //ALL:
  +                    all = true;
  +                case HEADS: //HEADS:
  +                    out.println("Message Headers:");
  +                    out.println(head);
  +                    if(!all) {
  +                        break;
  +                    }
  +                case BODY: //BODY:
  +                    out.println("Message:");
  +                    try {
  +                        out.println(message.getContent().toString());
  +                    } catch(Exception e) {
  +                        out.println("body unavailable");
  +                    }
  +                    break;
  +                default:
  +                case NONE: //NONE:
  +                    break;
  +            }
  +            MimeMultipart multipart = new MimeMultipart();
  +            //Add message as the first mime body part
  +            MimeBodyPart part       = new MimeBodyPart();
  +            part.setText(sout.toString());
  +            part.setDisposition("inline");
  +            multipart.addBodyPart(part);
  +            if(getAttachmentType() != NONE) {
  +                part = new MimeBodyPart();
  +                switch(getAttachmentType()) {
  +                    case HEADS: //HEADS:
  +                        part.setText(head);
  +                        break;
  +                    case BODY: //BODY:
  +                        try {
  +                            part.setText(message.getContent().toString());
  +                        } catch(Exception e) {
  +                            part.setText("body unavailable");
  +                        }
  +                        break;
  +                    case ALL: //ALL:
  +                        StringBuffer textBuffer = new StringBuffer(head);
  +                        textBuffer.append("\n\n");
  +                        textBuffer.append(message.toString());
  +                        part.setText(textBuffer.toString());
  +                        break;
  +                    case MESSAGE: //MESSAGE:
  +                        part.setContent(message, "message/rfc822");
  +                        break;
  +                }
  +                part.setDisposition("Attachment");
  +                multipart.addBodyPart(part);
  +            }
  +            reply.setContent(multipart);
  +            reply.setHeader("Content-Type", multipart.getContentType());
  +        } else {
  +            log("message resent unaltered:");
  +            reply = message;
  +        }
  +        //Set additional headers
  +        reply.setSubject(getSubjectPrefix() + message.getSubject());
  +        if(reply.getHeader("Date") == null) {
  +            reply.setHeader("Date", rfc822DateFormat.format(new Date()));
  +        }
  +        reply.setRecipients(Message.RecipientType.TO, apparentlyTo);
  +        if(replyTo != null) {
  +            InternetAddress[] iart = new InternetAddress[1];
  +            iart[0] = replyTo.toInternetAddress();
  +            reply.setReplyTo(iart);
  +        }
  +        if(sender == null) {
  +            reply.setHeader("From", message.getHeader("From", ","));
  +            sender = new MailAddress(((InternetAddress)message.getFrom()[0]).getAddress());
  +        } else {
  +            reply.setFrom(sender.toInternetAddress());
  +        }
  +        //Send it off...
  +        getMailetContext().sendMail(sender, recipients, reply);
  +        if(!getPassThrough()) {
  +            mail.setState(Mail.GHOST);
  +        }
  +    }
  +
  +    /**
  +* A private method to convert types from string to int.
  +*/
  +    private int getTypeCode(String param) {
  +        int code;
  +        param = param.toLowerCase();
  +        if(param.compareTo("unaltered") == 0) {
  +            return UNALTERED;
  +        }
  +        if(param.compareTo("heads") == 0) {
  +            return HEADS;
  +        }
  +        if(param.compareTo("body") == 0) {
  +            return BODY;
  +        }
  +        if(param.compareTo("all") == 0) {
  +            return ALL;
  +        }
  +        if(param.compareTo("none") == 0) {
  +            return NONE;
  +        }
  +        if(param.compareTo("message") == 0) {
  +            return MESSAGE;
  +        }
  +        return NONE;
  +    }
  +}
  
  
  
  1.5       +5 -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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- NotifySender.java	18 Jan 2002 02:48:38 -0000	1.4
  +++ NotifySender.java	28 Jul 2002 11:46:41 -0000	1.5
  @@ -7,7 +7,7 @@
    */
   package org.apache.james.transport.mailets;
   
  -import org.apache.james.util.RFC822Date;
  +import org.apache.james.util.RFC822DateFormat;
   import org.apache.mailet.GenericMailet;
   import org.apache.mailet.Mail;
   import org.apache.mailet.MailAddress;
  @@ -24,6 +24,7 @@
   import java.io.IOException;
   import java.io.PrintWriter;
   import java.io.StringWriter;
  +import java.util.Date;
   import java.util.HashSet;
   import java.util.Set;
   
  @@ -48,6 +49,8 @@
       boolean attachStackTrace = false;
       String noticeText = null;
   
  +    private RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();
  +
       public void init() throws MessagingException {
           if (getInitParameter("sendingAddress") == null) {
               notifier = getMailetContext().getPostmaster();
  @@ -160,7 +163,7 @@
   
           //Set additional headers
           if (reply.getHeader("Date")==null){
  -            reply.setHeader("Date",new RFC822Date().toString());
  +            reply.setHeader("Date", rfc822DateFormat.format(new Date()));
           }
           String subject = message.getSubject();
           if (subject == null) {
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>