james-mime4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From b...@apache.org
Subject svn commit: r895488 - in /james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j: parser/impl/DefaultBodyDescriptor.java parser/impl/MaximalBodyDescriptor.java util/MimeUtil.java
Date Sun, 03 Jan 2010 21:53:43 GMT
Author: bago
Date: Sun Jan  3 21:53:42 2010
New Revision: 895488

URL: http://svn.apache.org/viewvc?rev=895488&view=rev
Log:
MimeUtil.getHeaderParams moved temporarily to DefaultFieldParser that was the only client
of that method (this helps organizing code. but I think that the entry points for field parsing
still needs improvement) (MIME4J-157)

Modified:
    james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/DefaultBodyDescriptor.java
    james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/MaximalBodyDescriptor.java
    james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/util/MimeUtil.java

Modified: james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/DefaultBodyDescriptor.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/DefaultBodyDescriptor.java?rev=895488&r1=895487&r2=895488&view=diff
==============================================================================
--- james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/DefaultBodyDescriptor.java
(original)
+++ james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/DefaultBodyDescriptor.java
Sun Jan  3 21:53:42 2010
@@ -126,7 +126,7 @@
     private void parseContentType(String value) {
         contentTypeSet = true;
         
-        Map<String, String> params = MimeUtil.getHeaderParams(value);
+        Map<String, String> params = DefaultBodyDescriptor.getHeaderParams(value);
         
         String main = params.get("");
         String type = null;
@@ -246,4 +246,185 @@
     public String getSubType() {
         return subType;
     }
+
+    /**
+     * <p>Parses a complex field value into a map of key/value pairs. You may
+     * use this, for example, to parse a definition like
+     * <pre>
+     *   text/plain; charset=UTF-8; boundary=foobar
+     * </pre>
+     * The above example would return a map with the keys "", "charset",
+     * and "boundary", and the values "text/plain", "UTF-8", and "foobar".
+     * </p><p>
+     * Header value will be unfolded and excess white space trimmed.
+     * </p>
+     * @param pValue The field value to parse.
+     * @return The result map; use the key "" to retrieve the first value.
+     */
+    public static Map<String, String> getHeaderParams(String pValue) {
+        pValue = pValue.trim();
+        
+        Map<String, String> result = new HashMap<String, String>();
+    
+        // split main value and parameters
+        String main;
+        String rest;
+        if (pValue.indexOf(";") == -1) {
+            main = pValue;
+            rest = null;
+        } else {
+            main = pValue.substring(0, pValue.indexOf(";"));
+            rest = pValue.substring(main.length() + 1);
+        }
+    
+        result.put("", main);
+        if (rest != null) {
+            char[] chars = rest.toCharArray();
+            StringBuilder paramName = new StringBuilder(64);
+            StringBuilder paramValue = new StringBuilder(64);
+    
+            final byte READY_FOR_NAME = 0;
+            final byte IN_NAME = 1;
+            final byte READY_FOR_VALUE = 2;
+            final byte IN_VALUE = 3;
+            final byte IN_QUOTED_VALUE = 4;
+            final byte VALUE_DONE = 5;
+            final byte ERROR = 99;
+    
+            byte state = READY_FOR_NAME;
+            boolean escaped = false;
+            for (char c : chars) {
+                switch (state) {
+                    case ERROR:
+                        if (c == ';')
+                            state = READY_FOR_NAME;
+                        break;
+    
+                    case READY_FOR_NAME:
+                        if (c == '=') {
+                            log.error("Expected header param name, got '='");
+                            state = ERROR;
+                            break;
+                        }
+    
+                        paramName.setLength(0);
+                        paramValue.setLength(0);
+    
+                        state = IN_NAME;
+                        // fall-through
+    
+                    case IN_NAME:
+                        if (c == '=') {
+                            if (paramName.length() == 0)
+                                state = ERROR;
+                            else
+                                state = READY_FOR_VALUE;
+                            break;
+                        }
+    
+                        // not '='... just add to name
+                        paramName.append(c);
+                        break;
+    
+                    case READY_FOR_VALUE:
+                        boolean fallThrough = false;
+                        switch (c) {
+                            case ' ':
+                            case '\t':
+                                break;  // ignore spaces, especially before '"'
+    
+                            case '"':
+                                state = IN_QUOTED_VALUE;
+                                break;
+    
+                            default:
+                                state = IN_VALUE;
+                                fallThrough = true;
+                                break;
+                        }
+                        if (!fallThrough)
+                            break;
+    
+                        // fall-through
+    
+                    case IN_VALUE:
+                        fallThrough = false;
+                        switch (c) {
+                            case ';':
+                            case ' ':
+                            case '\t':
+                                result.put(
+                                   paramName.toString().trim().toLowerCase(),
+                                   paramValue.toString().trim());
+                                state = VALUE_DONE;
+                                fallThrough = true;
+                                break;
+                            default:
+                                paramValue.append(c);
+                                break;
+                        }
+                        if (!fallThrough)
+                            break;
+    
+                    case VALUE_DONE:
+                        switch (c) {
+                            case ';':
+                                state = READY_FOR_NAME;
+                                break;
+    
+                            case ' ':
+                            case '\t':
+                                break;
+    
+                            default:
+                                state = ERROR;
+                                break;
+                        }
+                        break;
+                        
+                    case IN_QUOTED_VALUE:
+                        switch (c) {
+                            case '"':
+                                if (!escaped) {
+                                    // don't trim quoted strings; the spaces could be intentional.
+                                    result.put(
+                                            paramName.toString().trim().toLowerCase(),
+                                            paramValue.toString());
+                                    state = VALUE_DONE;
+                                } else {
+                                    escaped = false;
+                                    paramValue.append(c);                               
    
+                                }
+                                break;
+                                
+                            case '\\':
+                                if (escaped) {
+                                    paramValue.append('\\');
+                                }
+                                escaped = !escaped;
+                                break;
+    
+                            default:
+                                if (escaped) {
+                                    paramValue.append('\\');
+                                }
+                                escaped = false;
+                                paramValue.append(c);
+                                break;
+                        }
+                        break;
+    
+                }
+            }
+    
+            // done looping.  check if anything is left over.
+            if (state == IN_VALUE) {
+                result.put(
+                        paramName.toString().trim().toLowerCase(),
+                        paramValue.toString().trim());
+            }
+        }
+    
+        return result;
+    }
 }

