You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mime4j-dev@james.apache.org by ol...@apache.org on 2011/07/13 16:17:20 UTC

svn commit: r1146050 - in /james/mime4j/trunk/core/src: main/java/org/apache/james/mime4j/codec/ main/java/org/apache/james/mime4j/parser/ main/java/org/apache/james/mime4j/stream/ main/javadoc/ test/java/org/apache/james/mime4j/stream/

Author: olegk
Date: Wed Jul 13 14:17:19 2011
New Revision: 1146050

URL: http://svn.apache.org/viewvc?rev=1146050&view=rev
Log:
Updated javadocs for mime4j core api

Removed:
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/LenientFieldBuilder.java
    james/mime4j/trunk/core/src/test/java/org/apache/james/mime4j/stream/LenientFieldBuilderTest.java
Modified:
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/codec/DecodeMonitor.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/AbstractContentHandler.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/ContentHandler.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/MimeStreamParser.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptor.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptorBuilder.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/ContentDescriptor.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/DefaultFieldBuilder.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/Field.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/FieldBuilder.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeEntityConfig.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeTokenStream.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/NameValuePair.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawBody.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawField.java
    james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawFieldParser.java
    james/mime4j/trunk/core/src/main/javadoc/overview.html

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/codec/DecodeMonitor.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/codec/DecodeMonitor.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/codec/DecodeMonitor.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/codec/DecodeMonitor.java Wed Jul 13 14:17:19 2011
@@ -19,17 +19,15 @@
 
 package org.apache.james.mime4j.codec;
 
