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