Index: src/test/java/org/apache/james/mime4j/stream/StrictMimeTokenStreamTest.java =================================================================== --- src/test/java/org/apache/james/mime4j/stream/StrictMimeTokenStreamTest.java (revision 905332) +++ src/test/java/org/apache/james/mime4j/stream/StrictMimeTokenStreamTest.java (working copy) @@ -34,7 +34,9 @@ public void testUnexpectedEndOfHeaders() throws Exception { - MimeTokenStream parser = MimeTokenStream.createStrictValidationStream(); + MimeEntityConfig config = new MimeEntityConfig(); + config.setStrictParsing(true); + MimeTokenStream parser = new MimeTokenStream(config); parser.parse(new ByteArrayInputStream(HEADER_ONLY.getBytes())); @@ -49,9 +51,10 @@ } public void testCorrectEndOfHeaders() throws Exception { + MimeEntityConfig config = new MimeEntityConfig(); + config.setStrictParsing(true); + MimeTokenStream parser = new MimeTokenStream(config); - MimeTokenStream parser = MimeTokenStream.createStrictValidationStream(); - parser.parse(new ByteArrayInputStream(CORRECT_HEADERS.getBytes())); assertEquals("Headers start", MimeTokenStream.T_START_HEADER, parser.next()); Index: src/test/java/org/apache/james/mime4j/parser/MaximalBodyDescriptorTest.java =================================================================== --- src/test/java/org/apache/james/mime4j/parser/MaximalBodyDescriptorTest.java (revision 905332) +++ src/test/java/org/apache/james/mime4j/parser/MaximalBodyDescriptorTest.java (working copy) @@ -23,10 +23,10 @@ import org.apache.james.mime4j.ExampleMail; import org.apache.james.mime4j.dom.datetime.DateTime; -import org.apache.james.mime4j.parser.MaximalBodyDescriptor; import org.apache.james.mime4j.parser.MimeTokenStream; import org.apache.james.mime4j.stream.BaseTestForBodyDescriptors; import org.apache.james.mime4j.stream.BodyDescriptor; +import org.apache.james.mime4j.stream.MimeEntityConfig; import org.apache.james.mime4j.stream.MutableBodyDescriptor; public class MaximalBodyDescriptorTest extends BaseTestForBodyDescriptors { @@ -36,7 +36,7 @@ @Override protected void setUp() throws Exception { super.setUp(); - parser = MimeTokenStream.createMaximalDescriptorStream(); + parser = new MimeTokenStream(new MimeEntityConfig(), null, new MaximalBodyDescriptorFactory()); } @Override @@ -183,7 +183,7 @@ @Override protected MutableBodyDescriptor newBodyDescriptor() { - return new MaximalBodyDescriptor(); + return new MaximalBodyDescriptor(null); } @Override Index: src/main/java/org/apache/james/mime4j/message/MessageImpl.java =================================================================== --- src/main/java/org/apache/james/mime4j/message/MessageImpl.java (revision 905332) +++ src/main/java/org/apache/james/mime4j/message/MessageImpl.java (working copy) @@ -54,6 +54,7 @@ import org.apache.james.mime4j.storage.DefaultStorageProvider; import org.apache.james.mime4j.storage.StorageProvider; import org.apache.james.mime4j.stream.MimeEntityConfig; +import org.apache.james.mime4j.stream.MutableBodyDescriptorFactory; import org.apache.james.mime4j.util.MimeUtil; /** @@ -145,16 +146,21 @@ * @param storageProvider * {@link StorageProvider} to use for storing text and binary * message bodies. + * @param bodyDescFactory + * {@link MutableBodyDescriptorFactory} to use for creating body descriptors. * @throws IOException * on I/O errors. * @throws MimeIOException * on MIME protocol violations. */ - public MessageImpl(InputStream is, MimeEntityConfig config, - StorageProvider storageProvider, DecodeMonitor monitor) throws IOException, - MimeIOException { + public MessageImpl( + final InputStream is, + final MimeEntityConfig config, + final StorageProvider storageProvider, + final DecodeMonitor monitor, + final MutableBodyDescriptorFactory bodyDescFactory) throws IOException, MimeIOException { try { - MimeStreamParser parser = new MimeStreamParser(config, monitor); + MimeStreamParser parser = new MimeStreamParser(config, monitor, bodyDescFactory); parser.setContentDecoding(true); this.monitor = monitor != null ? monitor : LoggingMonitor.MONITOR; parser.setContentHandler(new MessageBuilder(this, storageProvider, this.monitor)); @@ -164,11 +170,21 @@ } } - public MessageImpl(InputStream is, MimeEntityConfig config, - StorageProvider storageProvider) throws IOException, MimeIOException { - this(is, config, storageProvider, LoggingMonitor.MONITOR); + public MessageImpl( + final InputStream is, + final MimeEntityConfig config, + final StorageProvider storageProvider, + final MutableBodyDescriptorFactory bodyDescFactory) throws IOException, MimeIOException { + this(is, config, storageProvider, LoggingMonitor.MONITOR, bodyDescFactory); } + public MessageImpl( + final InputStream is, + final MimeEntityConfig config, + final StorageProvider storageProvider) throws IOException, MimeIOException { + this(is, config, storageProvider, LoggingMonitor.MONITOR, null); + } + /** * @see org.apache.james.mime4j.dom.Message#writeTo(java.io.OutputStream) */ Index: src/main/java/org/apache/james/mime4j/message/MessageBuilder.java =================================================================== --- src/main/java/org/apache/james/mime4j/message/MessageBuilder.java (revision 905332) +++ src/main/java/org/apache/james/mime4j/message/MessageBuilder.java (working copy) @@ -48,7 +48,7 @@ private final Entity entity; private final BodyFactory bodyFactory; - private Stack stack = new Stack(); + private final Stack stack; private final DecodeMonitor monitor; public MessageBuilder(Entity entity) { @@ -62,6 +62,7 @@ public MessageBuilder(Entity entity, StorageProvider storageProvider, DecodeMonitor monitor) { this.entity = entity; this.bodyFactory = new BodyFactory(storageProvider); + this.stack = new Stack(); this.monitor = monitor != null ? monitor : LoggingMonitor.MONITOR; } Index: src/main/java/org/apache/james/mime4j/stream/BasicMimeTokenStream.java =================================================================== --- src/main/java/org/apache/james/mime4j/stream/BasicMimeTokenStream.java (revision 905332) +++ src/main/java/org/apache/james/mime4j/stream/BasicMimeTokenStream.java (working copy) @@ -75,13 +75,14 @@ public class BasicMimeTokenStream implements EntityStates, RecursionMode { private final MimeEntityConfig config; + private final DecodeMonitor monitor; + private final MutableBodyDescriptorFactory bodyDescFactory; private final LinkedList entities = new LinkedList(); private int state = T_END_OF_STREAM; private EntityStateMachine currentStateMachine; private int recursionMode = M_RECURSE; private MimeEntity rootentity; - private final DecodeMonitor monitor; /** * Constructs a standard (lax) stream. @@ -94,16 +95,26 @@ } public BasicMimeTokenStream(final MimeEntityConfig config) { - this(config, null); + this(config, null, null); } - public BasicMimeTokenStream(final MimeEntityConfig config, DecodeMonitor monitor) { + public BasicMimeTokenStream( + final MimeEntityConfig config, + final MutableBodyDescriptorFactory bodyDescFactory) { + this(config, null, bodyDescFactory); + } + + public BasicMimeTokenStream( + final MimeEntityConfig config, + final DecodeMonitor monitor, + final MutableBodyDescriptorFactory bodyDescFactory) { super(); this.config = config; - this.monitor = monitor != null ? monitor : (config.isStrictParsing() ? DecodeMonitor.STRICT : DecodeMonitor.SILENT); + this.monitor = monitor != null ? monitor : + (config.isStrictParsing() ? DecodeMonitor.STRICT : DecodeMonitor.SILENT); + this.bodyDescFactory = bodyDescFactory; } - /** Instructs the {@code MimeTokenStream} to parse the given streams contents. * If the {@code MimeTokenStream} has already been in use, resets the streams * internal state. @@ -138,9 +149,20 @@ doParse(stream, newBodyDescriptor, start); } + /** + * Creates a new instance of {@link BodyDescriptor}. Subclasses may override + * this in order to create body descriptors, that provide more specific + * information. + */ protected MutableBodyDescriptor newBodyDescriptor() { - return new DefaultBodyDescriptor(null); - } + final MutableBodyDescriptor result; + if (bodyDescFactory != null) { + result = bodyDescFactory.newInstance(); + } else { + result = new DefaultBodyDescriptor(null); + } + return result; + } public void doParse(InputStream stream, MutableBodyDescriptor newBodyDescriptor, int start) { Index: src/main/java/org/apache/james/mime4j/stream/MimeEntityConfig.java =================================================================== --- src/main/java/org/apache/james/mime4j/stream/MimeEntityConfig.java (revision 905332) +++ src/main/java/org/apache/james/mime4j/stream/MimeEntityConfig.java (working copy) @@ -20,16 +20,12 @@ package org.apache.james.mime4j.stream; import org.apache.james.mime4j.MimeException; -import org.apache.james.mime4j.parser.MaximalBodyDescriptor; -import org.apache.james.mime4j.parser.MimeStreamParser; -import org.apache.james.mime4j.parser.MimeTokenStream; /** * MIME entity configuration */ public final class MimeEntityConfig implements Cloneable { - private boolean maximalBodyDescriptor; private boolean strictParsing; private int maxLineLen; private int maxHeaderCount; @@ -40,7 +36,6 @@ private boolean malformedHeaderStartsBody; public MimeEntityConfig() { - this.maximalBodyDescriptor = false; this.strictParsing = false; this.maxLineLen = 1000; this.maxHeaderCount = 1000; @@ -75,36 +70,6 @@ } /** - * Returns true if the maximum body descriptor should be - * used, false for the default body descriptor. - * - * @see #setMaximalBodyDescriptor(boolean) - * - * @return value of maximum body descriptor. - */ - public boolean isMaximalBodyDescriptor() { - return this.maximalBodyDescriptor; - } - - /** - * Specified whether the parser should use an instance of - * {@link MaximalBodyDescriptor} instead of {@link DefaultBodyDescriptor} to - * encapsulate the values of MIME-specific header fields. - *

- * The body descriptor can be retrieved by calling - * {@link MimeTokenStream#getBodyDescriptor()}. - *

- * Default value: false - * - * @param maximalBodyDescriptor true to use an instance of - * {@link MaximalBodyDescriptor}, false for an - * instance of {@link DefaultBodyDescriptor}. - */ - public void setMaximalBodyDescriptor(boolean maximalBodyDescriptor) { - this.maximalBodyDescriptor = maximalBodyDescriptor; - } - - /** * Returns the value of the strict parsing mode * @see #setStrictParsing(boolean) * @@ -290,8 +255,7 @@ @Override public String toString() { - return "[max body descriptor: " + maximalBodyDescriptor - + ", strict parsing: " + strictParsing + ", max line length: " + return "[strict parsing: " + strictParsing + ", max line length: " + maxLineLen + ", max header count: " + maxHeaderCount + ", max content length: " + maxContentLen + ", count line numbers: " + countLineNumbers + "]"; Index: src/main/java/org/apache/james/mime4j/stream/MutableBodyDescriptorFactory.java =================================================================== --- src/main/java/org/apache/james/mime4j/stream/MutableBodyDescriptorFactory.java (revision 0) +++ src/main/java/org/apache/james/mime4j/stream/MutableBodyDescriptorFactory.java (revision 0) @@ -0,0 +1,29 @@ +/**************************************************************** + * 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.stream; + +/** + * {@link MutableBodyDescriptor} factory. + */ +public interface MutableBodyDescriptorFactory { + + MutableBodyDescriptor newInstance(); + +} Index: src/main/java/org/apache/james/mime4j/parser/MimeStreamParser.java =================================================================== --- src/main/java/org/apache/james/mime4j/parser/MimeStreamParser.java (revision 905332) +++ src/main/java/org/apache/james/mime4j/parser/MimeStreamParser.java (working copy) @@ -29,6 +29,7 @@ import org.apache.james.mime4j.stream.BodyDescriptor; import org.apache.james.mime4j.stream.ContentHandler; import org.apache.james.mime4j.stream.MimeEntityConfig; +import org.apache.james.mime4j.stream.MutableBodyDescriptorFactory; /** *

@@ -59,24 +60,32 @@ this.contentDecoding = false; } - public MimeStreamParser(final MimeEntityConfig config, DecodeMonitor monitor, boolean clone) { - this(new MimeTokenStream(clone ? config.clone() : config, monitor)); + public MimeStreamParser( + final MimeEntityConfig config, + boolean clone, + final DecodeMonitor monitor, + final MutableBodyDescriptorFactory bodyDescFactory) { + this(new MimeTokenStream(clone ? config.clone() : config, monitor, bodyDescFactory)); } public MimeStreamParser(final MimeEntityConfig config, boolean clone) { - this(new MimeTokenStream(clone ? config.clone() : config, null)); + this(new MimeTokenStream(clone ? config.clone() : config, null, null)); } - public MimeStreamParser(final MimeEntityConfig config, DecodeMonitor monitor) { - this(config != null ? config : new MimeEntityConfig(), monitor, config != null); + public MimeStreamParser( + final MimeEntityConfig config, + final DecodeMonitor monitor, + final MutableBodyDescriptorFactory bodyDescFactory) { + this(config != null ? config : new MimeEntityConfig(), config != null, + monitor, bodyDescFactory); } public MimeStreamParser(final MimeEntityConfig config) { - this(config, null); + this(config, null, null); } public MimeStreamParser() { - this(new MimeEntityConfig(), false); + this(new MimeEntityConfig(), false, null, null); } /** Index: src/main/java/org/apache/james/mime4j/parser/MimeTokenStream.java =================================================================== --- src/main/java/org/apache/james/mime4j/parser/MimeTokenStream.java (revision 905332) +++ src/main/java/org/apache/james/mime4j/parser/MimeTokenStream.java (working copy) @@ -23,10 +23,8 @@ import org.apache.james.mime4j.codec.DecodeMonitor; import org.apache.james.mime4j.stream.BasicMimeTokenStream; -import org.apache.james.mime4j.stream.BodyDescriptor; -import org.apache.james.mime4j.stream.DefaultBodyDescriptor; import org.apache.james.mime4j.stream.MimeEntityConfig; -import org.apache.james.mime4j.stream.MutableBodyDescriptor; +import org.apache.james.mime4j.stream.MutableBodyDescriptorFactory; /** *

@@ -67,60 +65,26 @@ * one instance per thread.

*/ public class MimeTokenStream extends BasicMimeTokenStream { - - /** - * Creates a stream that creates a more detailed body descriptor. - * @return MimeTokenStream, not null - */ - public static final MimeTokenStream createMaximalDescriptorStream() { - MimeEntityConfig config = new MimeEntityConfig(); - config.setMaximalBodyDescriptor(true); - return new MimeTokenStream(config); - } - - /** - * Creates a stream that strictly validates the input. - * @return MimeTokenStream which throws a - * MimeException whenever possible issues - * are dedicated in the input - */ - public static final MimeTokenStream createStrictValidationStream() { - MimeEntityConfig config = new MimeEntityConfig(); - config.setStrictParsing(true); - return new MimeTokenStream(config); - } - - /** - * Constructs a standard (lax) stream. - * Optional validation events will be logged only. - * Use {@link #createStrictValidationStream()} to create - * a stream that strictly validates the input. - */ + public MimeTokenStream() { - this(new MimeEntityConfig()); + super(new MimeEntityConfig()); } - + public MimeTokenStream(final MimeEntityConfig config) { - this(config, null); + super(config, null, null); } - - public MimeTokenStream(final MimeEntityConfig config, DecodeMonitor monitor) { - super(config, monitor); + + public MimeTokenStream( + final MimeEntityConfig config, + final MutableBodyDescriptorFactory bodyDescFactory) { + super(config, null, bodyDescFactory); } - /** - * Creates a new instance of {@link BodyDescriptor}. Subclasses may override - * this in order to create body descriptors, that provide more specific - * information. - */ - protected MutableBodyDescriptor newBodyDescriptor() { - final MutableBodyDescriptor result; - if (getConfig().isMaximalBodyDescriptor()) { - result = new MaximalBodyDescriptor(null); - } else { - result = new DefaultBodyDescriptor(null); - } - return result; + public MimeTokenStream( + final MimeEntityConfig config, + final DecodeMonitor monitor, + final MutableBodyDescriptorFactory bodyDescFactory) { + super(config, monitor, bodyDescFactory); } - + } Index: src/main/java/org/apache/james/mime4j/parser/MaximalBodyDescriptorFactory.java =================================================================== --- src/main/java/org/apache/james/mime4j/parser/MaximalBodyDescriptorFactory.java (revision 0) +++ src/main/java/org/apache/james/mime4j/parser/MaximalBodyDescriptorFactory.java (revision 0) @@ -0,0 +1,31 @@ +/**************************************************************** + * 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.parser; + +import org.apache.james.mime4j.stream.MutableBodyDescriptor; +import org.apache.james.mime4j.stream.MutableBodyDescriptorFactory; + +public class MaximalBodyDescriptorFactory implements MutableBodyDescriptorFactory { + + public MutableBodyDescriptor newInstance() { + return new MaximalBodyDescriptor(null); + } + +}