[maven-release-plugin] copy for tag apache-mime4j-0.5
git-svn-id: https://svn.apache.org/repos/asf/james/mime4j/tags/apache-mime4j-0.5@703860 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index cae62a6..c3abd6b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
<groupId>org.apache.james</groupId>
<artifactId>apache-mime4j</artifactId>
<name>Apache JAMES Mime4j</name>
- <version>0.5-SNAPSHOT</version>
+ <version>0.5</version>
<description>Java stream based MIME message parser</description>
<url>http://james.apache.org/mime4j</url>
<issueManagement>
@@ -44,9 +44,9 @@
</site>
</distributionManagement>
<scm>
- <connection>scm:svn:http://svn.apache.org/repos/asf/james/mime4j/trunk</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/james/mime4j/trunk</developerConnection>
- <url>http://svn.apache.org/viewvc/james/mime4j/trunk/</url>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/james/mime4j/tags/apache-mime4j-0.5</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/james/mime4j/tags/apache-mime4j-0.5</developerConnection>
+ <url>http://svn.apache.org/viewvc/james/mime4j/tags/apache-mime4j-0.5</url>
</scm>
<build>
<plugins>
diff --git a/src/main/java/org/apache/james/mime4j/decoder/LineBreakingOutputStream.java b/src/main/java/org/apache/james/mime4j/decoder/LineBreakingOutputStream.java
index 2d5c06f..62ef8f7 100644
--- a/src/main/java/org/apache/james/mime4j/decoder/LineBreakingOutputStream.java
+++ b/src/main/java/org/apache/james/mime4j/decoder/LineBreakingOutputStream.java
@@ -29,6 +29,8 @@
* Default to 76 bytes lines.
* Please note that this does not check for existing newlines and
* simply adds CRLF every 76 bytes.
+ *
+ * @deprecated This class will be removed in 0.6 release
*/
public class LineBreakingOutputStream extends FilterOutputStream {
diff --git a/src/main/java/org/apache/james/mime4j/io/CloseShieldInputStream.java b/src/main/java/org/apache/james/mime4j/io/CloseShieldInputStream.java
index 1892518..e7ad170 100644
--- a/src/main/java/org/apache/james/mime4j/io/CloseShieldInputStream.java
+++ b/src/main/java/org/apache/james/mime4j/io/CloseShieldInputStream.java
@@ -26,6 +26,8 @@
/**
* InputStream that shields its underlying input stream from
* being closed.
+ *
+ * @deprecated This class will be removed in 0.6 release
*/
public class CloseShieldInputStream extends FilterInputStream {
diff --git a/src/main/java/org/apache/james/mime4j/io/PartialInputStream.java b/src/main/java/org/apache/james/mime4j/io/PartialInputStream.java
index fe6bc60..93b07d1 100644
--- a/src/main/java/org/apache/james/mime4j/io/PartialInputStream.java
+++ b/src/main/java/org/apache/james/mime4j/io/PartialInputStream.java
@@ -23,6 +23,9 @@
import java.io.InputStream;
import java.io.IOException;
+/**
+ * @deprecated This class will be removed in 0.6 release
+ */
public class PartialInputStream extends PositionInputStream {
private final long limit;
diff --git a/src/main/java/org/apache/james/mime4j/message/AbstractBody.java b/src/main/java/org/apache/james/mime4j/message/AbstractBody.java
index 1dd39bc..4512483 100644
--- a/src/main/java/org/apache/james/mime4j/message/AbstractBody.java
+++ b/src/main/java/org/apache/james/mime4j/message/AbstractBody.java
@@ -1,80 +1,59 @@
-/****************************************************************
- * 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.message;
-
-
-/**
- * Abstract <code>Body</code> implementation providing the parent
- * functionality required by bodies.
- *
- *
- * @version $Id: AbstractBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
- */
-public abstract class AbstractBody implements Body {
- private Entity parent = null;
- protected boolean disposed = false;
-
- /**
- * @see org.apache.james.mime4j.message.Body#getParent()
- */
- public Entity getParent() {
- return parent;
- }
-
- /**
- * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
- */
- public void setParent(Entity parent) {
- if (disposed)
- throw new IllegalStateException("AbstractBody has been disposed");
-
- this.parent = parent;
- }
-
- /**
- * Subclasses should override this method if they have allocated resources
- * that need to be freed explicitly (e.g. cannot be simply reclaimed by the
- * garbage collector). Subclasses that override this method should invoke
- * super.dispose().
- *
- * The default implementation marks this AbstractBody as disposed.
- *
- * @see org.apache.james.mime4j.message.Disposable#dispose()
- */
- public void dispose() {
- if (disposed)
- return;
-
- disposed = true;
-
- parent = null;
- }
-
- /**
- * Ensures that the <code>dispose</code> method of this abstract body is
- * called when there are no more references to it.
- *
- * Leave them out ATM (https://issues.apache.org/jira/browse/MIME4J-72?focusedCommentId=12636007#action_12636007)
- protected void finalize() throws Throwable {
- dispose();
- }
- */
-
-}
+/****************************************************************
+ * 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.message;
+
+
+/**
+ * Abstract <code>Body</code> implementation providing the parent
+ * functionality required by bodies.
+ *
+ *
+ * @version $Id: AbstractBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+public abstract class AbstractBody implements Body {
+ private Entity parent = null;
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#getParent()
+ */
+ public Entity getParent() {
+ return parent;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
+ */
+ public void setParent(Entity parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Subclasses should override this method if they have allocated resources
+ * that need to be freed explicitly (e.g. cannot be simply reclaimed by the
+ * garbage collector).
+ *
+ * The default implementation of this method does nothing.
+ *
+ * @see org.apache.james.mime4j.message.Disposable#dispose()
+ */
+ public void dispose() {
+ }
+
+}
diff --git a/src/main/java/org/apache/james/mime4j/message/Disposable.java b/src/main/java/org/apache/james/mime4j/message/Disposable.java
index b580af1..00b2262 100644
--- a/src/main/java/org/apache/james/mime4j/message/Disposable.java
+++ b/src/main/java/org/apache/james/mime4j/message/Disposable.java
@@ -27,5 +27,10 @@
* holding (such as open files).
*/
public interface Disposable {
+ /**
+ * Free any resources this object is holding and prepares this object
+ * for garbage collection. Once an object has been disposed it can no
+ * longer be used.
+ */
void dispose();
}
diff --git a/src/main/java/org/apache/james/mime4j/message/Entity.java b/src/main/java/org/apache/james/mime4j/message/Entity.java
index bda38f7..2a71b0f 100644
--- a/src/main/java/org/apache/james/mime4j/message/Entity.java
+++ b/src/main/java/org/apache/james/mime4j/message/Entity.java
@@ -1,246 +1,213 @@
-/****************************************************************
- * 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.message;
-
-import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.decoder.CodecUtil;
-import org.apache.james.mime4j.field.ContentTransferEncodingField;
-import org.apache.james.mime4j.field.ContentTypeField;
-import org.apache.james.mime4j.field.Field;
-import org.apache.james.mime4j.util.MessageUtils;
-import org.apache.james.mime4j.util.MimeUtil;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * MIME entity. An entity has a header and a body (see RFC 2045).
- *
- *
- * @version $Id: Entity.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
- */
-public abstract class Entity implements Disposable {
- private Header header = null;
- private Body body = null;
- private Entity parent = null;
- private boolean disposed = false;
-
- /**
- * Gets the parent entity of this entity.
- * Returns <code>null</code> if this is the root entity.
- *
- * @return the parent or <code>null</code>.
- */
- public Entity getParent() {
- return parent;
- }
-
- /**
- * Sets the parent entity of this entity.
- *
- * @param parent the parent entity or <code>null</code> if
- * this will be the root entity.
- */
- public void setParent(Entity parent) {
- if (disposed)
- throw new IllegalStateException("Entity has been disposed");
-
- this.parent = parent;
- }
-
- /**
- * Gets the entity header.
- *
- * @return the header.
- */
- public Header getHeader() {
- return header;
- }
-
- /**
- * Sets the entity header.
- *
- * @param header the header.
- */
- public void setHeader(Header header) {
- if (disposed)
- throw new IllegalStateException("Entity has been disposed");
-
- this.header = header;
- }
-
- /**
- * Gets the body of this entity.
- *
- * @return the body,
- */
- public Body getBody() {
- return body;
- }
-
- /**
- * Sets the body of this entity.
- *
- * @param body the body.
- */
- public void setBody(Body body) {
- if (disposed)
- throw new IllegalStateException("Entity has been disposed");
-
- this.body = body;
- body.setParent(this);
- }
-
- /**
- * Determines the MIME type of this <code>Entity</code>. The MIME type
- * is derived by looking at the parent's Content-Type field if no
- * Content-Type field is set for this <code>Entity</code>.
- *
- * @return the MIME type.
- */
- public String getMimeType() {
- ContentTypeField child =
- (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
- ContentTypeField parent = getParent() != null
- ? (ContentTypeField) getParent().getHeader().
- getField(Field.CONTENT_TYPE)
- : null;
-
- return ContentTypeField.getMimeType(child, parent);
- }
-
- /**
- * Determines the MIME character set encoding of this <code>Entity</code>.
- *
- * @return the MIME character set encoding.
- */
- public String getCharset() {
- return ContentTypeField.getCharset(
- (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE));
- }
-
- /**
- * Determines the transfer encoding of this <code>Entity</code>.
- *
- * @return the transfer encoding.
- */
- public String getContentTransferEncoding() {
- ContentTransferEncodingField f = (ContentTransferEncodingField)
- getHeader().getField(Field.CONTENT_TRANSFER_ENCODING);
-
- return ContentTransferEncodingField.getEncoding(f);
- }
-
- /**
- * Determines if the MIME type of this <code>Entity</code> matches the
- * given one. MIME types are case-insensitive.
- *
- * @param type the MIME type to match against.
- * @return <code>true</code> on match, <code>false</code> otherwise.
- */
- public boolean isMimeType(String type) {
- return getMimeType().equalsIgnoreCase(type);
- }
-
- /**
- * Determines if the MIME type of this <code>Entity</code> is
- * <code>multipart/*</code>. Since multipart-entities must have
- * a boundary parameter in the <code>Content-Type</code> field this
- * method returns <code>false</code> if no boundary exists.
- *
- * @return <code>true</code> on match, <code>false</code> otherwise.
- */
- public boolean isMultipart() {
- ContentTypeField f =
- (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
- return f != null && f.getBoundary() != null
- && getMimeType().startsWith(ContentTypeField.TYPE_MULTIPART_PREFIX);
- }
-
- /**
- * Write the content to the given outputstream
- *
- * @param out the outputstream to write to
- * @param mode compatibility mode:
- * {@link MessageUtils#LENIENT}, {@link MessageUtils#STRICT_ERROR}, {@link MessageUtils#STRICT_IGNORE}
- * @throws IOException
- */
- public void writeTo(OutputStream out, int mode) throws IOException, MimeException {
- if (disposed)
- throw new IllegalStateException("Entity has been disposed");
-
- getHeader().writeTo(out, mode);
-
- out.flush();
-
- final Body body = getBody();
-
- OutputStream encOut;
- if (MimeUtil.ENC_BASE64.equals(getContentTransferEncoding())) {
- encOut = CodecUtil.wrapBase64(out);
- } else if (MimeUtil.ENC_QUOTED_PRINTABLE.equals(getContentTransferEncoding())) {
- encOut = CodecUtil.wrapQuotedPrintable(out, (body instanceof BinaryBody));
- } else {
- encOut = out;
- }
- body.writeTo(encOut, mode);
- encOut.flush();
- // the Base64 output streams requires closing of the stream but
- // we don't want it to close the inner stream so we override the behaviour
- // for the wrapping stream writer.
- if (encOut != out) encOut.close();
- }
-
- /**
- * Disposes the body of this entity. Note that the dispose call does not get
- * forwarded to the parent entity of this Entity.
- *
- * Subclasses that need to free resources should override this method and
- * invoke super.dispose().
- *
- * @see org.apache.james.mime4j.message.Disposable#dispose()
- */
- public void dispose() {
- if (disposed)
- return;
-
- try {
- if (body != null)
- body.dispose();
- } finally {
- disposed = true;
-
- header = null;
- body = null;
- parent = null;
- }
- }
-
- /**
- * Ensures that the <code>dispose</code> method of this entity is called
- * when there are no more references to it.
- *
- * Leave them out ATM (https://issues.apache.org/jira/browse/MIME4J-72?focusedCommentId=12636007#action_12636007)
- protected void finalize() throws Throwable {
- dispose();
- }
- */
-
-}
+/****************************************************************
+ * 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.message;
+
+import org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.decoder.CodecUtil;
+import org.apache.james.mime4j.field.ContentTransferEncodingField;
+import org.apache.james.mime4j.field.ContentTypeField;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.util.MessageUtils;
+import org.apache.james.mime4j.util.MimeUtil;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * MIME entity. An entity has a header and a body (see RFC 2045).
+ *
+ *
+ * @version $Id: Entity.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public abstract class Entity implements Disposable {
+ private Header header = null;
+ private Body body = null;
+ private Entity parent = null;
+
+ /**
+ * Gets the parent entity of this entity.
+ * Returns <code>null</code> if this is the root entity.
+ *
+ * @return the parent or <code>null</code>.
+ */
+ public Entity getParent() {
+ return parent;
+ }
+
+ /**
+ * Sets the parent entity of this entity.
+ *
+ * @param parent the parent entity or <code>null</code> if
+ * this will be the root entity.
+ */
+ public void setParent(Entity parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Gets the entity header.
+ *
+ * @return the header.
+ */
+ public Header getHeader() {
+ return header;
+ }
+
+ /**
+ * Sets the entity header.
+ *
+ * @param header the header.
+ */
+ public void setHeader(Header header) {
+ this.header = header;
+ }
+
+ /**
+ * Gets the body of this entity.
+ *
+ * @return the body,
+ */
+ public Body getBody() {
+ return body;
+ }
+
+ /**
+ * Sets the body of this entity.
+ *
+ * @param body the body.
+ */
+ public void setBody(Body body) {
+ this.body = body;
+ body.setParent(this);
+ }
+
+ /**
+ * Determines the MIME type of this <code>Entity</code>. The MIME type
+ * is derived by looking at the parent's Content-Type field if no
+ * Content-Type field is set for this <code>Entity</code>.
+ *
+ * @return the MIME type.
+ */
+ public String getMimeType() {
+ ContentTypeField child =
+ (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
+ ContentTypeField parent = getParent() != null
+ ? (ContentTypeField) getParent().getHeader().
+ getField(Field.CONTENT_TYPE)
+ : null;
+
+ return ContentTypeField.getMimeType(child, parent);
+ }
+
+ /**
+ * Determines the MIME character set encoding of this <code>Entity</code>.
+ *
+ * @return the MIME character set encoding.
+ */
+ public String getCharset() {
+ return ContentTypeField.getCharset(
+ (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE));
+ }
+
+ /**
+ * Determines the transfer encoding of this <code>Entity</code>.
+ *
+ * @return the transfer encoding.
+ */
+ public String getContentTransferEncoding() {
+ ContentTransferEncodingField f = (ContentTransferEncodingField)
+ getHeader().getField(Field.CONTENT_TRANSFER_ENCODING);
+
+ return ContentTransferEncodingField.getEncoding(f);
+ }
+
+ /**
+ * Determines if the MIME type of this <code>Entity</code> matches the
+ * given one. MIME types are case-insensitive.
+ *
+ * @param type the MIME type to match against.
+ * @return <code>true</code> on match, <code>false</code> otherwise.
+ */
+ public boolean isMimeType(String type) {
+ return getMimeType().equalsIgnoreCase(type);
+ }
+
+ /**
+ * Determines if the MIME type of this <code>Entity</code> is
+ * <code>multipart/*</code>. Since multipart-entities must have
+ * a boundary parameter in the <code>Content-Type</code> field this
+ * method returns <code>false</code> if no boundary exists.
+ *
+ * @return <code>true</code> on match, <code>false</code> otherwise.
+ */
+ public boolean isMultipart() {
+ ContentTypeField f =
+ (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
+ return f != null && f.getBoundary() != null
+ && getMimeType().startsWith(ContentTypeField.TYPE_MULTIPART_PREFIX);
+ }
+
+ /**
+ * Write the content to the given outputstream
+ *
+ * @param out the outputstream to write to
+ * @param mode compatibility mode:
+ * {@link MessageUtils#LENIENT}, {@link MessageUtils#STRICT_ERROR}, {@link MessageUtils#STRICT_IGNORE}
+ * @throws IOException
+ */
+ public void writeTo(OutputStream out, int mode) throws IOException, MimeException {
+ getHeader().writeTo(out, mode);
+
+ out.flush();
+
+ final Body body = getBody();
+
+ OutputStream encOut;
+ if (MimeUtil.ENC_BASE64.equals(getContentTransferEncoding())) {
+ encOut = CodecUtil.wrapBase64(out);
+ } else if (MimeUtil.ENC_QUOTED_PRINTABLE.equals(getContentTransferEncoding())) {
+ encOut = CodecUtil.wrapQuotedPrintable(out, (body instanceof BinaryBody));
+ } else {
+ encOut = out;
+ }
+ body.writeTo(encOut, mode);
+ encOut.flush();
+ // the Base64 output streams requires closing of the stream but
+ // we don't want it to close the inner stream so we override the behaviour
+ // for the wrapping stream writer.
+ if (encOut != out) encOut.close();
+ }
+
+ /**
+ * Disposes the body of this entity. Note that the dispose call does not get
+ * forwarded to the parent entity of this Entity.
+ *
+ * Subclasses that need to free resources should override this method and
+ * invoke super.dispose().
+ *
+ * @see org.apache.james.mime4j.message.Disposable#dispose()
+ */
+ public void dispose() {
+ if (body != null) {
+ body.dispose();
+ }
+ }
+
+}
diff --git a/src/main/java/org/apache/james/mime4j/message/Multipart.java b/src/main/java/org/apache/james/mime4j/message/Multipart.java
index 4a7d2ef..3a1150f 100644
--- a/src/main/java/org/apache/james/mime4j/message/Multipart.java
+++ b/src/main/java/org/apache/james/mime4j/message/Multipart.java
@@ -1,281 +1,237 @@
-/****************************************************************
- * 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.message;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.nio.charset.Charset;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.field.ContentTypeField;
-import org.apache.james.mime4j.field.Field;
-import org.apache.james.mime4j.util.CharsetUtil;
-import org.apache.james.mime4j.util.MessageUtils;
-
-/**
- * Represents a MIME multipart body (see RFC 2045).A multipart body has a
- * ordered list of body parts. The multipart body also has a preamble and
- * epilogue. The preamble consists of whatever characters appear before the
- * first body part while the epilogue consists of whatever characters come
- * after the last body part.
- *
- *
- * @version $Id: Multipart.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
- */
-public class Multipart implements Body {
- private String preamble = "";
- private String epilogue = "";
- private List bodyParts = new LinkedList();
- private Entity parent = null;
- private String subType;
- private boolean disposed = false;
-
- /**
- * Creates a new empty <code>Multipart</code> instance.
- */
- public Multipart(String subType) {
- this.subType = subType;
- }
-
- /**
- * Gets the multipart sub-type. E.g. <code>alternative</code> (the default)
- * or <code>parallel</code>. See RFC 2045 for common sub-types and their
- * meaning.
- *
- * @return the multipart sub-type.
- */
- public String getSubType() {
- return subType;
- }
-
- /**
- * Sets the multipart sub-type. E.g. <code>alternative</code>
- * or <code>parallel</code>. See RFC 2045 for common sub-types and their
- * meaning.
- *
- * @param subType the sub-type.
- */
- public void setSubType(String subType) {
- if (disposed)
- throw new IllegalStateException("Multipart has been disposed");
-
- this.subType = subType;
- }
-
- /**
- * @see org.apache.james.mime4j.message.Body#getParent()
- */
- public Entity getParent() {
- return parent;
- }
-
- /**
- * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
- */
- public void setParent(Entity parent) {
- if (disposed)
- throw new IllegalStateException("Multipart has been disposed");
-
- this.parent = parent;
- for (Iterator it = bodyParts.iterator(); it.hasNext();) {
- ((BodyPart) it.next()).setParent(parent);
- }
- }
-
- /**
- * Gets the epilogue.
- *
- * @return the epilogue.
- */
- public String getEpilogue() {
- return epilogue;
- }
-
- /**
- * Sets the epilogue.
- *
- * @param epilogue the epilogue.
- */
- public void setEpilogue(String epilogue) {
- if (disposed)
- throw new IllegalStateException("Multipart has been disposed");
-
- this.epilogue = epilogue;
- }
-
- /**
- * Gets the list of body parts. The list is immutable.
- *
- * @return the list of <code>BodyPart</code> objects.
- */
- public List getBodyParts() {
- return Collections.unmodifiableList(bodyParts);
- }
-
- /**
- * Sets the list of body parts.
- *
- * @param bodyParts the new list of <code>BodyPart</code> objects.
- */
- public void setBodyParts(List bodyParts) {
- if (disposed)
- throw new IllegalStateException("Multipart has been disposed");
-
- this.bodyParts = bodyParts;
- for (Iterator it = bodyParts.iterator(); it.hasNext();) {
- ((BodyPart) it.next()).setParent(parent);
- }
- }
-
- /**
- * Adds a body part to the end of the list of body parts.
- *
- * @param bodyPart the body part.
- */
- public void addBodyPart(BodyPart bodyPart) {
- if (disposed)
- throw new IllegalStateException("Multipart has been disposed");
-
- bodyParts.add(bodyPart);
- bodyPart.setParent(parent);
- }
-
- /**
- * Gets the preamble.
- *
- * @return the preamble.
- */
- public String getPreamble() {
- return preamble;
- }
-
- /**
- * Sets the preamble.
- *
- * @param preamble the preamble.
- */
- public void setPreamble(String preamble) {
- if (disposed)
- throw new IllegalStateException("Multipart has been disposed");
-
- this.preamble = preamble;
- }
-
- /**
- * Write the Multipart to the given OutputStream.
- *
- * @param out the OutputStream to write to
- * @param mode compatibility mode
- *
- * @throws IOException if case of an I/O error
- * @throws MimeException if case of a MIME protocol violation
- */
- public void writeTo(final OutputStream out, int mode) throws IOException, MimeException {
- if (disposed)
- throw new IllegalStateException("Multipart has been disposed");
-
- Entity e = getParent();
-
- ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
- Field.CONTENT_TYPE);
- if (cField == null || cField.getBoundary() == null) {
- throw new MimeException("Multipart boundary not specified");
- }
- String boundary = cField.getBoundary();
-
- Charset charset = null;
- if (mode == MessageUtils.LENIENT) {
- if (cField != null && cField.getCharset() != null) {
- charset = CharsetUtil.getCharset(cField.getCharset());
- } else {
- charset = MessageUtils.ISO_8859_1;
- }
- } else {
- charset = MessageUtils.DEFAULT_CHARSET;
- }
-
- BufferedWriter writer = new BufferedWriter(
- new OutputStreamWriter(out, charset), 8192);
-
- List bodyParts = getBodyParts();
-
- writer.write(getPreamble());
- writer.write(MessageUtils.CRLF);
-
- for (int i = 0; i < bodyParts.size(); i++) {
- writer.write("--");
- writer.write(boundary);
- writer.write(MessageUtils.CRLF);
- writer.flush();
- final BodyPart bodyPart = (BodyPart) bodyParts.get(i);
- bodyPart.writeTo(out, mode);
- writer.write(MessageUtils.CRLF);
- }
-
- writer.write("--");
- writer.write(boundary);
- writer.write("--");
- writer.write(MessageUtils.CRLF);
- final String epilogue = getEpilogue();
- writer.write(epilogue);
- writer.flush();
- }
-
- /**
- * Disposes the BodyParts of this Multipart. Note that the dispose call does
- * not get forwarded to the parent entity of this Multipart.
- *
- * @see org.apache.james.mime4j.message.Disposable#dispose()
- */
- public void dispose() {
- if (disposed)
- return;
-
- try {
- for (Iterator it = bodyParts.iterator(); it.hasNext();) {
- ((BodyPart) it.next()).dispose();
- }
- } finally {
- disposed = true;
-
- preamble = null;
- epilogue = null;
- bodyParts = null;
- parent = null;
- subType = null;
- }
- }
-
- /**
- * Ensures that the <code>dispose</code> method of this multipart is
- * called when there are no more references to it.
- *
- * Leave them out ATM (https://issues.apache.org/jira/browse/MIME4J-72?focusedCommentId=12636007#action_12636007)
- protected void finalize() throws Throwable {
- dispose();
- }
- */
-}
+/****************************************************************
+ * 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.message;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.field.ContentTypeField;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.util.CharsetUtil;
+import org.apache.james.mime4j.util.MessageUtils;
+
+/**
+ * Represents a MIME multipart body (see RFC 2045).A multipart body has a
+ * ordered list of body parts. The multipart body also has a preamble and
+ * epilogue. The preamble consists of whatever characters appear before the
+ * first body part while the epilogue consists of whatever characters come
+ * after the last body part.
+ *
+ *
+ * @version $Id: Multipart.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public class Multipart implements Body {
+ private String preamble = "";
+ private String epilogue = "";
+ private List bodyParts = new LinkedList();
+ private Entity parent = null;
+ private String subType;
+
+ /**
+ * Creates a new empty <code>Multipart</code> instance.
+ */
+ public Multipart(String subType) {
+ this.subType = subType;
+ }
+
+ /**
+ * Gets the multipart sub-type. E.g. <code>alternative</code> (the default)
+ * or <code>parallel</code>. See RFC 2045 for common sub-types and their
+ * meaning.
+ *
+ * @return the multipart sub-type.
+ */
+ public String getSubType() {
+ return subType;
+ }
+
+ /**
+ * Sets the multipart sub-type. E.g. <code>alternative</code>
+ * or <code>parallel</code>. See RFC 2045 for common sub-types and their
+ * meaning.
+ *
+ * @param subType the sub-type.
+ */
+ public void setSubType(String subType) {
+ this.subType = subType;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#getParent()
+ */
+ public Entity getParent() {
+ return parent;
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#setParent(org.apache.james.mime4j.message.Entity)
+ */
+ public void setParent(Entity parent) {
+ this.parent = parent;
+ for (Iterator it = bodyParts.iterator(); it.hasNext();) {
+ ((BodyPart) it.next()).setParent(parent);
+ }
+ }
+
+ /**
+ * Gets the epilogue.
+ *
+ * @return the epilogue.
+ */
+ public String getEpilogue() {
+ return epilogue;
+ }
+
+ /**
+ * Sets the epilogue.
+ *
+ * @param epilogue the epilogue.
+ */
+ public void setEpilogue(String epilogue) {
+ this.epilogue = epilogue;
+ }
+
+ /**
+ * Gets the list of body parts. The list is immutable.
+ *
+ * @return the list of <code>BodyPart</code> objects.
+ */
+ public List getBodyParts() {
+ return Collections.unmodifiableList(bodyParts);
+ }
+
+ /**
+ * Sets the list of body parts.
+ *
+ * @param bodyParts the new list of <code>BodyPart</code> objects.
+ */
+ public void setBodyParts(List bodyParts) {
+ this.bodyParts = bodyParts;
+ for (Iterator it = bodyParts.iterator(); it.hasNext();) {
+ ((BodyPart) it.next()).setParent(parent);
+ }
+ }
+
+ /**
+ * Adds a body part to the end of the list of body parts.
+ *
+ * @param bodyPart the body part.
+ */
+ public void addBodyPart(BodyPart bodyPart) {
+ bodyParts.add(bodyPart);
+ bodyPart.setParent(parent);
+ }
+
+ /**
+ * Gets the preamble.
+ *
+ * @return the preamble.
+ */
+ public String getPreamble() {
+ return preamble;
+ }
+
+ /**
+ * Sets the preamble.
+ *
+ * @param preamble the preamble.
+ */
+ public void setPreamble(String preamble) {
+ this.preamble = preamble;
+ }
+
+ /**
+ * Write the Multipart to the given OutputStream.
+ *
+ * @param out the OutputStream to write to
+ * @param mode compatibility mode
+ *
+ * @throws IOException if case of an I/O error
+ * @throws MimeException if case of a MIME protocol violation
+ */
+ public void writeTo(final OutputStream out, int mode) throws IOException, MimeException {
+ Entity e = getParent();
+
+ ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
+ Field.CONTENT_TYPE);
+ if (cField == null || cField.getBoundary() == null) {
+ throw new MimeException("Multipart boundary not specified");
+ }
+ String boundary = cField.getBoundary();
+
+ Charset charset = null;
+ if (mode == MessageUtils.LENIENT) {
+ if (cField != null && cField.getCharset() != null) {
+ charset = CharsetUtil.getCharset(cField.getCharset());
+ } else {
+ charset = MessageUtils.ISO_8859_1;
+ }
+ } else {
+ charset = MessageUtils.DEFAULT_CHARSET;
+ }
+
+ BufferedWriter writer = new BufferedWriter(
+ new OutputStreamWriter(out, charset), 8192);
+
+ List bodyParts = getBodyParts();
+
+ writer.write(getPreamble());
+ writer.write(MessageUtils.CRLF);
+
+ for (int i = 0; i < bodyParts.size(); i++) {
+ writer.write("--");
+ writer.write(boundary);
+ writer.write(MessageUtils.CRLF);
+ writer.flush();
+ final BodyPart bodyPart = (BodyPart) bodyParts.get(i);
+ bodyPart.writeTo(out, mode);
+ writer.write(MessageUtils.CRLF);
+ }
+
+ writer.write("--");
+ writer.write(boundary);
+ writer.write("--");
+ writer.write(MessageUtils.CRLF);
+ final String epilogue = getEpilogue();
+ writer.write(epilogue);
+ writer.flush();
+ }
+
+ /**
+ * Disposes the BodyParts of this Multipart. Note that the dispose call does
+ * not get forwarded to the parent entity of this Multipart.
+ *
+ * @see org.apache.james.mime4j.message.Disposable#dispose()
+ */
+ public void dispose() {
+ for (Iterator it = bodyParts.iterator(); it.hasNext();) {
+ ((BodyPart) it.next()).dispose();
+ }
+ }
+
+}
diff --git a/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java b/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java
index c99a552..22febec 100644
--- a/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java
+++ b/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java
@@ -1,90 +1,85 @@
-/****************************************************************
- * 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.message;
-
-import org.apache.james.mime4j.decoder.CodecUtil;
-import org.apache.james.mime4j.message.storage.TempFile;
-import org.apache.james.mime4j.message.storage.TempPath;
-import org.apache.james.mime4j.message.storage.TempStorage;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-
-/**
- * Binary body backed by a {@link org.apache.james.mime4j.message.storage.TempFile}.
- *
- *
- * @version $Id: TempFileBinaryBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
- */
-class TempFileBinaryBody extends AbstractBody implements BinaryBody {
-
- private TempFile tempFile = null;
-
- /**
- * Use the given InputStream to build the TemporyFileBinaryBody
- *
- * @param is the InputStream to use as source
- * @throws IOException
- */
- public TempFileBinaryBody(final InputStream is) throws IOException {
-
- TempPath tempPath = TempStorage.getInstance().getRootTempPath();
- tempFile = tempPath.createTempFile("attachment", ".bin");
-
- OutputStream out = tempFile.getOutputStream();
- CodecUtil.copy(is, out);
- out.close();
- }
-
- /**
- * @see org.apache.james.mime4j.message.BinaryBody#getInputStream()
- */
- public InputStream getInputStream() throws IOException {
- return tempFile.getInputStream();
- }
-
- /**
- * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream, int)
- */
- public void writeTo(OutputStream out, int mode) throws IOException {
- if (disposed)
- throw new IllegalStateException("TempFileBinaryBody has been disposed");
-
- final InputStream inputStream = getInputStream();
- CodecUtil.copy(inputStream,out);
- }
-
- /**
- * Deletes the temporary file that stores the content of this binary body.
- *
- * @see org.apache.james.mime4j.message.Disposable#dispose()
- */
- public void dispose() {
- try {
- tempFile.delete();
- } finally {
- tempFile = null;
-
- super.dispose();
- }
- }
-}
+/****************************************************************
+ * 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.message;
+
+import org.apache.james.mime4j.decoder.CodecUtil;
+import org.apache.james.mime4j.message.storage.TempFile;
+import org.apache.james.mime4j.message.storage.TempPath;
+import org.apache.james.mime4j.message.storage.TempStorage;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+
+/**
+ * Binary body backed by a {@link org.apache.james.mime4j.message.storage.TempFile}.
+ *
+ *
+ * @version $Id: TempFileBinaryBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+class TempFileBinaryBody extends AbstractBody implements BinaryBody {
+
+ private TempFile tempFile = null;
+
+ /**
+ * Use the given InputStream to build the TemporyFileBinaryBody
+ *
+ * @param is the InputStream to use as source
+ * @throws IOException
+ */
+ public TempFileBinaryBody(final InputStream is) throws IOException {
+
+ TempPath tempPath = TempStorage.getInstance().getRootTempPath();
+ tempFile = tempPath.createTempFile("attachment", ".bin");
+
+ OutputStream out = tempFile.getOutputStream();
+ CodecUtil.copy(is, out);
+ out.close();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.BinaryBody#getInputStream()
+ */
+ public InputStream getInputStream() throws IOException {
+ return tempFile.getInputStream();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream, int)
+ */
+ public void writeTo(OutputStream out, int mode) throws IOException {
+ final InputStream inputStream = getInputStream();
+ CodecUtil.copy(inputStream,out);
+ }
+
+ /**
+ * Deletes the temporary file that stores the content of this binary body.
+ *
+ * @see org.apache.james.mime4j.message.Disposable#dispose()
+ */
+ public void dispose() {
+ if (tempFile != null) {
+ tempFile.delete();
+ tempFile = null;
+ }
+ }
+
+}
diff --git a/src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java b/src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java
index a4917de..1ac3d96 100644
--- a/src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java
+++ b/src/main/java/org/apache/james/mime4j/message/TempFileTextBody.java
@@ -1,129 +1,123 @@
-/****************************************************************
- * 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.message;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.james.mime4j.decoder.CodecUtil;
-import org.apache.james.mime4j.message.storage.TempFile;
-import org.apache.james.mime4j.message.storage.TempPath;
-import org.apache.james.mime4j.message.storage.TempStorage;
-import org.apache.james.mime4j.util.CharsetUtil;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-
-
-/**
- * Text body backed by a {@link org.apache.james.mime4j.message.storage.TempFile}.
- *
- *
- * @version $Id: TempFileTextBody.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
- */
-class TempFileTextBody extends AbstractBody implements TextBody {
- private static Log log = LogFactory.getLog(TempFileTextBody.class);
-
- private String mimeCharset = null;
- private TempFile tempFile = null;
-
- public TempFileTextBody(final InputStream is, final String mimeCharset) throws IOException {
-
- this.mimeCharset = mimeCharset;
- TempPath tempPath = TempStorage.getInstance().getRootTempPath();
- tempFile = tempPath.createTempFile("attachment", ".txt");
-
- OutputStream out = tempFile.getOutputStream();
- CodecUtil.copy(is, out);
- out.close();
- }
-
- /**
- * @see org.apache.james.mime4j.message.TextBody#getReader()
- */
- public Reader getReader() throws UnsupportedEncodingException, IOException {
- String javaCharset = null;
- if (mimeCharset != null) {
- javaCharset = CharsetUtil.toJavaCharset(mimeCharset);
- }
-
- if (javaCharset == null) {
- javaCharset = "ISO-8859-1";
-
- if (log.isWarnEnabled()) {
- if (mimeCharset == null) {
- log.warn("No MIME charset specified. Using " + javaCharset
- + " instead.");
- } else {
- log.warn("MIME charset '" + mimeCharset + "' has no "
- + "corresponding Java charset. Using " + javaCharset
- + " instead.");
- }
- }
- }
- /*
- if (log.isWarnEnabled()) {
- if (mimeCharset == null) {
- log.warn("No MIME charset specified. Using the "
- + "platform's default charset.");
- } else {
- log.warn("MIME charset '" + mimeCharset + "' has no "
- + "corresponding Java charset. Using the "
- + "platform's default charset.");
- }
- }
-
- return new InputStreamReader(tempFile.getInputStream());
- }*/
-
- return new InputStreamReader(tempFile.getInputStream(), javaCharset);
- }
-
-
- /**
- * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream, int)
- */
- public void writeTo(OutputStream out, int mode) throws IOException {
- if (disposed)
- throw new IllegalStateException("TempFileTextBody has been disposed");
-
- final InputStream inputStream = tempFile.getInputStream();
- CodecUtil.copy(inputStream, out);
- }
-
- /**
- * Deletes the temporary file that stores the content of this text body.
- *
- * @see org.apache.james.mime4j.message.Disposable#dispose()
- */
- public void dispose() {
- try {
- tempFile.delete();
- } finally {
- mimeCharset = null;
- tempFile = null;
-
- super.dispose();
- }
- }
-}
+/****************************************************************
+ * 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.message;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.decoder.CodecUtil;
+import org.apache.james.mime4j.message.storage.TempFile;
+import org.apache.james.mime4j.message.storage.TempPath;
+import org.apache.james.mime4j.message.storage.TempStorage;
+import org.apache.james.mime4j.util.CharsetUtil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+
+/**
+ * Text body backed by a {@link org.apache.james.mime4j.message.storage.TempFile}.
+ *
+ *
+ * @version $Id: TempFileTextBody.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
+ */
+class TempFileTextBody extends AbstractBody implements TextBody {
+ private static Log log = LogFactory.getLog(TempFileTextBody.class);
+
+ private String mimeCharset = null;
+ private TempFile tempFile = null;
+
+ public TempFileTextBody(final InputStream is, final String mimeCharset) throws IOException {
+
+ this.mimeCharset = mimeCharset;
+ TempPath tempPath = TempStorage.getInstance().getRootTempPath();
+ tempFile = tempPath.createTempFile("attachment", ".txt");
+
+ OutputStream out = tempFile.getOutputStream();
+ CodecUtil.copy(is, out);
+ out.close();
+ }
+
+ /**
+ * @see org.apache.james.mime4j.message.TextBody#getReader()
+ */
+ public Reader getReader() throws UnsupportedEncodingException, IOException {
+ String javaCharset = null;
+ if (mimeCharset != null) {
+ javaCharset = CharsetUtil.toJavaCharset(mimeCharset);
+ }
+
+ if (javaCharset == null) {
+ javaCharset = "ISO-8859-1";
+
+ if (log.isWarnEnabled()) {
+ if (mimeCharset == null) {
+ log.warn("No MIME charset specified. Using " + javaCharset
+ + " instead.");
+ } else {
+ log.warn("MIME charset '" + mimeCharset + "' has no "
+ + "corresponding Java charset. Using " + javaCharset
+ + " instead.");
+ }
+ }
+ }
+ /*
+ if (log.isWarnEnabled()) {
+ if (mimeCharset == null) {
+ log.warn("No MIME charset specified. Using the "
+ + "platform's default charset.");
+ } else {
+ log.warn("MIME charset '" + mimeCharset + "' has no "
+ + "corresponding Java charset. Using the "
+ + "platform's default charset.");
+ }
+ }
+
+ return new InputStreamReader(tempFile.getInputStream());
+ }*/
+
+ return new InputStreamReader(tempFile.getInputStream(), javaCharset);
+ }
+
+
+ /**
+ * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream, int)
+ */
+ public void writeTo(OutputStream out, int mode) throws IOException {
+ final InputStream inputStream = tempFile.getInputStream();
+ CodecUtil.copy(inputStream, out);
+ }
+
+ /**
+ * Deletes the temporary file that stores the content of this text body.
+ *
+ * @see org.apache.james.mime4j.message.Disposable#dispose()
+ */
+ public void dispose() {
+ if (tempFile != null) {
+ tempFile.delete();
+ tempFile = null;
+ }
+ }
+
+}
diff --git a/src/test/java/org/apache/james/mime4j/message/MessageTest.java b/src/test/java/org/apache/james/mime4j/message/MessageTest.java
index eb46c59..47d1c99 100644
--- a/src/test/java/org/apache/james/mime4j/message/MessageTest.java
+++ b/src/test/java/org/apache/james/mime4j/message/MessageTest.java
@@ -1,244 +1,231 @@
-/****************************************************************
- * 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.message;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.field.Field;
-import org.apache.james.mime4j.util.MessageUtils;
-
-/**
- *
- *
- *
- * @version $Id: MessageTest.java,v 1.4 2004/10/02 12:41:11 ntherning Exp $
- */
-public class MessageTest extends TestCase {
- private Header headerTextPlain = null;
- private Header headerMessageRFC822 = null;
- private Header headerEmpty = null;
- private Header headerMultipartMixed = null;
- private Header headerMultipartDigest = null;
-
- public void setUp() throws Exception {
- headerTextPlain = new Header();
- headerMessageRFC822 = new Header();
- headerEmpty = new Header();
- headerMultipartMixed = new Header();
- headerMultipartDigest = new Header();
-
- headerTextPlain.addField(
- Field.parse("Content-Type: text/plain"));
- headerMessageRFC822.addField(
- Field.parse("Content-Type: message/RFC822"));
- headerMultipartMixed.addField(
- Field.parse("Content-Type: multipart/mixed; boundary=foo"));
- headerMultipartDigest.addField(
- Field.parse("Content-Type: multipart/digest; boundary=foo"));
- }
-
- public void testGetParts() {
- }
-
- public void testGetMimeType() {
- Message parent = null;
- Message child = null;
-
- parent = new Message();
- child = new Message();
- child.setParent(parent);
- parent.setHeader(headerMultipartDigest);
- child.setHeader(headerEmpty);
- assertEquals("multipart/digest, empty", "message/rfc822",
- child.getMimeType());
- child.setHeader(headerTextPlain);
- assertEquals("multipart/digest, text/plain", "text/plain",
- child.getMimeType());
- child.setHeader(headerMessageRFC822);
- assertEquals("multipart/digest, message/rfc822", "message/rfc822",
- child.getMimeType());
-
- parent = new Message();
- child = new Message();
- child.setParent(parent);
- parent.setHeader(headerMultipartMixed);
- child.setHeader(headerEmpty);
- assertEquals("multipart/mixed, empty", "text/plain",
- child.getMimeType());
- child.setHeader(headerTextPlain);
- assertEquals("multipart/mixed, text/plain", "text/plain",
- child.getMimeType());
- child.setHeader(headerMessageRFC822);
- assertEquals("multipart/mixed, message/rfc822", "message/rfc822",
- child.getMimeType());
-
- child = new Message();
- child.setHeader(headerEmpty);
- assertEquals("null, empty", "text/plain", child.getMimeType());
- child.setHeader(headerTextPlain);
- assertEquals("null, text/plain", "text/plain", child.getMimeType());
- child.setHeader(headerMessageRFC822);
- assertEquals("null, message/rfc822", "message/rfc822",
- child.getMimeType());
- }
-
- public void testIsMultipart() {
- Message m = new Message();
-
- m.setHeader(headerEmpty);
- assertTrue("empty", !m.isMultipart());
-
- m.setHeader(headerTextPlain);
- assertTrue("text/plain", !m.isMultipart());
-
- m.setHeader(headerMultipartDigest);
- assertTrue("multipart/digest", m.isMultipart());
-
- m.setHeader(headerMultipartMixed);
- assertTrue("multipart/mixed", m.isMultipart());
- }
-
- public void testWriteTo() throws Exception {
- byte[] inputByte = getRawMessageAsByteArray();
-
- Message m = new Message(new ByteArrayInputStream(inputByte));
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- m.writeTo(out, MessageUtils.LENIENT);
-
- InputStream output = new ByteArrayInputStream(out.toByteArray());
-
- int b = -1;
- int i = 0;
- while ((b = output.read()) != -1) {
- assertEquals("same byte", b, inputByte[i]);
- i++;
- }
- }
-
- public void testAddHeaderWriteTo() throws Exception {
- String headerName = "testheader";
- String headerValue = "testvalue";
- String testheader = headerName + ": " + headerValue;
-
- byte[] inputByte = getRawMessageAsByteArray();
-
- Message m = new Message(new ByteArrayInputStream(inputByte));
- m.getHeader().addField(Field.parse(testheader));
-
- assertEquals("header added", m.getHeader().getField(headerName)
- .getBody(), headerValue);
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- m.writeTo(out, MessageUtils.LENIENT);
- List lines = IOUtils.readLines((new BufferedReader(
- new InputStreamReader(new ByteArrayInputStream(out
- .toByteArray())))));
-
- assertTrue("header added", lines.contains(testheader));
- }
-
- public void testDisposeGetsPropagatedToBody() throws Exception {
- DummyBody body1 = new DummyBody();
- BodyPart part1 = new BodyPart();
- part1.setHeader(headerEmpty);
- part1.setBody(body1);
-
- DummyBody body2 = new DummyBody();
- BodyPart part2 = new BodyPart();
- part2.setHeader(headerEmpty);
- part2.setBody(body2);
-
- Multipart mp = new Multipart("mixed");
- mp.addBodyPart(part1);
- mp.addBodyPart(part2);
-
- Message m = new Message();
- m.setHeader(headerMultipartMixed);
- m.setBody(mp);
-
- assertFalse(body1.disposed);
- assertFalse(body2.disposed);
-
- m.dispose();
-
- assertTrue(body1.disposed);
- assertTrue(body2.disposed);
- }
-
- public void testDisposedMessageThrowsException()
- throws Exception {
- byte[] inputByte = getRawMessageAsByteArray();
- Message m = new Message(new ByteArrayInputStream(inputByte));
- m.dispose();
-
- try {
- m.writeTo(new ByteArrayOutputStream(), MessageUtils.LENIENT);
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- private byte[] getRawMessageAsByteArray() {
- StringBuffer header = new StringBuffer();
- StringBuffer body = new StringBuffer();
- StringBuffer complete = new StringBuffer();
-
- header.append("Date: Wed, 21 Feb 2007 11:09:27 +0100\r\n");
- header.append("From: Test <test@test>\r\n");
- header.append("To: Norman Maurer <nm@byteaction.de>\r\n");
- header.append("Subject: Testmail\r\n");
- header
- .append("Content-Type: text/plain; charset=ISO-8859-15; format=flowed\r\n");
- header.append("Content-Transfer-Encoding: 8bit\r\n\r\n");
- body.append("testbody\r\n");
- complete.append(header);
- complete.append(body);
-
- return complete.toString().getBytes();
- }
-
- private static final class DummyBody extends AbstractBody {
-
- public boolean disposed = false;
-
- public void writeTo(OutputStream out, int mode) throws IOException,
- MimeException {
- out.write("dummy".getBytes("US-ASCII"));
- }
-
- public void dispose() {
- disposed = true;
- }
-
- }
-
-}
+/****************************************************************
+ * 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.message;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.util.MessageUtils;
+
+/**
+ *
+ *
+ *
+ * @version $Id: MessageTest.java,v 1.4 2004/10/02 12:41:11 ntherning Exp $
+ */
+public class MessageTest extends TestCase {
+ private Header headerTextPlain = null;
+ private Header headerMessageRFC822 = null;
+ private Header headerEmpty = null;
+ private Header headerMultipartMixed = null;
+ private Header headerMultipartDigest = null;
+
+ public void setUp() throws Exception {
+ headerTextPlain = new Header();
+ headerMessageRFC822 = new Header();
+ headerEmpty = new Header();
+ headerMultipartMixed = new Header();
+ headerMultipartDigest = new Header();
+
+ headerTextPlain.addField(
+ Field.parse("Content-Type: text/plain"));
+ headerMessageRFC822.addField(
+ Field.parse("Content-Type: message/RFC822"));
+ headerMultipartMixed.addField(
+ Field.parse("Content-Type: multipart/mixed; boundary=foo"));
+ headerMultipartDigest.addField(
+ Field.parse("Content-Type: multipart/digest; boundary=foo"));
+ }
+
+ public void testGetParts() {
+ }
+
+ public void testGetMimeType() {
+ Message parent = null;
+ Message child = null;
+
+ parent = new Message();
+ child = new Message();
+ child.setParent(parent);
+ parent.setHeader(headerMultipartDigest);
+ child.setHeader(headerEmpty);
+ assertEquals("multipart/digest, empty", "message/rfc822",
+ child.getMimeType());
+ child.setHeader(headerTextPlain);
+ assertEquals("multipart/digest, text/plain", "text/plain",
+ child.getMimeType());
+ child.setHeader(headerMessageRFC822);
+ assertEquals("multipart/digest, message/rfc822", "message/rfc822",
+ child.getMimeType());
+
+ parent = new Message();
+ child = new Message();
+ child.setParent(parent);
+ parent.setHeader(headerMultipartMixed);
+ child.setHeader(headerEmpty);
+ assertEquals("multipart/mixed, empty", "text/plain",
+ child.getMimeType());
+ child.setHeader(headerTextPlain);
+ assertEquals("multipart/mixed, text/plain", "text/plain",
+ child.getMimeType());
+ child.setHeader(headerMessageRFC822);
+ assertEquals("multipart/mixed, message/rfc822", "message/rfc822",
+ child.getMimeType());
+
+ child = new Message();
+ child.setHeader(headerEmpty);
+ assertEquals("null, empty", "text/plain", child.getMimeType());
+ child.setHeader(headerTextPlain);
+ assertEquals("null, text/plain", "text/plain", child.getMimeType());
+ child.setHeader(headerMessageRFC822);
+ assertEquals("null, message/rfc822", "message/rfc822",
+ child.getMimeType());
+ }
+
+ public void testIsMultipart() {
+ Message m = new Message();
+
+ m.setHeader(headerEmpty);
+ assertTrue("empty", !m.isMultipart());
+
+ m.setHeader(headerTextPlain);
+ assertTrue("text/plain", !m.isMultipart());
+
+ m.setHeader(headerMultipartDigest);
+ assertTrue("multipart/digest", m.isMultipart());
+
+ m.setHeader(headerMultipartMixed);
+ assertTrue("multipart/mixed", m.isMultipart());
+ }
+
+ public void testWriteTo() throws Exception {
+ byte[] inputByte = getRawMessageAsByteArray();
+
+ Message m = new Message(new ByteArrayInputStream(inputByte));
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ m.writeTo(out, MessageUtils.LENIENT);
+
+ InputStream output = new ByteArrayInputStream(out.toByteArray());
+
+ int b = -1;
+ int i = 0;
+ while ((b = output.read()) != -1) {
+ assertEquals("same byte", b, inputByte[i]);
+ i++;
+ }
+ }
+
+ public void testAddHeaderWriteTo() throws Exception {
+ String headerName = "testheader";
+ String headerValue = "testvalue";
+ String testheader = headerName + ": " + headerValue;
+
+ byte[] inputByte = getRawMessageAsByteArray();
+
+ Message m = new Message(new ByteArrayInputStream(inputByte));
+ m.getHeader().addField(Field.parse(testheader));
+
+ assertEquals("header added", m.getHeader().getField(headerName)
+ .getBody(), headerValue);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ m.writeTo(out, MessageUtils.LENIENT);
+ List lines = IOUtils.readLines((new BufferedReader(
+ new InputStreamReader(new ByteArrayInputStream(out
+ .toByteArray())))));
+
+ assertTrue("header added", lines.contains(testheader));
+ }
+
+ public void testDisposeGetsPropagatedToBody() throws Exception {
+ DummyBody body1 = new DummyBody();
+ BodyPart part1 = new BodyPart();
+ part1.setHeader(headerEmpty);
+ part1.setBody(body1);
+
+ DummyBody body2 = new DummyBody();
+ BodyPart part2 = new BodyPart();
+ part2.setHeader(headerEmpty);
+ part2.setBody(body2);
+
+ Multipart mp = new Multipart("mixed");
+ mp.addBodyPart(part1);
+ mp.addBodyPart(part2);
+
+ Message m = new Message();
+ m.setHeader(headerMultipartMixed);
+ m.setBody(mp);
+
+ assertFalse(body1.disposed);
+ assertFalse(body2.disposed);
+
+ m.dispose();
+
+ assertTrue(body1.disposed);
+ assertTrue(body2.disposed);
+ }
+
+ private byte[] getRawMessageAsByteArray() {
+ StringBuffer header = new StringBuffer();
+ StringBuffer body = new StringBuffer();
+ StringBuffer complete = new StringBuffer();
+
+ header.append("Date: Wed, 21 Feb 2007 11:09:27 +0100\r\n");
+ header.append("From: Test <test@test>\r\n");
+ header.append("To: Norman Maurer <nm@byteaction.de>\r\n");
+ header.append("Subject: Testmail\r\n");
+ header
+ .append("Content-Type: text/plain; charset=ISO-8859-15; format=flowed\r\n");
+ header.append("Content-Transfer-Encoding: 8bit\r\n\r\n");
+ body.append("testbody\r\n");
+ complete.append(header);
+ complete.append(body);
+
+ return complete.toString().getBytes();
+ }
+
+ private static final class DummyBody extends AbstractBody {
+
+ public boolean disposed = false;
+
+ public void writeTo(OutputStream out, int mode) throws IOException,
+ MimeException {
+ out.write("dummy".getBytes("US-ASCII"));
+ }
+
+ public void dispose() {
+ disposed = true;
+ }
+
+ }
+
+}