Index: src/java/org/apache/james/transport/mailets/AbstractRedirect.java
===================================================================
RCS file: /home/cvspublic/jakarta-james/src/java/org/apache/james/transport/mailets/AbstractRedirect.java,v
retrieving revision 1.1.2.13
diff -u -r1.1.2.13 AbstractRedirect.java
--- src/java/org/apache/james/transport/mailets/AbstractRedirect.java	27 Jun 2003 14:34:37 -0000	1.1.2.13
+++ src/java/org/apache/james/transport/mailets/AbstractRedirect.java	29 Jun 2003 17:47:23 -0000
@@ -1004,13 +1004,17 @@
      */
     protected void setSubjectPrefix(Mail newMail, String subjectPrefix, Mail originalMail) throws MessagingException {
         String subject = getSubject(originalMail);
+        if (subject == null && (subjectPrefix == null || subjectPrefix.length() == 0)) {
+            return; // no change
+        } 
         if (subject == null) {
             subject = originalMail.getMessage().getSubject();
         }
         if (subject == null) {
             subject = "";
         }
-        newMail.getMessage().setSubject(subjectPrefix + subject);
+        if (subjectPrefix != null) subject = subjectPrefix + subject;
+        changeSubject(newMail.getMessage(), subject);
         if (isDebug) {
             log("subjectPrefix set to: " + subjectPrefix);
         }
@@ -1705,4 +1709,88 @@
         }
     }
 
+    /**
+     * 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;
+    }
 }
Index: src/java/org/apache/james/transport/mailets/GenericListserv.java
===================================================================
RCS file: /home/cvspublic/jakarta-james/src/java/org/apache/james/transport/mailets/GenericListserv.java,v
retrieving revision 1.12.4.5
diff -u -r1.12.4.5 GenericListserv.java
--- src/java/org/apache/james/transport/mailets/GenericListserv.java	29 May 2003 20:31:17 -0000	1.12.4.5
+++ src/java/org/apache/james/transport/mailets/GenericListserv.java	29 Jun 2003 17:47:26 -0000
@@ -198,90 +198,6 @@
     }
 
     /**
-     * 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.
      */
     public final void service(Mail mail) throws MessagingException {
@@ -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

