Usage

Mime4j provides two different API's: An event based API by using the MimeStreamParser. Alternatively, you may use the iterative API, which is available through the MimeTokenStream. In terms of speed, you should not note any differences.

Token Streams

The iterative approach is using the class MimeTokenStream. Here's an example, how you could use the token stream:

  MimeTokenStream stream = new MimeTokenStream();
  stream.parse(new FileInputStream("mime.msg"));
  for (EntityState state = stream.getState();
       state != EntityState.T_END_OF_STREAM;
       state = stream.next()) {
    switch (state) {
      case T_BODY:
        System.out.println("Body detected, contents = "
          + stream.getInputStream() + ", header data = "
          + stream.getBodyDescriptor());
        break;
      case T_FIELD:
        System.out.println("Header field detected: "
          + stream.getField());
        break;
      case T_START_MULTIPART:
        System.out.println("Multipart message detexted,"
          + " header data = "
          + stream.getBodyDescriptor());
      ...
    }
  }

The token stream provides a set of tokens. Tokens are identified by a state. Most states are simply event indicators, with no additional data available. However, there are some states, which provide additional data. For example, the state T_BODY, which indicates that an actual body is available, If you note this state, then you may ask for the bodies contents, which are provided through the getInputStream() method, or you might ask for the header data by invoking getBodyDescriptor().

Sample Token Stream

The following sample should give you a rough idea of the order, in which you'll receive tokens:

  T_START_MESSAGE
      T_START_HEADER
          T_FIELD
          T_FIELD
          ...
      T_END_HEADER
      T_START_MULTIPART
          T_PREAMBLE
          T_START_BODYPART
              T_START_HEADER
                  T_FIELD
                  T_FIELD
                  ...
              T_END_HEADER
              T_BODY
          T_END_BODYPART
          T_START_BODYPART
              T_START_HEADER
                  T_FIELD
                  T_FIELD
                  ...
              T_END_HEADER
              T_BODY
          T_END_BODYPART
          T_EPILOGUE
      T_END_MULTIPART
   T_END_MESSAGE

The example shows a multipart message with two parts.

Event Handlers

The event based API requires, that you provide an event handler, which receives events. The event handler is an object, which implements the ContentHandler interface. Here's an example, how you could implement an event handler:

  public class MyContentHandler extends AbstractContentHandler {
      
      public void body(BodyDescriptor bd, InputStream is)
              throws MimeException, IOException {
          System.out.println("Body detected, contents = "
              + is + ", header data = " + bd);
      }
      public void field(String fieldData) throws MimeException {
          System.out.println("Header field detected: "
              + fieldData);
      }
      public void startMultipart(BodyDescriptor bd) throws MimeException {
          System.out.println("Multipart message detexted, header data = "
              + bd);
      }
      ...
  }

A little bit of additional code allows us to create an example, which is functionally equivalent to the example from the section on Token Streams:

  ContentHandler handler = new MyContentHandler();
  MimeStreamParser parser = new MimeStreamParser();
  parser.setContentHandler(handler);
  parser.parse(new FileInputStream("mime.msg"));

Sample Event Stream

Like above for tokens, we provide an additional example, which demonstrates the typical order of events that you have to expect:

  startMessage()
      startHeader()
          field(...)
          field(...)
          ...
      endHeader()
      startMultipart()
          preamble(...)
          startBodyPart()
              startHeader()
                  field(...)
                  field(...)
                  ...
              endHeader()
              body()
          endBodyPart()
          startBodyPart()
              startHeader()
                  field(...)
                  field(...)
                  ...
              endHeader()
              body()
          endBodyPart()
          epilogue(...)
      endMultipart()
  endMessage()