Modified: james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/MaximalBodyDescriptor.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/MaximalBodyDescriptor.java?rev=895488&r1=895487&r2=895488&view=diff
==============================================================================
--- james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/MaximalBodyDescriptor.java
(original)
+++ james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/parser/impl/MaximalBodyDescriptor.java
Sun Jan  3 21:53:42 2010
@@ -175,7 +175,7 @@
 
     private void parseContentDisposition(final String value) {
         isContentDispositionSet = true;
-        contentDispositionParameters = MimeUtil.getHeaderParams(value);
+        contentDispositionParameters = DefaultBodyDescriptor.getHeaderParams(value);
         contentDispositionType = contentDispositionParameters.get("");
         
         final String contentDispositionModificationDate 

Modified: james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/util/MimeUtil.java
URL: http://svn.apache.org/viewvc/james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/util/MimeUtil.java?rev=895488&r1=895487&r2=895488&view=diff
==============================================================================
--- james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/util/MimeUtil.java
(original)
+++ james/mime4j/branches/cycleclean/core/src/main/java/org/apache/james/mime4j/util/MimeUtil.java
Sun Jan  3 21:53:42 2010
@@ -24,20 +24,14 @@
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.GregorianCalendar;
-import java.util.HashMap;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Random;
 import java.util.TimeZone;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 /**
  * A utility class, which provides some MIME related application logic.
  */
 public final class MimeUtil {
-    private static final Log log = LogFactory.getLog(MimeUtil.class);
     
     /**
      * The <code>quoted-printable</code> encoding.
@@ -159,193 +153,21 @@
     }
 
     /**
-     * <p>Parses a complex field value into a map of key/value pairs. You may
-     * use this, for example, to parse a definition like
-     * <pre>
-     *   text/plain; charset=UTF-8; boundary=foobar
-     * </pre>
-     * The above example would return a map with the keys "", "charset",
-     * and "boundary", and the values "text/plain", "UTF-8", and "foobar".
-     * </p><p>
-     * Header value will be unfolded and excess white space trimmed.
-     * </p>
-     * @param pValue The field value to parse.
-     * @return The result map; use the key "" to retrieve the first value.
-     */
-    @SuppressWarnings("fallthrough")
-    public static Map<String, String> getHeaderParams(String pValue) {
-        pValue = pValue.trim();
-        
-        Map<String, String> result = new HashMap<String, String>();
-
-        // split main value and parameters
-        String main;
-        String rest;
-        if (pValue.indexOf(";") == -1) {
-            main = pValue;
-            rest = null;
-        } else {
-            main = pValue.substring(0, pValue.indexOf(";"));
-            rest = pValue.substring(main.length() + 1);
-        }
-
-        result.put("", main);
-        if (rest != null) {
-            char[] chars = rest.toCharArray();
-            StringBuilder paramName = new StringBuilder(64);
-            StringBuilder paramValue = new StringBuilder(64);
-
-            final byte READY_FOR_NAME = 0;
-            final byte IN_NAME = 1;
-            final byte READY_FOR_VALUE = 2;
-            final byte IN_VALUE = 3;
-            final byte IN_QUOTED_VALUE = 4;
-            final byte VALUE_DONE = 5;
-            final byte ERROR = 99;
-
-            byte state = READY_FOR_NAME;
-            boolean escaped = false;
-            for (char c : chars) {
-                switch (state) {
-                    case ERROR:
-                        if (c == ';')
-                            state = READY_FOR_NAME;
-                        break;
-
-                    case READY_FOR_NAME:
-                        if (c == '=') {
-                            log.error("Expected header param name, got '='");
-                            state = ERROR;
-                            break;
-                        }
-
-                        paramName.setLength(0);
-                        paramValue.setLength(0);
-
-                        state = IN_NAME;
-                        // fall-through
-
-                    case IN_NAME:
-                        if (c == '=') {
-                            if (paramName.length() == 0)
-                                state = ERROR;
-                            else
-                                state = READY_FOR_VALUE;
-                            break;
-                        }
-
-                        // not '='... just add to name
-                        paramName.append(c);
-                        break;
-
-                    case READY_FOR_VALUE:
-                        boolean fallThrough = false;
-                        switch (c) {
-                            case ' ':
-                            case '\t':
-                                break;  // ignore spaces, especially before '"'
-
-                            case '"':
-                                state = IN_QUOTED_VALUE;
-                                break;
-
-                            default:
-                                state = IN_VALUE;
-                                fallThrough = true;
-                                break;
-                        }
-                        if (!fallThrough)
-                            break;
-
-                        // fall-through
-
-                    case IN_VALUE:
-                        fallThrough = false;
-                        switch (c) {
-                            case ';':
-                            case ' ':
-                            case '\t':
-                                result.put(
-                                   paramName.toString().trim().toLowerCase(),
-                                   paramValue.toString().trim());
-                                state = VALUE_DONE;
-                                fallThrough = true;
-                                break;
-                            default:
-                                paramValue.append(c);
-                                break;
-                        }
-                        if (!fallThrough)
-                            break;
-
-                    case VALUE_DONE:
-                        switch (c) {
-                            case ';':
-                                state = READY_FOR_NAME;
-                                break;
-
-                            case ' ':
-                            case '\t':
-                                break;
-
-                            default:
-                                state = ERROR;
-                                break;
-                        }
-                        break;
-                        
-                    case IN_QUOTED_VALUE:
-                        switch (c) {
-                            case '"':
-                                if (!escaped) {
-                                    // don't trim quoted strings; the spaces could be intentional.
-                                    result.put(
-                                            paramName.toString().trim().toLowerCase(),
-                                            paramValue.toString());
-                                    state = VALUE_DONE;
-                                } else {
-                                    escaped = false;
-                                    paramValue.append(c);                               
    
-                                }
-                                break;
-                                
-                            case '\\':
-                                if (escaped) {
-                                    paramValue.append('\\');
-                                }
-                                escaped = !escaped;
-                                break;
-
-                            default:
-                                if (escaped) {
-                                    paramValue.append('\\');
-                                }
-                                escaped = false;
-                                paramValue.append(c);
-                                break;
-                        }
-                        break;
-
-                }
-            }
-
-            // done looping.  check if anything is left over.
-            if (state == IN_VALUE) {
-                result.put(
-                        paramName.toString().trim().toLowerCase(),
-                        paramValue.toString().trim());
-            }
-        }
-
-        return result;
-    }
-
-    /**
      * Creates a new unique message boundary string that can be used as boundary
      * parameter for the Content-Type header field of a message.
      * 
      * @return a new unique message boundary string.
      */
+    /* TODO - From rfc2045:
+     * Since the hyphen character ("-") may be represented as itself in the
+     * Quoted-Printable encoding, care must be taken, when encapsulating a
+     * quoted-printable encoded body inside one or more multipart entities,
+     * to ensure that the boundary delimiter does not appear anywhere in the
+     * encoded body.  (A good strategy is to choose a boundary that includes
+     * a character sequence such as "=_" which can never appear in a
+     * quoted-printable body.  See the definition of multipart messages in
+     * RFC 2046.)
+     */
     public static String createUniqueBoundary() {
         StringBuilder sb = new StringBuilder();
         sb.append("-=Part.");



Mime
View raw message