Анализ на основе событий в MIME4J - как заполнить новое сообщение из InputStream?

Я работаю с MIME4J для чтения событий MIME из дампа стека электронной почты. Я пытаюсь прочитать данное событие сообщения, как определено заголовками START_MESSAGE и END_MESSAGE, как целое событие, так как в конечном итоге я буду перемещать процесс в распределенную файловую систему, и мне нужно будет планировать пересечение границ разделением файлов.

Для анализа на основе событий в mime4j необходим интерфейс ContentHandler, и парсер вызывает из него методы, которые требуют, чтобы для него был установлен обработчик. Я экспериментировал с образцом Handler из другого SO-ответа, который расширяет упакованный SimpleContentHandler mime4j, но который действительно только анализирует заголовки.

Я пытаюсь создать свой собственный класс ContentHandler, чтобы собрать полное сообщение как одно событие. Затем мне нужно будет иметь событие во временном объекте, чтобы я мог разобрать заголовки, их поля и содержимое полей из него. Конечная цель состоит в том, чтобы адаптировать это поведение в MapReduce, поэтому необходимо справиться с возможностью того, что одна часть электронного письма будет в одном файловом разделе, а другая часть в другом файловом разделе необходима.

Для моего пользовательского ContentHandler, я дошел до:

public class CustomContentHandler extends AbstractContentHandler {}

И для основного я использую:

    public class Reader 
    {
     public static void main( String[] args ) throws FileNotFoundException, IOException,
     MimeException
    {

   QaContentHandler handler = new CustomContentHandler();
   MimeConfig config = new MimeConfig();
   MimeStreamParser parser = new MimeStreamParser(config);
   InputStream stream = new FileInputStream("/home/javadev1/lib/INBOX");

   parser.setContentHandler(handler);
   try 
   {
    do 
    {   
   parser.parse(stream);
   }
    while (stream.read() != -1);
       } 
   finally 
    {
           stream.close();
       }
    }

    }

Таким образом, любая помощь в том, как собрать информацию в обработчике, будет действительно полезной. Я попытался установить новый MessageImpl, затем с помощью компоновщика скопировать проанализированный поток в него, и я также попытался построить new Message из синтаксического анализа потока, а затем распечатать сообщение, когда читается заголовок END_MESSAGE, но это напечатало нули.

Возможно, я тоже испытываю концептуальную слепую зону. Если это так, я согласен с этим. Спасибо!

1 ответ

Решение

Вот выдержка из кода, которая работает для меня. Как только я нахожу интересное сообщение с помощью анализатора состояния, я переключаюсь на анализатор dom, чтобы создать объект сообщения.

/**
 * check the MessageStream
 * 
 * @param in - the inputstream to check
 * @param id - the id of a message to search for
 * @param encoding - the encoding of the stream e.g. ISO-8859
 * @return - the message with the given id of null if none is found
 * @throws IOException
 * @throws MimeException
 */
public Message checkMessageStream(InputStream in, String id, Charset encoding)
        throws IOException, MimeException {
    // https://james.apache.org/mime4j/usage.html
    String messageString = new String(StreamUtils.getBytes(in));
    messageString = fixMessageString(messageString);
    InputStream instream = new ByteArrayInputStream(
            messageString.getBytes(encoding));
    MimeTokenStream stream = new MimeTokenStream();
    stream.parse(instream);
    for (EntityState state = stream.getState(); state != EntityState.T_END_OF_STREAM; state = stream
            .next()) {
        switch (state) {
        case T_BODY:
            if (debug) {
                System.out.println("Body detected, contents = "
                        + stream.getInputStream() + ", header data = "
                        + stream.getBodyDescriptor());
            }
            break;
        case T_FIELD:
            Field field = stream.getField();
            if (debug) {
                System.out.println("Header field detected: " + stream.getField());
            }
            if (field.getName().toLowerCase().equals("message-id")) {
                // System.out.println("id: " + field.getBody() + "=" + id + "?");
                if (field.getBody().equals("<" + id + ">")) {
                    InputStream messageStream = new ByteArrayInputStream(
                            messageString.getBytes(encoding));
                    Message message = MessageServiceFactory.newInstance()
                            .newMessageBuilder().parseMessage(messageStream);
                    return message;
                } else {
                    return null;
                }
            }

            break;
        case T_START_MULTIPART:
            if (debug) {
                System.out.println("Multipart message detexted," + " header data = "
                        + stream.getBodyDescriptor());
            }
            break;
        }
    }
    return null;
}
Другие вопросы по тегам