~~ 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 <<>>, 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 <<>> method, or you might ask for the header data by invoking <<>>. {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() --------------------------------------------------------------------