You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2007/05/25 15:17:22 UTC

svn commit: r541636 - in /james/mime4j/trunk/src: main/java/org/apache/james/mime4j/ main/java/org/apache/james/mime4j/message/ test/java/org/apache/james/mime4j/

Author: norman
Date: Fri May 25 06:17:21 2007
New Revision: 541636

URL: http://svn.apache.org/viewvc?view=rev&rev=541636
Log:
Allow exceptions from a ContentHandler (Thx to Jukka). See MIME4J-16

Added:
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeException.java   (with props)
Modified:
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractContentHandler.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/ContentHandler.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeStreamParser.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java
    james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java
    james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeStreamParserTest.java

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractContentHandler.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractContentHandler.java?view=diff&rev=541636&r1=541635&r2=541636
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractContentHandler.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/AbstractContentHandler.java Fri May 25 06:17:21 2007
@@ -36,78 +36,80 @@
     /**
      * @see org.apache.james.mime4j.ContentHandler#endMultipart()
      */
-    public void endMultipart() {
+    public void endMultipart() throws MimeException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#startMultipart(org.apache.james.mime4j.BodyDescriptor)
      */
-    public void startMultipart(BodyDescriptor bd) {
+    public void startMultipart(BodyDescriptor bd) throws MimeException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
      */
-    public void body(BodyDescriptor bd, InputStream is) throws IOException {
+    public void body(BodyDescriptor bd, InputStream is)
+            throws MimeException, IOException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#endBodyPart()
      */
-    public void endBodyPart() {
+    public void endBodyPart() throws MimeException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#endHeader()
      */
-    public void endHeader() {
+    public void endHeader() throws MimeException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#endMessage()
      */
-    public void endMessage() {
+    public void endMessage() throws MimeException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#epilogue(java.io.InputStream)
      */
-    public void epilogue(InputStream is) throws IOException {
+    public void epilogue(InputStream is) throws MimeException, IOException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#field(java.lang.String)
      */
-    public void field(String fieldData) {
+    public void field(String fieldData) throws MimeException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#preamble(java.io.InputStream)
      */
-    public void preamble(InputStream is) throws IOException {
+    public void preamble(InputStream is) throws MimeException, IOException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#startBodyPart()
      */
-    public void startBodyPart() {
+    public void startBodyPart() throws MimeException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#startHeader()
      */
-    public void startHeader() {
+    public void startHeader() throws MimeException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#startMessage()
      */
-    public void startMessage() {
+    public void startMessage() throws MimeException {
     }
     
     /**
      * @see org.apache.james.mime4j.ContentHandler#raw(java.io.InputStream)
      */
-    public void raw(InputStream is) throws IOException {
+    public void raw(InputStream is) throws MimeException, IOException {
     }
+
 }

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/ContentHandler.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/ContentHandler.java?view=diff&rev=541636&r1=541635&r2=541636
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/ContentHandler.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/ContentHandler.java Fri May 25 06:17:21 2007
@@ -33,6 +33,9 @@
  * part in a multipart MIME entity.
  * </p>
  * <p>
+ * Throwing an exception from an event method will terminate the message
+ * processing, i.e. no new events will be generated for that message. 
+ * <p>
  * Events will be generated in the order the corresponding elements occur in
  * the message stream parsed by the parser. E.g.:
  * <pre>
@@ -77,65 +80,81 @@
  * @version $Id: ContentHandler.java,v 1.3 2004/10/02 12:41:10 ntherning Exp $
  */
 public interface ContentHandler {
+
     /**
      * Called when a new message starts (a top level message or an embedded 
      * rfc822 message).
+     *
+     * @throws MimeException on processing errors
      */
-    void startMessage();
-    
+    void startMessage() throws MimeException;
+
     /**
      * Called when a message ends.
+     *
+     * @throws MimeException on processing errors
      */
-    void endMessage();
-    
+    void endMessage() throws MimeException;
+
     /**
      * Called when a new body part starts inside a
      * <code>multipart/*</code> entity.
+     *
+     * @throws MimeException on processing errors
      */
-    void startBodyPart();
-    
+    void startBodyPart() throws MimeException;
+
     /**
      * Called when a body part ends.
+     *
+     * @throws MimeException on processing errors
      */
-    void endBodyPart();
-    
+    void endBodyPart() throws MimeException;
+
     /**
      * Called when a header (of a message or body part) is about to be parsed.
+     *
+     * @throws MimeException on processing errors
      */
-    void startHeader();
-    
+    void startHeader() throws MimeException;
+
     /**
      * Called for each field of a header.
      * 
      * @param fieldData the raw contents of the field 
      *        (<code>Field-Name: field value</code>). The value will not be 
      *        unfolded.
+     * @throws MimeException on processing errors
      */
-    void field(String fieldData);
-    
+    void field(String fieldData) throws MimeException;
+
     /**
      * Called when there are no more header fields in a message or body part.
+     *
+     * @throws MimeException on processing errors
      */
-    void endHeader();
-    
+    void endHeader() throws MimeException;
+
     /**
      * Called for the preamble (whatever comes before the first body part)
      * of a <code>multipart/*</code> entity.
      * 
      * @param is used to get the contents of the preamble.
+     * @throws MimeException on processing errors
      * @throws IOException should be thrown on I/O errors.
      */
-    void preamble(InputStream is) throws IOException;
-    
+    void preamble(InputStream is) throws MimeException, IOException;
+
     /**
      * Called for the epilogue (whatever comes after the final body part) 
      * of a <code>multipart/*</code> entity.
      * 
      * @param is used to get the contents of the epilogue.
+     * @throws MimeException on processing errors
      * @throws IOException should be thrown on I/O errors.
      */
-    void epilogue(InputStream is) throws IOException;
-    
+    void epilogue(InputStream is) throws MimeException, IOException;
+
     /**
      * Called when the body of a multipart entity is about to be parsed.
      * 
@@ -144,14 +163,17 @@
      *        as described in the 
      *        MIME rfc:s) of the <code>Content-Type</code> and 
      *        <code>Content-Transfer-Encoding</code> header fields.
+     * @throws MimeException on processing errors
      */
-    void startMultipart(BodyDescriptor bd);
-    
+    void startMultipart(BodyDescriptor bd) throws MimeException;
+
     /**
      * Called when the body of an entity has been parsed.
+     *
+     * @throws MimeException on processing errors
      */
-    void endMultipart();
-    
+    void endMultipart() throws MimeException;
+
     /**
      * Called when the body of a discrete (non-multipart) entity is about to 
      * be parsed.
@@ -161,17 +183,21 @@
      *           - it will not be decoded if encoded. The <code>bd</code>
      *           parameter should be used to determine how the stream data
      *           should be decoded.
+     * @throws MimeException on processing errors
      * @throws IOException should be thrown on I/O errors.
      */
-    void body(BodyDescriptor bd, InputStream is) throws IOException;
-    
+    void body(BodyDescriptor bd, InputStream is)
+        throws MimeException, IOException;
+
     /**
      * Called when a new entity (message or body part) starts and the 
      * parser is in <code>raw</code> mode.
      * 
      * @param is the raw contents of the entity.
+     * @throws MimeException on processing errors
      * @throws IOException should be thrown on I/O errors.
      * @see MimeStreamParser#setRaw(boolean)
      */
-    void raw(InputStream is) throws IOException;
+    void raw(InputStream is) throws MimeException, IOException;
+
 }

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeException.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeException.java?view=auto&rev=541636
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeException.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeException.java Fri May 25 06:17:21 2007
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+package org.apache.james.mime4j;
+
+/**
+ * MIME processing exception.
+ */
+public class MimeException extends Exception {
+
+    /**
+     * Constructs a new MIME exception with the specified detail message.
+     *
+     * @param message detail message
+     */
+    public MimeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a MIME exception with the specified detail message and cause.
+     *
+     * @param message detail message
+     * @param cause cause of the exception
+     */
+    public MimeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}

Propchange: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeStreamParser.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeStreamParser.java?view=diff&rev=541636&r1=541635&r2=541636
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeStreamParser.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeStreamParser.java Fri May 25 06:17:21 2007
@@ -79,9 +79,10 @@
      * Parses a stream of bytes containing a MIME message.
      * 
      * @param is the stream to parse.
+     * @throws MimeException if the message can not be processed
      * @throws IOException on I/O errors.
      */
-    public void parse(InputStream is) throws IOException {
+    public void parse(InputStream is) throws MimeException, IOException {
         rootStream = new RootInputStream(is);
         parseMessage(rootStream);
     }
@@ -132,9 +133,10 @@
      * arbitrary data, body parts or an embedded message.
      * 
      * @param is the stream to parse.
+     * @throws MimeException if the entity can not be processed
      * @throws IOException on I/O errors.
      */
-    private void parseEntity(InputStream is) throws IOException {
+    private void parseEntity(InputStream is) throws MimeException, IOException {
         BodyDescriptor bd = parseHeader(is);
         
         if (bd.isMultipart()) {
@@ -192,7 +194,8 @@
         }
     }
     
-    private void parseMessage(InputStream is) throws IOException {
+    private void parseMessage(InputStream is)
+            throws MimeException, IOException {
         if (raw) {
             handler.raw(new CloseShieldInputStream(is));
         } else {
@@ -202,7 +205,8 @@
         }
     }
     
-    private void parseBodyPart(InputStream is) throws IOException {
+    private void parseBodyPart(InputStream is)
+            throws MimeException, IOException {
         if (raw) {
             handler.raw(new CloseShieldInputStream(is));
         } else {
@@ -218,8 +222,11 @@
      * @param is the stream to parse.
      * @return a <code>BodyDescriptor</code> describing the body following 
      *         the header.
+     * @throws MimeException if the header can not be processed
+     * @throws IOException on I/O errors
      */
-    private BodyDescriptor parseHeader(InputStream is) throws IOException {
+    private BodyDescriptor parseHeader(InputStream is)
+            throws MimeException, IOException {
         BodyDescriptor bd = new BodyDescriptor(bodyDescriptors.isEmpty() 
                         ? null : (BodyDescriptor) bodyDescriptors.getFirst());
         

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java?view=diff&rev=541636&r1=541635&r2=541636
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java Fri May 25 06:17:21 2007
@@ -31,6 +31,7 @@
 import java.util.List;
 
 import org.apache.james.mime4j.AbstractContentHandler;
+import org.apache.james.mime4j.MimeException;
 import org.apache.james.mime4j.MimeStreamParser;
 import org.apache.james.mime4j.field.ContentTypeField;
 import org.apache.james.mime4j.field.Field;
@@ -68,7 +69,14 @@
                 addField(Field.parse(fieldData));
             }
         });
-        parser.parse(is);
+        try {
+            parser.parse(is);
+        } catch (MimeException e) {
+            IllegalStateException ise = new IllegalStateException(
+                    "Unexpected header processing error");
+            ise.initCause(e);
+            throw ise;
+        }
     }
 
     /**

Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java?view=diff&rev=541636&r1=541635&r2=541636
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java Fri May 25 06:17:21 2007
@@ -26,6 +26,7 @@
 
 import org.apache.james.mime4j.BodyDescriptor;
 import org.apache.james.mime4j.ContentHandler;
+import org.apache.james.mime4j.MimeException;
 import org.apache.james.mime4j.MimeStreamParser;
 import org.apache.james.mime4j.decoder.Base64InputStream;
 import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
@@ -64,7 +65,14 @@
     public Message(InputStream is) throws IOException {
         MimeStreamParser parser = new MimeStreamParser();
         parser.setContentHandler(new MessageBuilder());
-        parser.parse(is);
+        try {
+            parser.parse(is);
+        } catch (MimeException e) {
+            IllegalStateException ise = new IllegalStateException(
+                    "Unexpected message processing error");
+            ise.initCause(e);
+            throw ise;
+        }
     }
 
     

Modified: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeStreamParserTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeStreamParserTest.java?view=diff&rev=541636&r1=541635&r2=541636
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeStreamParserTest.java (original)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeStreamParserTest.java Fri May 25 06:17:21 2007
@@ -91,7 +91,7 @@
         }
     }*/
     
-    public void testBoundaryInEpilogue() throws IOException {
+    public void testBoundaryInEpilogue() throws Exception {
         StringBuffer sb = new StringBuffer();
         sb.append("From: foo@bar.com\r\n");
         sb.append("To: someone@else.com\r\n");
@@ -136,7 +136,7 @@
         assertEquals(epilogue.toString(), actual.toString());
     }
     
-    public void testParseOneLineFields() throws IOException {
+    public void testParseOneLineFields() throws Exception {
         StringBuffer sb = new StringBuffer();
         final LinkedList expected = new LinkedList();
         expected.add("From: foo@abr.com");
@@ -156,7 +156,7 @@
         assertEquals(0, expected.size());
     }
     
-    public void testCRWithoutLFInHeader() throws IOException {
+    public void testCRWithoutLFInHeader() throws Exception {
         /*
          * Test added because \r:s not followed by \n:s in the header would
          * cause an infinite loop. 
@@ -179,7 +179,7 @@
         assertEquals(0, expected.size());
     }
     
-    public void testParseMultiLineFields() throws IOException {
+    public void testParseMultiLineFields() throws Exception {
         StringBuffer sb = new StringBuffer();
         final LinkedList expected = new LinkedList();
         expected.add("Received: by netmbx.netmbx.de (/\\==/\\ Smail3.1.28.1)\r\n"
@@ -202,7 +202,7 @@
         assertEquals(0, expected.size());
     }
     
-    public void testStop() throws IOException {
+    public void testStop() throws Exception {
         final MimeStreamParser parser = new MimeStreamParser();
         TestHandler handler = new TestHandler() {
             public void endHeader() {
@@ -239,7 +239,7 @@
     /*
      * Tests that invalid fields are ignored.
      */
-    public void testInvalidFields() throws IOException {
+    public void testInvalidFields() throws Exception {
         StringBuffer sb = new StringBuffer();
         final LinkedList expected = new LinkedList();
         sb.append("From - foo@abr.com\r\n");
@@ -264,7 +264,7 @@
     /*
      * Tests that empty streams still generate the expected series of events.
      */
-    public void testEmptyStream() throws IOException {
+    public void testEmptyStream() throws Exception {
         final LinkedList expected = new LinkedList();
         expected.add("startMessage");
         expected.add("startHeader");
@@ -323,7 +323,7 @@
     /*
      * Tests parsing of empty headers.
      */
-    public void testEmpyHeader() throws IOException {
+    public void testEmpyHeader() throws Exception {
         StringBuffer sb = new StringBuffer();
         sb.append("\r\n");
         sb.append("The body is right here\r\n");
@@ -351,7 +351,7 @@
     /*
      * Tests parsing of empty body.
      */
-    public void testEmptyBody() throws IOException {
+    public void testEmptyBody() throws Exception {
         StringBuffer sb = new StringBuffer();
         final LinkedList expected = new LinkedList();
         expected.add("From: some@one.com");
@@ -377,7 +377,7 @@
     /*
      * Tests that invalid fields are ignored.
      */
-    public void testPrematureEOFAfterFields() throws IOException {
+    public void testPrematureEOFAfterFields() throws Exception {
         StringBuffer sb = new StringBuffer();
         final LinkedList expected = new LinkedList();
         expected.add("From: some@one.com");
@@ -415,7 +415,7 @@
         assertEquals(0, expected.size());
     }
     
-    public void testParse() throws IOException {
+    public void testParse() throws Exception {
         File dir = new File("src/test/resources/testmsgs");
         File[] files = dir.listFiles();
         



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org