1 /************************************************************************
2 * Copyright (c) 2000-2006 The Apache Software Foundation. *
3 * All rights reserved. *
4 * ------------------------------------------------------------------- *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you *
6 * may not use this file except in compliance with the License. You *
7 * may obtain a copy of the License at: *
8 * *
9 * http://www.apache.org/licenses/LICENSE-2.0 *
10 * *
11 * Unless required by applicable law or agreed to in writing, software *
12 * distributed under the License is distributed on an "AS IS" BASIS, *
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14 * implied. See the License for the specific language governing *
15 * permissions and limitations under the License. *
16 ***********************************************************************/
17
18 package org.apache.james.core;
19
20 import javax.mail.MessagingException;
21 import javax.mail.internet.InternetHeaders;
22
23 import java.io.ByteArrayOutputStream;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.io.PrintStream;
27 import java.io.Serializable;
28 import java.util.Enumeration;
29
30 import org.apache.mailet.RFC2822Headers;
31
32 /***
33 * This interface defines a container for mail headers. Each header must use
34 * MIME format: <pre>name: value</pre>.
35 *
36 */
37 public class MailHeaders extends InternetHeaders implements Serializable, Cloneable {
38
39 /***
40 * No argument constructor
41 *
42 * @throws MessagingException if the super class cannot be properly instantiated
43 */
44 public MailHeaders() throws MessagingException {
45 super();
46 }
47
48 /***
49 * Constructor that takes an InputStream containing the contents
50 * of the set of mail headers.
51 *
52 * @param in the InputStream containing the header data
53 *
54 * @throws MessagingException if the super class cannot be properly instantiated
55 * based on the stream
56 */
57 public MailHeaders(InputStream in) throws MessagingException {
58 super();
59 load(in);
60 }
61
62 /***
63 * Write the headers to an output stream
64 *
65 * @param writer the stream to which to write the headers
66 */
67 public void writeTo(OutputStream out) {
68 PrintStream pout;
69 if (out instanceof PrintStream) {
70 pout = (PrintStream)out;
71 } else {
72 pout = new PrintStream(out);
73 }
74 for (Enumeration e = super.getAllHeaderLines(); e.hasMoreElements(); ) {
75 pout.print((String) e.nextElement());
76 pout.print("\r\n");
77 }
78
79 pout.print("\r\n");
80 }
81
82 /***
83 * Generate a representation of the headers as a series of bytes.
84 *
85 * @return the byte array containing the headers
86 */
87 public byte[] toByteArray() {
88 ByteArrayOutputStream headersBytes = new ByteArrayOutputStream();
89 writeTo(headersBytes);
90 return headersBytes.toByteArray();
91 }
92
93 /***
94 * Check if a particular header is present.
95 *
96 * @return true if the header is present, false otherwise
97 */
98 public boolean isSet(String name) {
99 String[] value = super.getHeader(name);
100 return (value != null && value.length != 0);
101 }
102
103 /***
104 * If the new header is a Return-Path we get sure that we add it to the top
105 * Javamail, at least until 1.4.0 does the wrong thing if it loaded a stream with
106 * a return-path in the middle.
107 *
108 * @see javax.mail.internet.InternetHeaders#addHeader(java.lang.String, java.lang.String)
109 */
110 public void addHeader(String arg0, String arg1) {
111 if (RFC2822Headers.RETURN_PATH.equalsIgnoreCase(arg0)) {
112 headers.add(0, new InternetHeader(arg0, arg1));
113 } else {
114 super.addHeader(arg0, arg1);
115 }
116 }
117
118 /***
119 * If the new header is a Return-Path we get sure that we add it to the top
120 * Javamail, at least until 1.4.0 does the wrong thing if it loaded a stream with
121 * a return-path in the middle.
122 *
123 * @see javax.mail.internet.InternetHeaders#setHeader(java.lang.String, java.lang.String)
124 */
125 public void setHeader(String arg0, String arg1) {
126 if (RFC2822Headers.RETURN_PATH.equalsIgnoreCase(arg0)) {
127 super.removeHeader(arg0);
128 }
129 super.setHeader(arg0, arg1);
130 }
131
132 protected Object clone() throws CloneNotSupportedException {
133
134 return super.clone();
135 }
136
137 /***
138 * Check if all REQUIRED headers fields as specified in RFC 822
139 * are present.
140 *
141 * @return true if the headers are present, false otherwise
142 */
143 public boolean isValid() {
144 return (isSet(RFC2822Headers.DATE) && isSet(RFC2822Headers.TO) && isSet(RFC2822Headers.FROM));
145 }
146 }