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 ba...@apache.org on 2007/04/27 00:56:18 UTC

svn commit: r532898 [3/6] - in /james/mime4j/trunk: ./ examples/src/java/org/apache/ examples/src/java/org/apache/james/ examples/src/java/org/apache/james/mime4j/ examples/src/java/org/apache/james/mime4j/samples/ examples/src/java/org/apache/james/mi...

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/UnstructuredField.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/UnstructuredField.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/UnstructuredField.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/UnstructuredField.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,49 @@
+/****************************************************************
+ * 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.field;
+
+import org.apache.james.mime4j.decoder.DecoderUtil;
+
+
+/**
+ * Simple unstructured field such as <code>Subject</code>.
+ *
+ * 
+ * @version $Id: UnstructuredField.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
+ */
+public class UnstructuredField extends Field {
+    private String value;
+    
+    protected UnstructuredField(String name, String body, String raw, String value) {
+        super(name, body, raw);
+        this.value = value;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public static class Parser implements FieldParser {
+        public Field parse(final String name, final String body, final String raw) {
+            final String value = DecoderUtil.decodeEncodedWords(body);
+            return new UnstructuredField(name, body, raw, value);
+        }
+    }
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Address.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Address.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Address.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Address.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,52 @@
+/****************************************************************
+ * 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.field.address;
+
+import java.util.ArrayList;
+
+/**
+ * The abstract base for classes that represent RFC2822 addresses.
+ * This includes groups and mailboxes.
+ * 
+ * Currently, no public methods are introduced on this class.
+ * 
+ * 
+ */
+public abstract class Address {
+
+	/**
+	 * Adds any mailboxes represented by this address
+	 * into the given ArrayList. Note that this method
+	 * has default (package) access, so a doAddMailboxesTo
+	 * method is needed to allow the behavior to be
+	 * overridden by subclasses.
+	 */
+	final void addMailboxesTo(ArrayList results) {
+		doAddMailboxesTo(results);
+	}
+	
+	/**
+	 * Adds any mailboxes represented by this address
+	 * into the given ArrayList. Must be overridden by
+	 * concrete subclasses.
+	 */
+	protected abstract void doAddMailboxesTo(ArrayList results);
+
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/AddressList.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/AddressList.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/AddressList.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/AddressList.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,150 @@
+/****************************************************************
+ * 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.field.address;
+
+import org.apache.james.mime4j.field.address.parser.AddressListParser;
+import org.apache.james.mime4j.field.address.parser.ParseException;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * An immutable, random-access list of Address objects.
+ *
+ * 
+ */
+public class AddressList {
+	
+	private ArrayList addresses;
+
+	/**
+	 * @param addresses An ArrayList that contains only Address objects. 
+	 * @param dontCopy true iff it is not possible for the addresses ArrayList to be modified by someone else.
+	 */
+	public AddressList(ArrayList addresses, boolean dontCopy) {
+		if (addresses != null)
+			this.addresses = (dontCopy ? addresses : (ArrayList) addresses.clone());
+		else
+			this.addresses = new ArrayList(0);
+	}
+
+    public Iterator iterator() {
+        return new Iterator() {
+            private int pos = 0;
+            public void remove() { throw new UnsupportedOperationException(); }
+            public boolean hasNext() { return pos < size(); }
+            public Object next() { return get(pos++); }
+        };
+    }
+
+	/**
+	 * The number of elements in this list.
+	 */
+	public int size() {
+		return addresses.size();
+	}
+
+	/**
+	 * Gets an address. 
+	 */
+	public Address get(int index) {
+		if (0 > index || size() <= index)
+			throw new IndexOutOfBoundsException();
+		return (Address) addresses.get(index);
+	}
+
+	/**
+	 * Returns a flat list of all mailboxes represented
+	 * in this address list. Use this if you don't care
+	 * about grouping. 
+	 */
+	public MailboxList flatten() {
+		// in the common case, all addresses are mailboxes
+		boolean groupDetected = false;
+		for (int i = 0; i < size(); i++) {
+			if (!(get(i) instanceof Mailbox)) {
+				groupDetected = true;
+				break;
+			}
+		}
+		
+		if (!groupDetected)
+			return new MailboxList(addresses, true);
+		
+		ArrayList results = new ArrayList();
+		for (int i = 0; i < size(); i++) {
+			Address addr = get(i);
+			addr.addMailboxesTo(results);
+		}
+		
+		// copy-on-construct this time, because subclasses
+		// could have held onto a reference to the results
+		return new MailboxList(results, false);
+	}
+	
+	/**
+	 * Dumps a representation of this address list to
+	 * stdout, for debugging purposes.
+	 */
+	public void print() {
+		for (int i = 0; i < size(); i++) {
+			Address addr = get(i);
+			System.out.println(addr.toString());
+		}
+	}
+
+
+
+	/**
+	 * Parse the address list string, such as the value 
+	 * of a From, To, Cc, Bcc, Sender, or Reply-To
+	 * header.
+	 * 
+	 * The string MUST be unfolded already.
+	 */
+	public static AddressList parse(String rawAddressList) throws ParseException {
+		AddressListParser parser = new AddressListParser(new StringReader(rawAddressList));
+		return Builder.getInstance().buildAddressList(parser.parse());
+	}
+	
+	/**
+	 * Test console.
+	 */
+	public static void main(String[] args) throws Exception {
+		java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
+		while (true) {
+			try {
+				System.out.print("> ");
+				String line = reader.readLine();
+				if (line.length() == 0 || line.toLowerCase().equals("exit") || line.toLowerCase().equals("quit")) {
+					System.out.println("Goodbye.");
+					return;
+				}
+				AddressList list = parse(line);
+				list.print();
+			}
+			catch(Exception e) {
+				e.printStackTrace();
+				Thread.sleep(300);
+			}
+		}
+	}
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Builder.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Builder.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Builder.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Builder.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,244 @@
+/****************************************************************
+ * 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.field.address;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.james.mime4j.decoder.DecoderUtil;
+import org.apache.james.mime4j.field.address.parser.*;
+import org.apache.james.mime4j.field.address.parser.ASTaddr_spec;
+import org.apache.james.mime4j.field.address.parser.ASTaddress;
+import org.apache.james.mime4j.field.address.parser.ASTaddress_list;
+import org.apache.james.mime4j.field.address.parser.ASTangle_addr;
+import org.apache.james.mime4j.field.address.parser.ASTdomain;
+import org.apache.james.mime4j.field.address.parser.ASTgroup_body;
+import org.apache.james.mime4j.field.address.parser.ASTlocal_part;
+import org.apache.james.mime4j.field.address.parser.ASTmailbox;
+import org.apache.james.mime4j.field.address.parser.ASTname_addr;
+import org.apache.james.mime4j.field.address.parser.ASTphrase;
+import org.apache.james.mime4j.field.address.parser.ASTroute;
+import org.apache.james.mime4j.field.address.parser.Node;
+import org.apache.james.mime4j.field.address.parser.SimpleNode;
+import org.apache.james.mime4j.field.address.parser.Token;
+
+/**
+ * Transforms the JJTree-generated abstract syntax tree
+ * into a graph of org.apache.james.mime4j.field.address objects.
+ *
+ * 
+ */
+class Builder {
+
+	private static Builder singleton = new Builder();
+	
+	public static Builder getInstance() {
+		return singleton;
+	}
+	
+	
+	
+	public AddressList buildAddressList(ASTaddress_list node) {
+		ArrayList list = new ArrayList();
+		for (int i = 0; i < node.jjtGetNumChildren(); i++) {
+			ASTaddress childNode = (ASTaddress) node.jjtGetChild(i);
+			Address address = buildAddress(childNode);
+			list.add(address);
+		}
+		return new AddressList(list, true);
+	}
+
+	private Address buildAddress(ASTaddress node) {
+		ChildNodeIterator it = new ChildNodeIterator(node);
+		Node n = it.nextNode();
+		if (n instanceof ASTaddr_spec) {
+			return buildAddrSpec((ASTaddr_spec)n);
+		}
+		else if (n instanceof ASTangle_addr) {
+			return buildAngleAddr((ASTangle_addr)n);
+		}
+		else if (n instanceof ASTphrase) {
+			String name = buildString((ASTphrase)n, false);
+			Node n2 = it.nextNode();
+			if (n2 instanceof ASTgroup_body) {
+				return new Group(name, buildGroupBody((ASTgroup_body)n2));
+			}
+			else if (n2 instanceof ASTangle_addr) {
+                name = DecoderUtil.decodeEncodedWords(name);
+				return new NamedMailbox(name, buildAngleAddr((ASTangle_addr)n2));
+			}
+			else {
+				throw new IllegalStateException();
+			}
+		}
+		else {
+			throw new IllegalStateException();
+		}
+	}
+	
+	
+	
+	private MailboxList buildGroupBody(ASTgroup_body node) {
+		ArrayList results = new ArrayList();
+		ChildNodeIterator it = new ChildNodeIterator(node);
+		while (it.hasNext()) {
+			Node n = it.nextNode();
+			if (n instanceof ASTmailbox)
+				results.add(buildMailbox((ASTmailbox)n));
+			else
+				throw new IllegalStateException();
+		}
+		return new MailboxList(results, true);
+	}
+
+	private Mailbox buildMailbox(ASTmailbox node) {
+		ChildNodeIterator it = new ChildNodeIterator(node);
+		Node n = it.nextNode();
+		if (n instanceof ASTaddr_spec) {
+			return buildAddrSpec((ASTaddr_spec)n);
+		}
+		else if (n instanceof ASTangle_addr) {
+			return buildAngleAddr((ASTangle_addr)n);
+		}
+		else if (n instanceof ASTname_addr) {
+			return buildNameAddr((ASTname_addr)n);
+		}
+		else {
+			throw new IllegalStateException();
+		}
+	}
+
+	private NamedMailbox buildNameAddr(ASTname_addr node) {
+		ChildNodeIterator it = new ChildNodeIterator(node);
+		Node n = it.nextNode();
+		String name;
+		if (n instanceof ASTphrase) {
+			name = buildString((ASTphrase)n, false);
+		}
+		else {
+			throw new IllegalStateException();
+		}
+		
+		n = it.nextNode();
+		if (n instanceof ASTangle_addr) {
+            name = DecoderUtil.decodeEncodedWords(name);
+			return new NamedMailbox(name, buildAngleAddr((ASTangle_addr) n));
+		}
+		else {
+			throw new IllegalStateException();
+		}
+	}
+	
+	private Mailbox buildAngleAddr(ASTangle_addr node) {
+		ChildNodeIterator it = new ChildNodeIterator(node);
+		DomainList route = null;
+		Node n = it.nextNode();
+		if (n instanceof ASTroute) {
+			route = buildRoute((ASTroute)n);
+			n = it.nextNode();
+		}
+		else if (n instanceof ASTaddr_spec)
+			; // do nothing
+		else
+			throw new IllegalStateException();
+		
+		if (n instanceof ASTaddr_spec)
+			return buildAddrSpec(route, (ASTaddr_spec)n);
+		else
+			throw new IllegalStateException();
+	}
+
+	private DomainList buildRoute(ASTroute node) {
+		ArrayList results = new ArrayList(node.jjtGetNumChildren());
+		ChildNodeIterator it = new ChildNodeIterator(node);
+		while (it.hasNext()) {
+			Node n = it.nextNode();
+			if (n instanceof ASTdomain)
+				results.add(buildString((ASTdomain)n, true));
+			else
+				throw new IllegalStateException();
+		}
+		return new DomainList(results, true);
+	}
+
+	private Mailbox buildAddrSpec(ASTaddr_spec node) {
+		return buildAddrSpec(null, node);
+	}
+	private Mailbox buildAddrSpec(DomainList route, ASTaddr_spec node) {
+		ChildNodeIterator it = new ChildNodeIterator(node);
+		String localPart = buildString((ASTlocal_part)it.nextNode(), true);
+		String domain = buildString((ASTdomain)it.nextNode(), true);
+		return new Mailbox(route, localPart, domain);		
+	}
+
+
+	private String buildString(SimpleNode node, boolean stripSpaces) {
+		Token head = node.firstToken;
+		Token tail = node.lastToken;
+		StringBuffer out = new StringBuffer();
+		
+		while (head != tail) {
+			out.append(head.image);
+			head = head.next;
+			if (!stripSpaces)
+				addSpecials(out, head.specialToken);
+		}
+		out.append(tail.image);			
+		
+		return out.toString();
+	}
+
+	private void addSpecials(StringBuffer out, Token specialToken) {
+		if (specialToken != null) {
+			addSpecials(out, specialToken.specialToken);
+			out.append(specialToken.image);
+		}
+	}
+
+	private static class ChildNodeIterator implements Iterator {
+
+		private SimpleNode simpleNode;
+		private int index;
+		private int len;
+		
+		public ChildNodeIterator(SimpleNode simpleNode) {
+			this.simpleNode = simpleNode;
+			this.len = simpleNode.jjtGetNumChildren();
+			this.index = 0;
+		}
+		
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
+
+		public boolean hasNext() {
+			return index < len;
+		}
+
+		public Object next() {
+			return nextNode();
+		}
+		
+		public Node nextNode() {
+			return simpleNode.jjtGetChild(index++);
+		}
+		
+	}
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/DomainList.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/DomainList.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/DomainList.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/DomainList.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,76 @@
+/****************************************************************
+ * 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.field.address;
+
+import java.util.ArrayList;
+
+/**
+ * An immutable, random-access list of Strings (that 
+ * are supposedly domain names or domain literals).
+ *
+ * 
+ */
+public class DomainList {
+	private ArrayList domains;
+	
+	/**
+	 * @param domains An ArrayList that contains only String objects. 
+	 * @param dontCopy true iff it is not possible for the domains ArrayList to be modified by someone else.
+	 */
+	public DomainList(ArrayList domains, boolean dontCopy) {
+		if (domains != null)
+			this.domains = (dontCopy ? domains : (ArrayList) domains.clone());
+		else
+			this.domains = new ArrayList(0);
+	}
+	
+	/**
+	 * The number of elements in this list.
+	 */
+	public int size() {
+		return domains.size();
+	}
+
+	/**
+	 * Gets the domain name or domain literal at the
+	 * specified index.
+	 * @throws IndexOutOfBoundsException If index is &lt; 0 or &gt;= size().
+	 */
+	public String get(int index) {
+		if (0 > index || size() <= index)
+			throw new IndexOutOfBoundsException();
+		return (String) domains.get(index);
+	}
+
+	/**
+	 * Returns the list of domains formatted as a route
+	 * string (not including the trailing ':'). 
+	 */
+	public String toRouteString() {
+		StringBuffer out = new StringBuffer();
+		for (int i = 0; i < domains.size(); i++) {
+			out.append("@");
+			out.append(get(i));
+			if (i + 1 < domains.size())
+				out.append(",");
+		}
+		return out.toString();
+	}
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Group.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Group.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Group.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Group.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,73 @@
+/****************************************************************
+ * 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.field.address;
+
+import java.util.ArrayList;
+
+/**
+ * A named group of zero or more mailboxes.  
+ *
+ * 
+ */
+public class Group extends Address {
+	private String name;
+	private MailboxList mailboxList;
+	
+	/**
+	 * @param name The group name.
+	 * @param mailboxes The mailboxes in this group.
+	 */
+	public Group(String name, MailboxList mailboxes) {
+		this.name = name;
+		this.mailboxList = mailboxes;
+	}
+
+	/**
+	 * Returns the group name.
+	 */
+	public String getName() {
+		return name;
+	}
+	
+	/**
+	 * Returns the mailboxes in this group.
+	 */
+	public MailboxList getMailboxes() {
+		return mailboxList;
+	}
+	
+	public String toString() {
+		StringBuffer buf = new StringBuffer();
+		buf.append(name);
+		buf.append(":");
+		for (int i = 0; i < mailboxList.size(); i++) {
+			buf.append(mailboxList.get(i).toString());
+			if (i + 1 < mailboxList.size())
+				buf.append(",");
+		}
+		buf.append(";");
+		return buf.toString();
+	}
+
+	protected void doAddMailboxesTo(ArrayList results) {
+		for (int i = 0; i < mailboxList.size(); i++)
+			results.add(mailboxList.get(i));
+	}
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Mailbox.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Mailbox.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Mailbox.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/Mailbox.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,119 @@
+/****************************************************************
+ * 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.field.address;
+
+import java.util.ArrayList;
+
+/**
+ * Represents a single e-mail address. 
+ *
+ * 
+ */
+public class Mailbox extends Address {
+	private DomainList route;
+	private String localPart;
+	private String domain;
+
+	/**
+	 * Creates a mailbox without a route. Routes are obsolete.
+	 * @param localPart The part of the e-mail address to the left of the "@".
+	 * @param domain The part of the e-mail address to the right of the "@".
+	 */
+	public Mailbox(String localPart, String domain) {
+		this(null, localPart, domain);
+	}
+	
+	/**
+	 * Creates a mailbox with a route. Routes are obsolete.
+	 * @param route The zero or more domains that make up the route. Can be null.
+	 * @param localPart The part of the e-mail address to the left of the "@".
+	 * @param domain The part of the e-mail address to the right of the "@".
+	 */
+	public Mailbox(DomainList route, String localPart, String domain) {
+		this.route = route;
+		this.localPart = localPart;
+		this.domain = domain;
+	}
+
+	/**
+	 * Returns the route list.
+	 */
+	public DomainList getRoute() {
+		return route;
+	}
+
+	/**
+	 * Returns the left part of the e-mail address 
+	 * (before "@").
+	 */
+	public String getLocalPart() {
+		return localPart;
+	}
+	
+	/**
+	 * Returns the right part of the e-mail address 
+	 * (after "@").
+	 */
+	public String getDomain() {
+		return domain;
+	}
+
+	/**
+	 * Formats the address as a string, not including
+	 * the route.
+	 * 
+	 * @see #getAddressString(boolean)
+	 */
+	public String getAddressString() {
+		return getAddressString(false);
+	}
+	
+	/**
+	 * Note that this value may not be usable
+	 * for transport purposes, only display purposes.
+	 * 
+	 * For example, if the unparsed address was
+	 * 
+	 *   <"Joe Cheng"@joecheng.com>
+	 * 
+	 * this method would return
+	 * 
+	 *   <Joe Cheng@joecheng.com>
+	 * 
+	 * which is not valid for transport; the local part
+	 * would need to be re-quoted.
+	 * 
+	 * @param includeRoute true if the route should be included if it exists. 
+	 */
+	public String getAddressString(boolean includeRoute) {
+		return "<" + (!includeRoute || route == null ? "" : route.toRouteString() + ":") 
+			+ localPart
+			+ (domain == null ? "" : "@") 
+			+ domain + ">";  
+	}
+	
+	protected final void doAddMailboxesTo(ArrayList results) {
+		results.add(this);
+	}
+	
+	public String toString() {
+		return getAddressString();
+	}
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/MailboxList.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/MailboxList.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/MailboxList.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/MailboxList.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,71 @@
+/****************************************************************
+ * 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.field.address;
+
+import java.util.ArrayList;
+
+/**
+ * An immutable, random-access list of Mailbox objects.
+ *
+ * 
+ */
+public class MailboxList {
+
+	private ArrayList mailboxes;
+	
+	/**
+	 * @param mailboxes An ArrayList that contains only Mailbox objects. 
+	 * @param dontCopy true iff it is not possible for the mailboxes ArrayList to be modified by someone else.
+	 */
+	public MailboxList(ArrayList mailboxes, boolean dontCopy) {
+		if (mailboxes != null)
+			this.mailboxes = (dontCopy ? mailboxes : (ArrayList) mailboxes.clone());
+		else
+			mailboxes = new ArrayList(0);
+	}
+	
+	/**
+	 * The number of elements in this list.
+	 */
+	public int size() {
+		return mailboxes.size();
+	}
+	
+	/**
+	 * Gets an address. 
+	 */
+	public Mailbox get(int index) {
+		if (0 > index || size() <= index)
+			throw new IndexOutOfBoundsException();
+		return (Mailbox) mailboxes.get(index);
+	}
+	
+	/**
+	 * Dumps a representation of this mailbox list to
+	 * stdout, for debugging purposes.
+	 */
+	public void print() {
+		for (int i = 0; i < size(); i++) {
+			Mailbox mailbox = get(i);
+			System.out.println(mailbox.toString());
+		}
+	}
+
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/NamedMailbox.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/NamedMailbox.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/NamedMailbox.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/NamedMailbox.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,70 @@
+/****************************************************************
+ * 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.field.address;
+
+/**
+ * A Mailbox that has a name/description.
+ *
+ * 
+ */
+public class NamedMailbox extends Mailbox {
+	private String name;
+
+	/**
+	 * @see Mailbox#Mailbox(String, String)
+	 */
+	public NamedMailbox(String name, String localPart, String domain) {
+		super(localPart, domain);
+		this.name = name;
+	}
+
+	/**
+	 * @see Mailbox#Mailbox(DomainList, String, String)
+	 */
+	public NamedMailbox(String name, DomainList route, String localPart, String domain) {
+		super(route, localPart, domain);
+		this.name = name;
+	}
+	
+	/**
+	 * Creates a named mailbox based on an unnamed mailbox. 
+	 */
+	public NamedMailbox(String name, Mailbox baseMailbox) {
+		super(baseMailbox.getRoute(), baseMailbox.getLocalPart(), baseMailbox.getDomain());
+		this.name = name;
+	}
+
+	/**
+	 * Returns the name of the mailbox. 
+	 */
+	public String getName() {
+		return this.name;
+	}
+	
+	/**
+	 * Same features (or problems) as Mailbox.getAddressString(boolean),
+	 * only more so.
+	 * 
+	 * @see Mailbox#getAddressString(boolean) 
+	 */
+	public String getAddressString(boolean includeRoute) {
+		return (name == null ? "" : name + " ") + super.getAddressString(includeRoute);
+	}
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/parser/BaseNode.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/parser/BaseNode.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/parser/BaseNode.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/address/parser/BaseNode.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,30 @@
+/****************************************************************
+ * 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.field.address.parser;
+
+import org.apache.james.mime4j.field.address.parser.Node;
+import org.apache.james.mime4j.field.address.parser.Token;
+
+public abstract class BaseNode implements Node {
+  
+  public Token firstToken;
+  public Token lastToken;
+
+}
\ No newline at end of file

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/datetime/DateTime.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/datetime/DateTime.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/datetime/DateTime.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/datetime/DateTime.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,127 @@
+/****************************************************************
+ * 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.field.datetime;
+
+import org.apache.james.mime4j.field.datetime.parser.DateTimeParser;
+import org.apache.james.mime4j.field.datetime.parser.ParseException;
+import org.apache.james.mime4j.field.datetime.parser.TokenMgrError;
+
+import java.util.Date;
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.GregorianCalendar;
+import java.io.StringReader;
+
+public class DateTime {
+    private final Date date;
+    private final int year;
+    private final int month;
+    private final int day;
+    private final int hour;
+    private final int minute;
+    private final int second;
+    private final int timeZone;
+
+    public DateTime(String yearString, int month, int day, int hour, int minute, int second, int timeZone) {
+        this.year = convertToYear(yearString);
+        this.date = convertToDate(year, month, day, hour, minute, second, timeZone);
+        this.month = month;
+        this.day = day;
+        this.hour = hour;
+        this.minute = minute;
+        this.second = second;
+        this.timeZone = timeZone;
+    }
+
+    private int convertToYear(String yearString) {
+        int year = Integer.parseInt(yearString);
+        switch (yearString.length()) {
+            case 1:
+            case 2:
+                if (year >= 0 && year < 50)
+                    return 2000 + year;
+                else
+                    return 1900 + year;
+            case 3:
+                return 1900 + year;
+            default:
+                return year;
+        }
+    }
+
+    public static Date convertToDate(int year, int month, int day, int hour, int minute, int second, int timeZone) {
+        Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT+0"));
+        c.set(year, month - 1, day, hour, minute, second);
+        c.set(Calendar.MILLISECOND, 0);
+
+        if (timeZone != Integer.MIN_VALUE) {
+            int minutes = ((timeZone / 100) * 60) + timeZone % 100;
+            c.add(Calendar.MINUTE, -1 * minutes);
+        }
+
+        return c.getTime();
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public int getYear() {
+        return year;
+    }
+
+    public int getMonth() {
+        return month;
+    }
+
+    public int getDay() {
+        return day;
+    }
+
+    public int getHour() {
+        return hour;
+    }
+
+    public int getMinute() {
+        return minute;
+    }
+
+    public int getSecond() {
+        return second;
+    }
+
+    public int getTimeZone() {
+        return timeZone;
+    }
+
+    public void print() {
+        System.out.println(getYear() + " " + getMonth() + " " + getDay() + "; " + getHour() + " " + getMinute() + " " + getSecond() + " " + getTimeZone());
+    }
+
+
+    public static DateTime parse(String dateString) throws ParseException {
+        try {
+            return new DateTimeParser(new StringReader(dateString)).parseAll();
+        }
+        catch (TokenMgrError err) {
+            throw new ParseException(err.getMessage());
+        }
+    }
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/AbstractBody.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/AbstractBody.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/AbstractBody.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/AbstractBody.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,47 @@
+/****************************************************************
+ * 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;
+    }
+
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BinaryBody.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BinaryBody.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BinaryBody.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BinaryBody.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.IOException;
+import java.io.InputStream;
+
+
+/**
+ * Interface implemented by bodies containing binary data.
+ *
+ * 
+ * @version $Id: BinaryBody.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public interface BinaryBody extends Body {
+    
+    /**
+     * Gets a <code>InputStream</code> which reads the bytes of the
+     * body.
+     * 
+     * @return the stream.
+     * @throws IOException on I/O errors.
+     */
+    InputStream getInputStream() throws IOException;
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Body.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Body.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Body.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Body.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,54 @@
+/****************************************************************
+ * 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.IOException;
+import java.io.OutputStream;
+
+/**
+ * Encapsulates the body of an entity (see RFC 2045).
+ *
+ * 
+ * @version $Id: Body.java,v 1.4 2004/10/04 15:36:43 ntherning Exp $
+ */
+public interface Body {
+
+    /**
+     * Gets the parent of this body.
+     * 
+     * @return the parent.
+     */
+    Entity getParent();
+    
+    /**
+     * Sets the parent of this body.
+     * 
+     * @param parent the parent.
+     */
+    void setParent(Entity parent);
+    
+    /**
+     * Writes this body to the given stream in MIME message format.
+     * 
+     * @param out the stream to write to.
+     * @throws IOException on I/O errors.
+     */
+    void writeTo(OutputStream out) throws IOException;
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BodyPart.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BodyPart.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BodyPart.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BodyPart.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,42 @@
+/****************************************************************
+ * 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.IOException;
+import java.io.OutputStream;
+
+
+/**
+ * Represents a MIME body part  (see RFC 2045).
+ *
+ * 
+ * @version $Id: BodyPart.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public class BodyPart extends Entity {
+
+    /**
+     * 
+     * @see org.apache.james.mime4j.message.Entity#writeTo(java.io.OutputStream)
+     */
+    public void writeTo(OutputStream out) throws IOException {
+        getHeader().writeTo(out);
+        getBody().writeTo(out);
+    }
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Entity.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Entity.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Entity.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Entity.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,170 @@
+/****************************************************************
+ * 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.IOException;
+import java.io.OutputStream;
+
+import org.apache.james.mime4j.field.ContentTransferEncodingField;
+import org.apache.james.mime4j.field.ContentTypeField;
+import org.apache.james.mime4j.field.Field;
+
+/**
+ * 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 {
+    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
+     * @throws IOException 
+     */
+    public abstract void writeTo(OutputStream out) throws IOException;
+}

Added: 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=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Header.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,156 @@
+/****************************************************************
+ * 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.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.james.mime4j.AbstractContentHandler;
+import org.apache.james.mime4j.MimeStreamParser;
+import org.apache.james.mime4j.field.ContentTypeField;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.util.CharsetUtil;
+
+
+/**
+ * The header of an entity (see RFC 2045).
+ *
+ * 
+ * @version $Id: Header.java,v 1.3 2004/10/04 15:36:44 ntherning Exp $
+ */
+public class Header {
+    private List fields = new LinkedList();
+    private HashMap fieldMap = new HashMap();
+    
+    /**
+     * Creates a new empty <code>Header</code>.
+     */
+    public Header() {
+    }
+
+    /**
+     * Creates a new <code>Header</code> from the specified stream.
+     * 
+     * @param is the stream to read the header from.
+     */
+    public Header(InputStream is) throws IOException {
+        final MimeStreamParser parser = new MimeStreamParser();
+        parser.setContentHandler(new AbstractContentHandler() {
+            public void endHeader() {
+                parser.stop();
+            }
+            public void field(String fieldData) {
+                addField(Field.parse(fieldData));
+            }
+        });
+        parser.parse(is);
+    }
+
+    /**
+     * Adds a field to the end of the list of fields.
+     * 
+     * @param field the field to add.
+     */
+    public void addField(Field field) {
+        List values = (List) fieldMap.get(field.getName().toLowerCase());
+        if (values == null) {
+            values = new LinkedList();
+            fieldMap.put(field.getName().toLowerCase(), values);
+        }
+        values.add(field);
+        fields.add(field);
+    }
+    
+    /**
+     * Gets the fields of this header. The returned list will not be
+     * modifiable.
+     * 
+     * @return the list of <code>Field</code> objects.
+     */
+    public List getFields() {
+        return Collections.unmodifiableList(fields);
+    }
+
+    /**
+     * Gets a <code>Field</code> given a field name. If there are multiple
+     * such fields defined in this header the first one will be returned.
+     * 
+     * @param name the field name (e.g. From, Subject).
+     * @return the field or <code>null</code> if none found.
+     */
+    public Field getField(String name) {
+        List l = (List) fieldMap.get(name.toLowerCase());
+        if (l != null && !l.isEmpty()) {
+            return (Field) l.get(0);
+        }
+        return null;
+    }
+    
+    /**
+     * Gets all <code>Field</code>s having the specified field name. 
+     * 
+     * @param name the field name (e.g. From, Subject).
+     * @return the list of fields.
+     */
+    public List getFields(String name) {
+        List l = (List) fieldMap.get(name.toLowerCase());
+        return Collections.unmodifiableList(l);
+    }
+    
+    /**
+     * Return Header Object as String representation. Each headerline is
+     * seperated by "\r\n"
+     * 
+     * @return headers
+     */
+    public String toString() {
+        StringBuffer str = new StringBuffer();
+        for (Iterator it = fields.iterator(); it.hasNext();) {
+            str.append(it.next().toString());
+            str.append("\r\n");
+        }
+        return str.toString();
+    }
+    
+    
+    /**
+     * Write the Header to the given OutputStream
+     * 
+     * @param out the OutputStream to write to
+     * @throws IOException
+     */
+    public void writeTo(OutputStream out) throws IOException {
+        String charString = ((ContentTypeField) getField(Field.CONTENT_TYPE)).getCharset();
+        
+        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, CharsetUtil.getCharset(charString)),8192);
+        writer.write(toString()+ "\r\n");
+        writer.flush();
+        writer.close();
+    }
+
+}

Added: 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=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,256 @@
+/****************************************************************
+ * 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.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Stack;
+
+import org.apache.james.mime4j.BodyDescriptor;
+import org.apache.james.mime4j.ContentHandler;
+import org.apache.james.mime4j.MimeStreamParser;
+import org.apache.james.mime4j.decoder.Base64InputStream;
+import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.UnstructuredField;
+
+
+/**
+ * Represents a MIME message. The following code parses a stream into a 
+ * <code>Message</code> object.
+ * 
+ * <pre>
+ *      Message msg = new Message(new BufferedInputStream(
+ *                                      new FileInputStream("mime.msg")));
+ * </pre>
+ * 
+ *
+ * 
+ * @version $Id: Message.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
+ */
+public class Message extends Entity implements Body {
+    
+    /**
+     * Creates a new empty <code>Message</code>.
+     */
+    public Message() {
+    }
+    
+    /**
+     * Parses the specified MIME message stream into a <code>Message</code>
+     * instance.
+     * 
+     * @param is the stream to parse.
+     * @throws IOException on I/O errors.
+     */
+    public Message(InputStream is) throws IOException {
+        MimeStreamParser parser = new MimeStreamParser();
+        parser.setContentHandler(new MessageBuilder());
+        parser.parse(is);
+    }
+
+    
+    /**
+     * Gets the <code>Subject</code> field.
+     * 
+     * @return the <code>Subject</code> field or <code>null</code> if it
+     *         doesn't exist.
+     */
+    public UnstructuredField getSubject() {
+        return (UnstructuredField) getHeader().getField(Field.SUBJECT);
+    }
+
+    /**
+     * 
+     * @see org.apache.james.mime4j.message.Entity#writeTo(java.io.OutputStream)
+     */
+    public void writeTo(OutputStream out) throws IOException {
+        getHeader().writeTo(out);
+
+        Body body = getBody();
+        if (body instanceof Multipart) {
+            Multipart mp = (Multipart) body;
+            mp.writeTo(out);
+        } else {
+            body.writeTo(out);
+        }
+    }
+    
+    
+    private class MessageBuilder implements ContentHandler {
+        private Stack stack = new Stack();
+        
+        public MessageBuilder() {
+        }
+        
+        private void expect(Class c) {
+            if (!c.isInstance(stack.peek())) {
+                throw new IllegalStateException("Internal stack error: "
+                        + "Expected '" + c.getName() + "' found '"
+                        + stack.peek().getClass().getName() + "'");
+            }
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#startMessage()
+         */
+        public void startMessage() {
+            if (stack.isEmpty()) {
+                stack.push(Message.this);
+            } else {
+                expect(Entity.class);
+                Message m = new Message();
+                ((Entity) stack.peek()).setBody(m);
+                stack.push(m);
+            }
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#endMessage()
+         */
+        public void endMessage() {
+            expect(Message.class);
+            stack.pop();
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#startHeader()
+         */
+        public void startHeader() {
+            stack.push(new Header());
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#field(java.lang.String)
+         */
+        public void field(String fieldData) {
+            expect(Header.class);
+            ((Header) stack.peek()).addField(Field.parse(fieldData));
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#endHeader()
+         */
+        public void endHeader() {
+            expect(Header.class);
+            Header h = (Header) stack.pop();
+            expect(Entity.class);
+            ((Entity) stack.peek()).setHeader(h);
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#startMultipart(org.apache.james.mime4j.BodyDescriptor)
+         */
+        public void startMultipart(BodyDescriptor bd) {
+            expect(Entity.class);
+            
+            Entity e = (Entity) stack.peek();
+            Multipart multiPart = new Multipart();
+            e.setBody(multiPart);
+            stack.push(multiPart);
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
+         */
+        public void body(BodyDescriptor bd, InputStream is) throws IOException {
+            expect(Entity.class);
+            
+            String enc = bd.getTransferEncoding();
+            if ("base64".equals(enc)) {
+                is = new Base64InputStream(is);
+            } else if ("quoted-printable".equals(enc)) {
+                is = new QuotedPrintableInputStream(is);
+            }
+            
+            Body body = null;
+            if (bd.getMimeType().startsWith("text/")) {
+                body = new TempFileTextBody(is, bd.getCharset());
+            } else {
+                body = new TempFileBinaryBody(is);
+            }
+            
+            ((Entity) stack.peek()).setBody(body);
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#endMultipart()
+         */
+        public void endMultipart() {
+            stack.pop();
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#startBodyPart()
+         */
+        public void startBodyPart() {
+            expect(Multipart.class);
+            
+            BodyPart bodyPart = new BodyPart();
+            ((Multipart) stack.peek()).addBodyPart(bodyPart);
+            stack.push(bodyPart);
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#endBodyPart()
+         */
+        public void endBodyPart() {
+            expect(BodyPart.class);
+            stack.pop();
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#epilogue(java.io.InputStream)
+         */
+        public void epilogue(InputStream is) throws IOException {
+            expect(Multipart.class);
+            StringBuffer sb = new StringBuffer();
+            int b;
+            while ((b = is.read()) != -1) {
+                sb.append((char) b);
+            }
+            ((Multipart) stack.peek()).setEpilogue(sb.toString());
+        }
+        
+        /**
+         * @see org.apache.james.mime4j.ContentHandler#preamble(java.io.InputStream)
+         */
+        public void preamble(InputStream is) throws IOException {
+            expect(Multipart.class);
+            StringBuffer sb = new StringBuffer();
+            int b;
+            while ((b = is.read()) != -1) {
+                sb.append((char) b);
+            }
+            ((Multipart) stack.peek()).setPreamble(sb.toString());
+        }
+        
+        /**
+         * TODO: Implement me
+         * 
+         * @see org.apache.james.mime4j.ContentHandler#raw(java.io.InputStream)
+         */
+        public void raw(InputStream is) throws IOException {
+            throw new UnsupportedOperationException("Not supported");
+        }
+
+    }
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Multipart.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Multipart.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Multipart.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Multipart.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,203 @@
+/****************************************************************
+ * 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.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.james.mime4j.field.ContentTypeField;
+import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.util.CharsetUtil;
+
+/**
+ * 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 = "alternative";
+
+    /**
+     * Creates a new empty <code>Multipart</code> instance.
+     */
+    public Multipart() {
+    }
+
+    /**
+     * 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;
+    }
+
+    /**
+     * 
+     * @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream)
+     */
+    public void writeTo(OutputStream out) throws IOException {
+        String boundary = getBoundary();
+        List bodyParts = getBodyParts();
+
+        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, CharsetUtil.getCharset(getCharset())),8192);
+        
+        writer.write(getPreamble() + "\r\n");
+
+        for (int i = 0; i < bodyParts.size(); i++) {
+            writer.write(boundary + "\r\n");
+            ((BodyPart) bodyParts.get(i)).writeTo(out);
+        }
+
+        writer.write(getEpilogue() + "\r\n");
+        writer.write(boundary + "--" + "\r\n");
+
+    }
+
+    /**
+     * Return the boundory of the parent Entity
+     * 
+     * @return boundery
+     */
+    private String getBoundary() {
+        Entity e = getParent();
+        ContentTypeField cField = (ContentTypeField) e.getHeader().getField(
+                Field.CONTENT_TYPE);
+        return cField.getBoundary();
+    }
+    
+    private String getCharset() {
+        Entity e = getParent();
+        String charString = ((ContentTypeField) e.getHeader().getField(Field.CONTENT_TYPE)).getCharset();
+        return charString;
+    }
+}

Added: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java?view=auto&rev=532898
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java (added)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java Thu Apr 26 15:56:11 2007
@@ -0,0 +1,89 @@
+/****************************************************************
+ * 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.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.util.TempFile;
+import org.apache.james.mime4j.util.TempPath;
+import org.apache.james.mime4j.util.TempStorage;
+
+
+/**
+ * Binary body backed by a {@link org.apache.james.mime4j.util.TempFile}.
+ *
+ * 
+ * @version $Id: TempFileBinaryBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
+ */
+class TempFileBinaryBody extends AbstractBody implements BinaryBody {
+    private static Log log = LogFactory.getLog(TempFileBinaryBody.class);
+    
+    private Entity parent = null;
+    private TempFile tempFile = null;
+
+    /**
+     * Use the given InputStream to build the TemporyFileBinaryBody
+     * 
+     * @param is the InputStream to use as source
+     * @throws IOException
+     */
+    public TempFileBinaryBody(InputStream is) throws IOException {
+        
+        TempPath tempPath = TempStorage.getInstance().getRootTempPath();
+        tempFile = tempPath.createTempFile("attachment", ".bin");
+        
+        OutputStream out = tempFile.getOutputStream();
+        IOUtils.copy(is, out);
+        out.close();
+    }
+    
+    /**
+     * @see org.apache.james.mime4j.message.AbstractBody#getParent()
+     */
+    public Entity getParent() {
+        return parent;
+    }
+    
+    /**
+     * @see org.apache.james.mime4j.message.AbstractBody#setParent(org.apache.james.mime4j.message.Entity)
+     */
+    public void setParent(Entity parent) {
+        this.parent = parent;
+    }
+    
+    /**
+     * @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)
+     */
+    public void writeTo(OutputStream out) throws IOException {
+	IOUtils.copy(getInputStream(),out);
+    }
+}



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