1 /*
2 * $Id: MimeHeaders.java,v 1.4 2004/04/02 01:24:17 ofung Exp $
3 * $Revision: 1.4 $
4 * $Date: 2004/04/02 01:24:17 $
5 */
6
7 /*
8 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10 *
11 * This code is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 only, as
13 * published by the Free Software Foundation. Sun designates this
14 * particular file as subject to the "Classpath" exception as provided
15 * by Sun in the LICENSE file that accompanied this code.
16 *
17 * This code is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * version 2 for more details (a copy is included in the LICENSE file that
21 * accompanied this code).
22 *
23 * You should have received a copy of the GNU General Public License version
24 * 2 along with this work; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
28 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * have any questions.
30 */
31 package javax.xml.soap;
32
33 import java.util.Iterator;
34 import java.util.Vector;
35
36 /**
37 * A container for <code>MimeHeader</code> objects, which represent
38 * the MIME headers present in a MIME part of a message.
39 *
40 * <p>This class is used primarily when an application wants to
41 * retrieve specific attachments based on certain MIME headers and
42 * values. This class will most likely be used by implementations of
43 * <code>AttachmentPart</code> and other MIME dependent parts of the SAAJ
44 * API.
45 * @see SOAPMessage#getAttachments
46 * @see AttachmentPart
47 */
48 public class MimeHeaders {
49 private Vector headers;
50
51 /**
52 * Constructs a default <code>MimeHeaders</code> object initialized with
53 * an empty <code>Vector</code> object.
54 */
55 public MimeHeaders() {
56 headers = new Vector();
57 }
58
59 /**
60 * Returns all of the values for the specified header as an array of
61 * <code>String</code> objects.
62 *
63 * @param name the name of the header for which values will be returned
64 * @return a <code>String</code> array with all of the values for the
65 * specified header
66 * @see #setHeader
67 */
68 public String[] getHeader(String name) {
69 Vector values = new Vector();
70
71 for(int i = 0; i < headers.size(); i++) {
72 MimeHeader hdr = (MimeHeader) headers.elementAt(i);
73 if (hdr.getName().equalsIgnoreCase(name)
74 && hdr.getValue() != null)
75 values.addElement(hdr.getValue());
76 }
77
78 if (values.size() == 0)
79 return null;
80
81 String r[] = new String[values.size()];
82 values.copyInto(r);
83 return r;
84 }
85
86 /**
87 * Replaces the current value of the first header entry whose name matches
88 * the given name with the given value, adding a new header if no existing header
89 * name matches. This method also removes all matching headers after the first one.
90 * <P>
91 * Note that RFC822 headers can contain only US-ASCII characters.
92 *
93 * @param name a <code>String</code> with the name of the header for
94 * which to search
95 * @param value a <code>String</code> with the value that will replace the
96 * current value of the specified header
97 *
98 * @exception IllegalArgumentException if there was a problem in the
99 * mime header name or the value being set
100 * @see #getHeader
101 */
102 public void setHeader(String name, String value)
103 {
104 boolean found = false;
105
106 if ((name == null) || name.equals(""))
107 throw new IllegalArgumentException("Illegal MimeHeader name");
108
109 for(int i = 0; i < headers.size(); i++) {
110 MimeHeader hdr = (MimeHeader) headers.elementAt(i);
111 if (hdr.getName().equalsIgnoreCase(name)) {
112 if (!found) {
113 headers.setElementAt(new MimeHeader(hdr.getName(),
114 value), i);
115 found = true;
116 }
117 else
118 headers.removeElementAt(i--);
119 }
120 }
121
122 if (!found)
123 addHeader(name, value);
124 }
125
126 /**
127 * Adds a <code>MimeHeader</code> object with the specified name and value
128 * to this <code>MimeHeaders</code> object's list of headers.
129 * <P>
130 * Note that RFC822 headers can contain only US-ASCII characters.
131 *
132 * @param name a <code>String</code> with the name of the header to
133 * be added
134 * @param value a <code>String</code> with the value of the header to
135 * be added
136 *
137 * @exception IllegalArgumentException if there was a problem in the
138 * mime header name or value being added
139 */
140 public void addHeader(String name, String value)
141 {
142 if ((name == null) || name.equals(""))
143 throw new IllegalArgumentException("Illegal MimeHeader name");
144
145 int pos = headers.size();
146
147 for(int i = pos - 1 ; i >= 0; i--) {
148 MimeHeader hdr = (MimeHeader) headers.elementAt(i);
149 if (hdr.getName().equalsIgnoreCase(name)) {
150 headers.insertElementAt(new MimeHeader(name, value),
151 i+1);
152 return;
153 }
154 }
155 headers.addElement(new MimeHeader(name, value));
156 }
157
158 /**
159 * Remove all <code>MimeHeader</code> objects whose name matches the
160 * given name.
161 *
162 * @param name a <code>String</code> with the name of the header for
163 * which to search
164 */
165 public void removeHeader(String name) {
166 for(int i = 0; i < headers.size(); i++) {
167 MimeHeader hdr = (MimeHeader) headers.elementAt(i);
168 if (hdr.getName().equalsIgnoreCase(name))
169 headers.removeElementAt(i--);
170 }
171 }
172
173 /**
174 * Removes all the header entries from this <code>MimeHeaders</code> object.
175 */
176 public void removeAllHeaders() {
177 headers.removeAllElements();
178 }
179
180
181 /**
182 * Returns all the <code>MimeHeader</code>s in this <code>MimeHeaders</code> object.
183 *
184 * @return an <code>Iterator</code> object over this <code>MimeHeaders</code>
185 * object's list of <code>MimeHeader</code> objects
186 */
187 public Iterator getAllHeaders() {
188 return headers.iterator();
189 }
190
191 class MatchingIterator implements Iterator {
192 private boolean match;
193 private Iterator iterator;
194 private String[] names;
195 private Object nextHeader;
196
197 MatchingIterator(String[] names, boolean match) {
198 this.match = match;
199 this.names = names;
200 this.iterator = headers.iterator();
201 }
202
203 private Object nextMatch() {
204 next:
205 while (iterator.hasNext()) {
206 MimeHeader hdr = (MimeHeader) iterator.next();
207
208 if (names == null)
209 return match ? null : hdr;
210
211 for(int i = 0; i < names.length; i++)
212 if (hdr.getName().equalsIgnoreCase(names[i]))
213 if (match)
214 return hdr;
215 else
216 continue next;
217 if (!match)
218 return hdr;
219 }
220 return null;
221 }
222
223
224 public boolean hasNext() {
225 if (nextHeader == null)
226 nextHeader = nextMatch();
227 return nextHeader != null;
228 }
229
230 public Object next() {
231 // hasNext should've prefetched the header for us,
232 // return it.
233 if (nextHeader != null) {
234 Object ret = nextHeader;
235 nextHeader = null;
236 return ret;
237 }
238 if (hasNext())
239 return nextHeader;
240 return null;
241 }
242
243 public void remove() {
244 iterator.remove();
245 }
246 }
247
248
249 /**
250 * Returns all the <code>MimeHeader</code> objects whose name matches
251 * a name in the given array of names.
252 *
253 * @param names an array of <code>String</code> objects with the names
254 * for which to search
255 * @return an <code>Iterator</code> object over the <code>MimeHeader</code>
256 * objects whose name matches one of the names in the given list
257 */
258 public Iterator getMatchingHeaders(String[] names) {
259 return new MatchingIterator(names, true);
260 }
261
262 /**
263 * Returns all of the <code>MimeHeader</code> objects whose name does not
264 * match a name in the given array of names.
265 *
266 * @param names an array of <code>String</code> objects with the names
267 * for which to search
268 * @return an <code>Iterator</code> object over the <code>MimeHeader</code>
269 * objects whose name does not match one of the names in the given list
270 */
271 public Iterator getNonMatchingHeaders(String[] names) {
272 return new MatchingIterator(names, false);
273 }
274 }