~~ 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 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 {{{./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 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}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() | |
-------------------------------------------------------------------- |