
~~   Licensed to the Apache Software Foundation (ASF) under one
~~   or more contributor license agreements.  See the NOTICE file
~~   distributed with this work for additional information
~~   regarding copyright ownership.  The ASF licenses this file
~~   to you under the Apache License, Version 2.0 (the
~~   "License"); you may not use this file except in compliance
~~   with the License.  You may obtain a copy of the License at
~~
~~     http://www.apache.org/licenses/LICENSE-2.0
~~
~~   Unless required by applicable law or agreed to in writing,
~~   software distributed under the License is distributed on an
~~   "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.

 -------------
 Usage
 -------------

{Usage}

  Mime4j provides two different API's: An event based API by using
  the {{{apidocs/org/apache/james/mime4j/parser/MimeStreamParser.html}
  MimeStreamParser}}. Alternatively, you may use the iterative
  API, which is available through the
  {{{apidocs/org/apache/james/mime4j/parser/MimeTokenStream.html}
  MimeTokenStream}}. In terms of speed, you should not note
  any differences.

  * {{{#Token Streams}Token Streams}}

  * {{{#Sample Token Stream}Sample Token Stream}}

  * {{{#Event Handlers}Event Handlers}}

  * {{{#Sample Event Stream}Sample Event Stream}}

{Token Streams}

  The iterative approach is using the class
  {{{apidocs/org/apache/james/mime4j/parser/MimeTokenStream.html}
  MimeTokenStream}}. Here's an example, how you could use
  the token stream:

--------------------------------------------------------------------
  MimeTokenStream stream = new MimeTokenStream();
  stream.parse(new BufferedInputStream(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());
      ...
    }
  }
--------------------------------------------------------------------  

  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 {{{apidocs/org/apache/james/mime4j/parser/ContentHandler.html}
  ContentHandler}} interface. Here's an example, how you could
  implement an event handler:

--------------------------------------------------------------------  
  public class MyContentHandler extends org.apache.james.mime4j.parser.ContentHandler {
      public 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}Token Streams}}:

--------------------------------------------------------------------  
  ContentHandler handler = new MyContentHandler();
  MimeStreamParser parser = new MimeStreamParser();
  parser.setContentHandler(handler);
  parser.parse(new BufferedInputStream(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()
--------------------------------------------------------------------  