-
 /**
  * This class is used to drive how decoder/parser should deal with malformed
  * and unexpected data.
  *
  * 2 basic implementations are provided:
- * STRICT return "true" on any occurrence.
- * SILENT ignores any problem.
- *
- * @see org.apache.james.mime4j.field.LoggingMonitor for an example
- * about logging malformations via Commons-logging.
+ * <ul>
+ * <li>{@link #STRICT} return "true" on any occurrence</li>
+ * <li>{@link #SILENT} ignores any problem</li>
+ * </ul>
  */
 public class DecodeMonitor {
 

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/AbstractContentHandler.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/AbstractContentHandler.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/AbstractContentHandler.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/AbstractContentHandler.java Wed Jul 13 14:17:19 2011
@@ -27,10 +27,8 @@ import java.io.IOException;
 import java.io.InputStream;
 
 /**
- * Abstract <code>ContentHandler</code> with default implementations of all
- * the methods of the <code>ContentHandler</code> interface.
- *
- * The default is to do nothing.
+ * Abstract base class for custom {@link ContentHandler} implementations. Methods of this class
+ * take no action and are expected to be selectively overridden by super-classes.
  */
 public abstract class AbstractContentHandler implements ContentHandler {
 

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/ContentHandler.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/ContentHandler.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/ContentHandler.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/ContentHandler.java Wed Jul 13 14:17:19 2011
@@ -31,7 +31,7 @@ import java.io.InputStream;
  * Receives notifications of the content of a plain RFC822 or MIME message.
  * Implement this interface and register an instance of that implementation
  * with a <code>MimeStreamParser</code> instance using its
- * {@link org.apache.james.mime4j.stream.MimeStreamParser#setContentHandler(ContentHandler)}
+ * {@link org.apache.james.mime4j.parser.MimeStreamParser#setContentHandler(ContentHandler)}
  * method. The parser uses the <code>ContentHandler</code> instance to report
  * basic message-related events like the start and end of the body of a
  * part in a multipart MIME entity.
@@ -195,7 +195,7 @@ public interface ContentHandler {
      * @param is the raw contents of the entity.
      * @throws MimeException on processing errors
      * @throws IOException should be thrown on I/O errors.
-     * @see org.apache.james.mime4j.stream.MimeStreamParser#setRaw(boolean)
+     * @see org.apache.james.mime4j.parser.MimeStreamParser#setRaw()
      */
     void raw(InputStream is) throws MimeException, IOException;
 

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/MimeStreamParser.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/MimeStreamParser.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/MimeStreamParser.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/parser/MimeStreamParser.java Wed Jul 13 14:17:19 2011
@@ -35,50 +35,42 @@ import org.apache.james.mime4j.stream.Re
 /**
  * <p>
  * Parses MIME (or RFC822) message streams of bytes or characters and reports
- * parsing events to a <code>ContentHandler</code> instance.
+ * parsing events to a {@link ContentHandler} instance.
  * </p>
  * <p>
  * Typical usage:<br/>
  * <pre>
  *      ContentHandler handler = new MyHandler();
- *      MimeStreamParser parser = new MimeStreamParser();
+ *      MimeEntityConfig config = new MimeEntityConfig();
+ *      MimeStreamParser parser = new MimeStreamParser(config);
  *      parser.setContentHandler(handler);
- *      parser.parse(new FileInputStream("mime.msg"));
+ *      InputStream instream = new FileInputStream("mime.msg");
+ *      try {
+ *          parser.parse(instream);
+ *      } finally {
+ *          instream.close();
+ *      }
  * </pre>
  */
 public class MimeStreamParser {
 
     private ContentHandler handler = null;
     private boolean contentDecoding;
-    private final MimeEntityConfig mimeEntityConfig;
 
     private final MimeTokenStream mimeTokenStream;
 
     public MimeStreamParser(MimeTokenStream tokenStream) {
         super();
         this.mimeTokenStream = tokenStream;
-        this.mimeEntityConfig = tokenStream.getConfig();
         this.contentDecoding = false;
     }
 
     public MimeStreamParser(
             final MimeEntityConfig config,
-            boolean clone,
             final DecodeMonitor monitor,
             final BodyDescriptorBuilder bodyDescBuilder) {
-        this(new MimeTokenStream(clone ? config.clone() : config, monitor, bodyDescBuilder));
-    }
-
-    public MimeStreamParser(final MimeEntityConfig config, boolean clone) {
-        this(new MimeTokenStream(clone ? config.clone() : config, null, null));
-    }
-
-    public MimeStreamParser(
-            final MimeEntityConfig config,
-            final DecodeMonitor monitor,
-            final BodyDescriptorBuilder bodyDescBuilder) {
-        this(config != null ? config : new MimeEntityConfig(), config != null,
-                monitor, bodyDescBuilder);
+        this(new MimeTokenStream(config != null ? config.clone() : new MimeEntityConfig(),
+                monitor, bodyDescBuilder));
     }
 
     public MimeStreamParser(final MimeEntityConfig config) {
@@ -86,7 +78,7 @@ public class MimeStreamParser {
     }
 
     public MimeStreamParser() {
-        this(new MimeEntityConfig(), false, null, null);
+        this(new MimeTokenStream(new MimeEntityConfig(), null, null));
     }
 
     /**
@@ -106,23 +98,26 @@ public class MimeStreamParser {
     }
 
     /**
-     * Parses a stream of bytes containing a MIME message. If the mime config of this
-     * object contains a not null defaultContentType
-     * ({@link MimeEntityConfig#getDefaultContentType()}) a headless parsing is performed.
+     * Parses a stream of bytes containing a MIME message. Please note that if the
+     * {@link MimeEntityConfig} associated with the mime stream returns a not null Content-Type
+     * value from its {@link MimeEntityConfig#getHeadlessParsing()} method, the message is
+     * assumed to have no head section and the headless parsing mode will be used.
      *
-     * @param is the stream to parse.
+     * @param instream the stream to parse.
      * @throws MimeException if the message can not be processed
      * @throws IOException on I/O errors.
      */
-    public void parse(InputStream inputStream) throws MimeException, IOException {
-        if (mimeEntityConfig.getHeadlessParsing() != null) {
-            Field contentType = mimeTokenStream.parseHeadless(inputStream, mimeEntityConfig.getHeadlessParsing());
+    public void parse(InputStream instream) throws MimeException, IOException {
+        MimeEntityConfig config = mimeTokenStream.getConfig();
+        if (config.getHeadlessParsing() != null) {
+            Field contentType = mimeTokenStream.parseHeadless(
+                    instream, config.getHeadlessParsing());
             handler.startMessage();
             handler.startHeader();
             handler.field(contentType);
             handler.endHeader();
         } else {
-            mimeTokenStream.parse(inputStream);
+            mimeTokenStream.parse(instream);
         }
         OUTER: for (;;) {
             EntityState state = mimeTokenStream.getState();
@@ -187,7 +182,7 @@ public class MimeStreamParser {
      *
      * @return <code>true</code> if in raw mode, <code>false</code>
      *         otherwise.
-     * @see #setRaw(boolean)
+     * @see #setRaw()
      */
     public boolean isRaw() {
         return mimeTokenStream.isRaw();
@@ -213,7 +208,7 @@ public class MimeStreamParser {
     }
 
     /**
-     * Enables recursive mode. In tihs mode rfc822 parts are recursively
+     * Enables recursive mode. In this mode rfc822 parts are recursively
      * parsed.
      */
     public void setRecurse() {

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptor.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptor.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptor.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptor.java Wed Jul 13 14:17:19 2011
@@ -20,8 +20,7 @@
 package org.apache.james.mime4j.stream;
 
 /**
- * Encapsulates the values of the MIME-specific header fields
- * (which starts with <code>Content-</code>).
+ * Descriptor containing common MIME content body properties.
  */
 public interface BodyDescriptor extends ContentDescriptor {
 

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptorBuilder.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptorBuilder.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptorBuilder.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/BodyDescriptorBuilder.java Wed Jul 13 14:17:19 2011
@@ -21,30 +21,57 @@ package org.apache.james.mime4j.stream;
 
 import org.apache.james.mime4j.MimeException;
 
+/**
+ * Body descriptor builders are intended to construct {@link BodyDescriptor} instances from
+ * multiple unstructured {@link RawField}s.
+ * <p/>
+ * Body descriptor builders are stateful and modal as they have to store intermediate results
+ * between method invocations and also rely on a particular sequence of method invocations
+ * (the mode of operation).
+ * <p/>
+ * Consumers are expected to interact with body descriptor builders in the following way:
+ * <ul>
+ * <li>Invoke {@link #reset()} method in order to reset builder's internal state and make it
+ *   ready to start the process of building a new {@link BodyDescriptor}.</li>
+ * <li>Invoke {@link #addField(RawField)} multiple times method in order to collect
+ *   necessary details for building a body descriptor. The builder can optionally
+ *   transform the unstructured field given an an input into a structured one and return
+ *   an instance {@link Field} that also implements a richer interface for a particular type
+ *   of fields such as <code>Content-Type</code>. The builder can also return <code>null</code>
+ *   if the field is to be ignored</li>
+ * <li>Optionally invoke {@link #newChild()} for each embedded body of content. Please note that
+ *   the resultant {@link BodyDescriptorBuilder}} child instance can inherit some its parent
+ *   properties such as MIME type.</li>
+ * <li>Invoke {@link #build()()} method in order to generate a {@link BodyDescriptor}} instance
+ *   based on the internal state of the builder.</li>
+ * </ul>
+ */
 public interface BodyDescriptorBuilder {
 
     /**
-     * Resets the internal state.
+     * Resets the internal state of the builder making it ready to process new input.
      */
     void reset();
 
     /**
-     * Adds a field to the builder updating its internal state. The field
-     * can be transformed as a result of this operation.
-     * @param field the MIME field.
-     *
-     * @return null or an elaborated field representing the same data.
+     * Updates builder's internal state by adding a new field. The builder can optionally
+     * transform the unstructured field given an an input into a structured one and return
+     * an instance {@link Field} that also implements a richer interface for a particular type
+     * of fields such as <code>Content-Type</code>. The builder can also return <code>null</code>
+     * if the field is to be ignored.
      */
     Field addField(RawField field) throws MimeException;
 
     /**
-     * Builds an instance of {@link BodyDescriptor} based on the internal
-     * state.
-     *
-     * @return body descriptor
+     * Builds an instance of {@link BodyDescriptor} based on the internal state.
      */
     BodyDescriptor build();
 
+    /**
+     * Creates an instance of {@link BodyDescriptorBuilder} to be used for processing of an
+     * embedded content body. Please the child instance can inherit some of its parent properties
+     * such as MIME type.
+     */
     BodyDescriptorBuilder newChild();
 
 }

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/ContentDescriptor.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/ContentDescriptor.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/ContentDescriptor.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/ContentDescriptor.java Wed Jul 13 14:17:19 2011
@@ -20,7 +20,7 @@
 package org.apache.james.mime4j.stream;
 
 /**
- * Represents common content properties.
+ * Descriptor containing common MIME content properties.
  */
 public interface ContentDescriptor {
 

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/DefaultFieldBuilder.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/DefaultFieldBuilder.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/DefaultFieldBuilder.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/DefaultFieldBuilder.java Wed Jul 13 14:17:19 2011
@@ -25,6 +25,10 @@ import org.apache.james.mime4j.MimeExcep
 import org.apache.james.mime4j.io.MaxHeaderLengthLimitException;
 import org.apache.james.mime4j.util.ByteArrayBuffer;
 
+/**
+ * Default implementation of {@link FieldBuilder}.
+ *
+ */
 public class DefaultFieldBuilder implements FieldBuilder {
 
     private static final BitSet FIELD_CHARS = new BitSet();

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/Field.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/Field.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/Field.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/Field.java Wed Jul 13 14:17:19 2011
@@ -22,14 +22,17 @@ package org.apache.james.mime4j.stream;
 import org.apache.james.mime4j.util.ByteSequence;
 
 /**
- * Abstract MIME field.
+ * This interface represents an abstract MIME field. A MIME field must have a non <code>null</code>
+ * name and a content body (unfolded but unparsed and possibly encoded). Optionally implementing
+ * classes may also retain the original (raw) representation in a form of {@link ByteSequence}.
+ * <p/>
+ * Specific implementations of this interface may also use a richer model to represent the field
+ * if its body can be parsed into a set of constituent elements.
  */
 public interface Field {
 
     /**
-     * Gets the name of the field (<code>Subject</code>, <code>From</code>, etc).
-     *
-     * @return the field name.
+     * Returns the name of the field.
      */
     String getName();
 

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/FieldBuilder.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/FieldBuilder.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/FieldBuilder.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/FieldBuilder.java Wed Jul 13 14:17:19 2011
@@ -22,14 +22,48 @@ package org.apache.james.mime4j.stream;
 import org.apache.james.mime4j.MimeException;
 import org.apache.james.mime4j.util.ByteArrayBuffer;
 
+/**
+ * Field builders are intended to construct {@link RawField} instances from multiple lines
+ * contained in {@link ByteArrayBuffer}s.
+ * <p/>
+ * Field builders are stateful and modal as they have to store intermediate results between
+ * method invocations and also rely on a particular sequence of method invocations
+ * (the mode of operation).
+ * <p/>
+ * Consumers are expected to interact with field builder in the following way:
+ * <ul>
+ * <li>Invoke {@link #reset()} method in order to reset builder's internal state and make it
+ *   ready to start the process of building a new {@link RawField}.</li>
+ * <li>Invoke {@link #append(ByteArrayBuffer)} method one or multiple times in order to build
+ *   an internal representation of a MIME field from individual lines of text.</li>
+ * <li>Optionally {@link #getRaw()} method can be invoked in order to get combined content
+ *   of all lines processed so far. Please note builder implementations can return
+ *   <code>null</code> if they do not retain original raw content.</li>
+ * <li>Invoke {@link #build()} method in order to generate a {@link RawField} instance
+ *   based on the internal state of the builder.</li>
+ * </ul>
+ */
 public interface FieldBuilder {
 
+    /**
+     * Resets the internal state of the builder making it ready to process new input.
+     */
     void reset();
 
+    /**
+     * Updates builder's internal state by adding a new line of text.
+     */
     void append(ByteArrayBuffer line) throws MimeException;
 
+    /**
+     * Builds an instance of {@link RawField} based on the internal state.
+     */
     RawField build() throws MimeException;
 
+    /**
+     * Returns combined content of all lines processed so far or <code>null</code>
+     * if the builder does not retain original raw content.
+     */
     ByteArrayBuffer getRaw();
 
 }

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeEntityConfig.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeEntityConfig.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeEntityConfig.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeEntityConfig.java Wed Jul 13 14:17:19 2011
@@ -22,7 +22,7 @@ package org.apache.james.mime4j.stream;
 import org.apache.james.mime4j.MimeException;
 
 /**
- * MIME entity configuration
+ * Properties used to configure the behavior of MIME stream parsers.
  */
 public final class MimeEntityConfig implements Cloneable {
 

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeTokenStream.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeTokenStream.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeTokenStream.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/MimeTokenStream.java Wed Jul 13 14:17:19 2011
@@ -42,26 +42,31 @@ import org.apache.james.mime4j.util.Char
  * </p>
  * <pre>
  *      MimeTokenStream stream = new MimeTokenStream();
- *      stream.parse(new FileInputStream("mime.msg"));
- *      for (int state = stream.getState();
- *           state != MimeTokenStream.T_END_OF_STREAM;
- *           state = stream.next()) {
- *          switch (state) {
- *            case MimeTokenStream.T_BODY:
- *              System.out.println("Body detected, contents = "
- *                + stream.getInputStream() + ", header data = "
- *                + stream.getBodyDescriptor());
- *              break;
- *            case MimeTokenStream.T_FIELD:
- *              System.out.println("Header field detected: "
- *                + stream.getField());
- *              break;
- *            case MimeTokenStream.T_START_MULTIPART:
- *              System.out.println("Multipart message detexted,"
- *                + " header data = "
- *                + stream.getBodyDescriptor());
- *            ...
+ *      InputStream instream = new FileInputStream("mime.msg");
+ *      try {
+ *          stream.parse(instream);
+ *          for (int state = stream.getState();
+ *              state != MimeTokenStream.T_END_OF_STREAM;
+ *              state = stream.next()) {
+ *              switch (state) {
+ *              case MimeTokenStream.T_BODY:
+ *                  System.out.println("Body detected, contents = "
+ *                  + stream.getInputStream() + ", header data = "
+ *                  + stream.getBodyDescriptor());
+ *                  break;
+ *              case MimeTokenStream.T_FIELD:
+ *                  System.out.println("Header field detected: "
+ *                  + stream.getField());
+ *                  break;
+ *              case MimeTokenStream.T_START_MULTIPART:
+ *                  System.out.println("Multipart message detexted,"
+ *                  + " header data = "
+ *                  + stream.getBodyDescriptor());
+ *              ...
+ *              }
  *          }
+ *      } finally {
+ *          instream.close();
  *      }
  * </pre>
  * <p>Instances of {@link MimeTokenStream} are reusable: Invoking the
@@ -202,7 +207,7 @@ public class MimeTokenStream {
      *
      * @return <code>true</code> if in raw mode, <code>false</code>
      *         otherwise.
-     * @see #setRecursionMode(int)
+     * @see #setRecursionMode(RecursionMode)
      */
     public boolean isRaw() {
         return recursionMode == RecursionMode.M_RAW;
@@ -211,11 +216,12 @@ public class MimeTokenStream {
     /**
      * Gets the current recursion mode.
      * The recursion mode specifies the approach taken to parsing parts.
-     * {@link #M_RAW}  mode does not parse the part at all.
-     * {@link #M_RECURSE} mode recursively parses each mail
-     * when an <code>message/rfc822</code> part is encounted;
-     * {@link #M_NO_RECURSE} does not.
-     * @return {@link #M_RECURSE}, {@link #M_RAW} or {@link #M_NO_RECURSE}
+     * {@link RecursionMode#M_RAW}  mode does not parse the part at all.
+     * {@link RecursionMode#M_RECURSE} mode recursively parses each mail
+     * when an <code>message/rfc822</code> part is encountered;
+     * {@link RecursionMode#M_NO_RECURSE} does not.
+     * @return {@link RecursionMode#M_RECURSE}, {@link RecursionMode#M_RAW} or
+     *   {@link RecursionMode#M_NO_RECURSE}
      */
     public RecursionMode getRecursionMode() {
         return recursionMode;
@@ -224,11 +230,12 @@ public class MimeTokenStream {
     /**
      * Sets the current recursion.
      * The recursion mode specifies the approach taken to parsing parts.
-     * {@link #M_RAW}  mode does not parse the part at all.
-     * {@link #M_RECURSE} mode recursively parses each mail
-     * when an <code>message/rfc822</code> part is encounted;
-     * {@link #M_NO_RECURSE} does not.
-     * @param mode {@link #M_RECURSE}, {@link #M_RAW} or {@link #M_NO_RECURSE}
+     * {@link RecursionMode#M_RAW}  mode does not parse the part at all.
+     * {@link RecursionMode#M_RECURSE} mode recursively parses each mail
+     * when an <code>message/rfc822</code> part is encountered;
+     * {@link RecursionMode#M_NO_RECURSE} does not.
+     * @param mode {@link RecursionMode#M_RECURSE}, {@link RecursionMode#M_RAW} or
+     *   {@link RecursionMode#M_NO_RECURSE}
      */
     public void setRecursionMode(RecursionMode mode) {
         recursionMode = mode;
@@ -258,7 +265,8 @@ public class MimeTokenStream {
      * This method returns the raw entity, preamble, or epilogue contents.
      * <p/>
      * This method is valid, if {@link #getState()} returns either of
-     * {@link #T_RAW_ENTITY}, {@link #T_PREAMBLE}, or {@link #T_EPILOGUE}.
+     * {@link EntityState#T_RAW_ENTITY}, {@link EntityState#T_PREAMBLE}, or
+     * {@link EntityState#T_EPILOGUE}.
      *
      * @return Data stream, depending on the current state.
      * @throws IllegalStateException {@link #getState()} returns an
@@ -273,7 +281,8 @@ public class MimeTokenStream {
      * fields with the standard defaults.
      * <p/>
      * This method is valid, if {@link #getState()} returns either of
-     * {@link #T_RAW_ENTITY}, {@link #T_PREAMBLE}, or {@link #T_EPILOGUE}.
+     * {@link EntityState#T_RAW_ENTITY}, {@link EntityState#T_PREAMBLE}, or
+     * {@link EntityState#T_EPILOGUE}.
      *
      * @return Data stream, depending on the current state.
      * @throws IllegalStateException {@link #getState()} returns an
@@ -317,10 +326,10 @@ public class MimeTokenStream {
      * <p>Gets a descriptor for the current entity.
      * This method is valid if {@link #getState()} returns:</p>
      * <ul>
-     * <li>{@link #T_BODY}</li>
-     * <li>{@link #T_START_MULTIPART}</li>
-     * <li>{@link #T_EPILOGUE}</li>
-     * <li>{@link #T_PREAMBLE}</li>
+     * <li>{@link EntityState#T_BODY}</li>
+     * <li>{@link EntityState#T_START_MULTIPART}</li>
+     * <li>{@link EntityState#T_EPILOGUE}</li>
+     * <li>{@link EntityState#T_PREAMBLE}</li>
      * </ul>
      * @return <code>BodyDescriptor</code>, not nulls
      */
@@ -329,10 +338,10 @@ public class MimeTokenStream {
     }
 
     /**
-     * This method is valid, if {@link #getState()} returns {@link #T_FIELD}.
+     * This method is valid, if {@link #getState()} returns {@link EntityState#T_FIELD}.
      * @return String with the fields raw contents.
      * @throws IllegalStateException {@link #getState()} returns another
-     *   value than {@link #T_FIELD}.
+     *   value than {@link EntityState#T_FIELD}.
      */
     public Field getField() {
         return currentStateMachine.getField();
@@ -341,7 +350,7 @@ public class MimeTokenStream {
     /**
      * This method advances the token stream to the next token.
      * @throws IllegalStateException The method has been called, although
-     *   {@link #getState()} was already {@link #T_END_OF_STREAM}.
+     *   {@link #getState()} was already {@link EntityState#T_END_OF_STREAM}.
      */
     public EntityState next() throws IOException, MimeException {
         if (state == EntityState.T_END_OF_STREAM  ||  currentStateMachine == null) {

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/NameValuePair.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/NameValuePair.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/NameValuePair.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/NameValuePair.java Wed Jul 13 14:17:19 2011
@@ -21,6 +21,9 @@ package org.apache.james.mime4j.stream;
 
 import org.apache.james.mime4j.util.LangUtils;
 
+/**
+ * A name / value tuple
+ */
 public final class NameValuePair {
 
     private final String name;

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawBody.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawBody.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawBody.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawBody.java Wed Jul 13 14:17:19 2011
@@ -22,6 +22,13 @@ package org.apache.james.mime4j.stream;
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * This class represents a field's body consisting of a textual value and a number of optional
+ * name / value parameters separated with semicolon.
+ * <pre>
+ * value; param1 = value1; param2 = "value2";
+ * </pre>
+ */
 public final class RawBody {
 
     private final String value;

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawField.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawField.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawField.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawField.java Wed Jul 13 14:17:19 2011
@@ -24,7 +24,10 @@ import org.apache.james.mime4j.util.Cont
 import org.apache.james.mime4j.util.MimeUtil;
 
 /**
- * The basic immutable MIME field.
+ * Raw (unstructured) MIME field. The field's body is unparsed and possibly encoded.
+ * <p/>
+ *  Instances of this class can be created by using
+ * {@link RawFieldParser#parseField(ByteSequence)} method.
  */
 public final class RawField implements Field {
 

Modified: james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawFieldParser.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawFieldParser.java?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawFieldParser.java (original)
+++ james/mime4j/trunk/core/src/main/java/org/apache/james/mime4j/stream/RawFieldParser.java Wed Jul 13 14:17:19 2011
@@ -29,7 +29,10 @@ import org.apache.james.mime4j.util.Char
 import org.apache.james.mime4j.util.ContentUtil;
 
 /**
- * The basic immutable MIME field.
+ * Low level parser for header field elements. The parsing routines of this class are designed
+ * to produce near zero intermediate garbage and make no intermediate copies of input data.
+ * <p/>
+ * This class is immutable and thread safe.
  */
 public class RawFieldParser {
 
@@ -47,6 +50,11 @@ public class RawFieldParser {
 
     public static final RawFieldParser DEFAULT = new RawFieldParser();
 
+    /**
+     * Parses the sequence of bytes into {@link RawField}.
+     *
+     * @throws MimeException if the input data does not contain a valid MIME field.
+     */
     public RawField parseField(final ByteSequence raw) throws MimeException {
         if (raw == null) {
             return null;
@@ -60,6 +68,11 @@ public class RawFieldParser {
         return new RawField(raw, cursor.getPos(), name, null);
     }
 
+    /**
+     * Parses the field body containing a value with parameters into {@link RawBody}.
+     *
+     * @param field unstructured (raw) field
+     */
     public RawBody parseRawBody(final RawField field) {
         ByteSequence buf = field.getRaw();
         int pos = field.getDelimiterIdx() + 1;
@@ -75,6 +88,12 @@ public class RawFieldParser {
         return parseRawBody(buf, cursor);
     }
 
+    /**
+     * Parses the sequence of bytes containing a value with parameters into {@link RawBody}.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     */
     public RawBody parseRawBody(final ByteSequence buf, final ParserCursor cursor) {
         String value = parseToken(buf, cursor, SEMICOLON);
         if (cursor.atEnd()) {
@@ -85,6 +104,13 @@ public class RawFieldParser {
         return new RawBody(value, params);
     }
 
+    /**
+     * Parses the sequence of bytes containing field parameters delimited with semicolon into
+     * a list of {@link NameValuePair}s.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     */
     public List<NameValuePair> parseParameters(final ByteSequence buf, final ParserCursor cursor) {
         List<NameValuePair> params = new ArrayList<NameValuePair>();
         skipWhiteSpace(buf, cursor);
@@ -95,6 +121,13 @@ public class RawFieldParser {
         return params;
     }
 
+    /**
+     * Parses the sequence of bytes containing a field parameter delimited with semicolon into
+     * {@link NameValuePair}.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     */
     public NameValuePair parseParameter(final ByteSequence buf, final ParserCursor cursor) {
         String name = parseToken(buf, cursor, EQUAL_OR_SEMICOLON);
         if (cursor.atEnd()) {
@@ -112,6 +145,15 @@ public class RawFieldParser {
         return new NameValuePair(name, value);
     }
 
+    /**
+     * Extracts from the sequence of bytes a token terminated with any of the given delimiters
+     * discarding semantically insignificant whitespace characters and comments.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     * @param delimiters set of delimiting characters. Can be <code>null</code> if the token
+     *  is not delimited by any character.
+     */
     public String parseToken(final ByteSequence buf, final ParserCursor cursor, final BitSet delimiters) {
         StringBuilder dst = new StringBuilder();
         boolean whitespace = false;
@@ -135,6 +177,16 @@ public class RawFieldParser {
         return dst.toString();
     }
 
+    /**
+     * Extracts from the sequence of bytes a value which can be enclosed in quote marks and
+     * terminated with any of the given delimiters discarding semantically insignificant
+     * whitespace characters and comments.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     * @param delimiters set of delimiting characters. Can be <code>null</code> if the value
+     *  is not delimited by any character.
+     */
     public String parseValue(final ByteSequence buf, final ParserCursor cursor, final BitSet delimiters) {
         StringBuilder dst = new StringBuilder();
         boolean whitespace = false;
@@ -164,6 +216,13 @@ public class RawFieldParser {
         return dst.toString();
     }
 
+    /**
+     * Skips semantically insignificant whitespace characters and moves the cursor to the closest
+     * non-whitespace character.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     */
     public void skipWhiteSpace(final ByteSequence buf, final ParserCursor cursor) {
         int pos = cursor.getPos();
         int indexFrom = cursor.getPos();
@@ -179,6 +238,14 @@ public class RawFieldParser {
         cursor.updatePos(pos);
     }
 
+    /**
+     * Skips semantically insignificant content if the current position is positioned at the
+     * beginning of a comment and moves the cursor past the end of the comment.
+     * Nested comments and escaped characters are recognized and handled appropriately.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     */
     public void skipComment(final ByteSequence buf, final ParserCursor cursor) {
         if (cursor.atEnd()) {
             return;
@@ -216,6 +283,14 @@ public class RawFieldParser {
         cursor.updatePos(pos);
     }
 
+    /**
+     * Skips semantically insignificant whitespace characters and comments and moves the cursor
+     * to the closest semantically significant non-whitespace character.
+     * Nested comments and escaped characters are recognized and handled appropriately.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     */
     public void skipAllWhiteSpace(final ByteSequence buf, final ParserCursor cursor) {
         while (!cursor.atEnd()) {
             char current = (char) (buf.byteAt(cursor.getPos()) & 0xff);
@@ -229,6 +304,16 @@ public class RawFieldParser {
         }
     }
 
+    /**
+     * Transfers content into the destination buffer until a whitespace character, a comment,
+     * or any of the given delimiters is encountered.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     * @param delimiters set of delimiting characters. Can be <code>null</code> if the value
+     *  is delimited by a whitespace or a comment only.
+     * @param dst destination buffer
+     */
     public void copyContent(final ByteSequence buf, final ParserCursor cursor, final BitSet delimiters,
             final StringBuilder dst) {
         int pos = cursor.getPos();
@@ -247,6 +332,13 @@ public class RawFieldParser {
         cursor.updatePos(pos);
     }
 
+    /**
+     * Transfers content enclosed with quote marks into the destination buffer.
+     *
+     * @param buf buffer with the sequence of bytes to be parsed
+     * @param cursor defines the bounds and current position of the buffer
+     * @param dst destination buffer
+     */
     public void copyQuotedContent(final ByteSequence buf, final ParserCursor cursor,
             final StringBuilder dst) {
         if (cursor.atEnd()) {

Modified: james/mime4j/trunk/core/src/main/javadoc/overview.html
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/core/src/main/javadoc/overview.html?rev=1146050&r1=1146049&r2=1146050&view=diff
==============================================================================
--- james/mime4j/trunk/core/src/main/javadoc/overview.html (original)
+++ james/mime4j/trunk/core/src/main/javadoc/overview.html Wed Jul 13 14:17:19 2011
@@ -15,18 +15,27 @@
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
-  under the License.    
+  under the License.
 -->
 <HTML>
   <HEAD>
     <TITLE>API Overview</TITLE>
   </HEAD>
   <BODY>
-<p><b>Mime4j</b> provides a parser, <a href="org/apache/james/mime4j/parser/MimeStreamParser.html">MimeStreamParser</a>, for e-mail message streams in plain rfc822 and MIME format and a <a href="org/apache/james/mime4j/message/Message.html">Message</a> class used to build a tree representation of an e-mail message.</p>
-
-<p>The parser uses a callback mechanism to report parsing events such as the start of an entity header the start of a body, etc. If you are familiar with the SAX XML parser interface you should have no problem getting started with mime4j.</p>
-<p>The parser only deals with the structure of the message stream. It won't do any decoding of base64 or quoted-printable encoded header fields and bodies. This is intentional - the parser should only provide the most basic functionality needed to build more complex parsers. However, mime4j does include facilities to decode bodies and fields and the Message class described below handles decoding of fields and bodies transparently.</p>
-<p>The parser has been designed to be extremely tolerant against messages violating the standards. It has been tested using a large corpus (>5000) of e-mail messages. As a benchmark the widely used perl MIME::Tools parser has been used. mime4j and MIME:Tools rarely differ (<25 in those 5000). When they do (which only occurs for illegally formatted spam messages) we think mime4j does a better job.</p>
-<p><b>Mime4j</b> can also be used to build a tree representation of an e-mail message using the <a href="org/apache/james/mime4j/message/Message.html">Message</a> class. Using this facility mime4j automatically handles the decoding of fields and bodies and uses temporary files for large attachments. This representation is similar to the representation constructed by the JavaMail API:s but is more tolerant to messages violating the standards.</p>
+    <p><b>Mime4j Core</b> provides a parser,
+     <a href="org/apache/james/mime4j/parser/MimeStreamParser.html">MimeStreamParser</a>, for
+     message streams in plain rfc822 and MIME format.</p>
+    <p>The parser uses a callback mechanism to report parsing events such as the start of an entity
+     header the start of a body, etc. If you are familiar with the SAX XML parser interface you
+     should have no problem getting started with mime4j.</p>
+    <p>The parser only deals with the structure of the message stream. It won't do any decoding of
+      base64 or quoted-printable encoded header fields and bodies. This is intentional - the parser
+      should only provide the most basic functionality needed to build more complex parsers.
+      However, mime4j does include facilities to decode bodies and fields.</p>
+    <p>The parser has been designed to be tolerant against messages violating the standards. It has
+      been tested using a large corpus (>5000) of e-mail messages. As a benchmark the widely used
+      perl MIME::Tools parser has been used. mime4j and MIME:Tools rarely differ (<25 in those
+      5000). When they do (which only occurs for illegally formatted spam messages) we think mime4j
+      does a better job.</p>
   </BODY>
 </HTML>