001 /*
002 * Copyright 2001-2004 The Apache Software Foundation.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package javax.xml.soap;
017
018 import java.util.Iterator;
019 import java.util.Vector;
020
021 /**
022 * A container for <CODE>MimeHeader</CODE> objects, which
023 * represent the MIME headers present in a MIME part of a
024 * message.</P>
025 *
026 * <P>This class is used primarily when an application wants to
027 * retrieve specific attachments based on certain MIME headers and
028 * values. This class will most likely be used by implementations
029 * of <CODE>AttachmentPart</CODE> and other MIME dependent parts
030 * of the JAXM API.
031 * @see SOAPMessage#getAttachments() SOAPMessage.getAttachments()
032 * @see AttachmentPart AttachmentPart
033 */
034 public class MimeHeaders {
035
036 class MatchingIterator implements Iterator {
037
038 private Object nextMatch() {
039
040 label0:
041 while (iterator.hasNext()) {
042 MimeHeader mimeheader = (MimeHeader) iterator.next();
043
044 if (names == null) {
045 return match
046 ? null
047 : mimeheader;
048 }
049
050 for (int i = 0; i < names.length; i++) {
051 if (!mimeheader.getName().equalsIgnoreCase(names[i])) {
052 continue;
053 }
054
055 if (match) {
056 return mimeheader;
057 }
058
059 continue label0;
060 }
061
062 if (!match) {
063 return mimeheader;
064 }
065 }
066
067 return null;
068 }
069
070 public boolean hasNext() {
071
072 if (nextHeader == null) {
073 nextHeader = nextMatch();
074 }
075
076 return nextHeader != null;
077 }
078
079 public Object next() {
080
081 if (nextHeader != null) {
082 Object obj = nextHeader;
083
084 nextHeader = null;
085
086 return obj;
087 }
088
089 if (hasNext()) {
090 return nextHeader;
091 } else {
092 return null;
093 }
094 }
095
096 public void remove() {
097 iterator.remove();
098 }
099
100 private boolean match;
101
102 private Iterator iterator;
103
104 private String names[];
105
106 private Object nextHeader;
107
108 MatchingIterator(String as[], boolean flag) {
109
110 match = flag;
111 names = as;
112 iterator = headers.iterator();
113 }
114 }
115
116 /**
117 * Constructs
118 * a default <CODE>MimeHeaders</CODE> object initialized with
119 * an empty <CODE>Vector</CODE> object.
120 */
121 public MimeHeaders() {
122 headers = new Vector();
123 }
124
125 /**
126 * Returns all of the values for the specified header as an
127 * array of <CODE>String</CODE> objects.
128 * @param name the name of the header for which
129 * values will be returned
130 * @return a <CODE>String</CODE> array with all of the values
131 * for the specified header
132 * @see #setHeader(java.lang.String, java.lang.String) setHeader(java.lang.String, java.lang.String)
133 */
134 public String[] getHeader(String name) {
135
136 Vector vector = new Vector();
137
138 for (int i = 0; i < headers.size(); i++) {
139 MimeHeader mimeheader = (MimeHeader) headers.elementAt(i);
140
141 if (mimeheader.getName().equalsIgnoreCase(name)
142 && (mimeheader.getValue() != null)) {
143 vector.addElement(mimeheader.getValue());
144 }
145 }
146
147 if (vector.size() == 0) {
148 return null;
149 } else {
150 String as[] = new String[vector.size()];
151
152 vector.copyInto(as);
153
154 return as;
155 }
156 }
157
158 /**
159 * Replaces the current value of the first header entry whose
160 * name matches the given name with the given value, adding a
161 * new header if no existing header name matches. This method
162 * also removes all matching headers after the first one.
163 *
164 * <P>Note that RFC822 headers can contain only US-ASCII
165 * characters.</P>
166 * @param name a <CODE>String</CODE> with the
167 * name of the header for which to search
168 * @param value a <CODE>String</CODE> with the
169 * value that will replace the current value of the
170 * specified header
171 * @throws java.lang.IllegalArgumentException if there was a
172 * problem in the mime header name or the value being set
173 * @see #getHeader(java.lang.String) getHeader(java.lang.String)
174 */
175 public void setHeader(String name, String value) {
176
177 boolean flag = false;
178
179 if ((name == null) || name.equals("")) {
180 throw new IllegalArgumentException(
181 "Illegal MimeHeader name");
182 }
183
184 for (int i = 0; i < headers.size(); i++) {
185 MimeHeader mimeheader = (MimeHeader) headers.elementAt(i);
186
187 if (mimeheader.getName().equalsIgnoreCase(name)) {
188 if (!flag) {
189 headers.setElementAt(new MimeHeader(mimeheader
190 .getName(), value), i);
191
192 flag = true;
193 } else {
194 headers.removeElementAt(i--);
195 }
196 }
197 }
198
199 if (!flag) {
200 addHeader(name, value);
201 }
202 }
203
204 /**
205 * Adds a <CODE>MimeHeader</CODE> object with the specified
206 * name and value to this <CODE>MimeHeaders</CODE> object's
207 * list of headers.
208 *
209 * <P>Note that RFC822 headers can contain only US-ASCII
210 * characters.</P>
211 * @param name a <CODE>String</CODE> with the
212 * name of the header to be added
213 * @param value a <CODE>String</CODE> with the
214 * value of the header to be added
215 * @throws java.lang.IllegalArgumentException if
216 * there was a problem in the mime header name or value
217 * being added
218 */
219 public void addHeader(String name, String value) {
220
221 if ((name == null) || name.equals("")) {
222 throw new IllegalArgumentException(
223 "Illegal MimeHeader name");
224 }
225
226 int i = headers.size();
227
228 for (int j = i - 1; j >= 0; j--) {
229 MimeHeader mimeheader = (MimeHeader) headers.elementAt(j);
230
231 if (mimeheader.getName().equalsIgnoreCase(name)) {
232 headers.insertElementAt(new MimeHeader(name, value), j + 1);
233
234 return;
235 }
236 }
237
238 headers.addElement(new MimeHeader(name, value));
239 }
240
241 /**
242 * Remove all <CODE>MimeHeader</CODE> objects whose name
243 * matches the the given name.
244 * @param name a <CODE>String</CODE> with the
245 * name of the header for which to search
246 */
247 public void removeHeader(String name) {
248
249 for (int i = 0; i < headers.size(); i++) {
250 MimeHeader mimeheader = (MimeHeader) headers.elementAt(i);
251
252 if (mimeheader.getName().equalsIgnoreCase(name)) {
253 headers.removeElementAt(i--);
254 }
255 }
256 }
257
258 /**
259 * Removes all the header entries from this <CODE>
260 * MimeHeaders</CODE> object.
261 */
262 public void removeAllHeaders() {
263 headers.removeAllElements();
264 }
265
266 /**
267 * Returns all the headers in this <CODE>MimeHeaders</CODE>
268 * object.
269 * @return an <CODE>Iterator</CODE> object over this <CODE>
270 * MimeHeaders</CODE> object's list of <CODE>
271 * MimeHeader</CODE> objects
272 */
273 public Iterator getAllHeaders() {
274 return headers.iterator();
275 }
276
277 /**
278 * Returns all the <CODE>MimeHeader</CODE> objects whose
279 * name matches a name in the given array of names.
280 * @param names an array of <CODE>String</CODE>
281 * objects with the names for which to search
282 * @return an <CODE>Iterator</CODE> object over the <CODE>
283 * MimeHeader</CODE> objects whose name matches one of the
284 * names in the given list
285 */
286 public Iterator getMatchingHeaders(String names[]) {
287 return new MatchingIterator(names, true);
288 }
289
290 /**
291 * Returns all of the <CODE>MimeHeader</CODE> objects whose
292 * name does not match a name in the given array of names.
293 * @param names an array of <CODE>String</CODE>
294 * objects with the names for which to search
295 * @return an <CODE>Iterator</CODE> object over the <CODE>
296 * MimeHeader</CODE> objects whose name does not match one
297 * of the names in the given list
298 */
299 public Iterator getNonMatchingHeaders(String names[]) {
300 return new MatchingIterator(names, false);
301 }
302
303 // fixme: does this need to be a Vector? Will a non-synchronized impl of
304 // List do?
305 /**
306 * A <code>Vector</code> containing the headers as <code>MimeHeader</code>
307 * instances.
308 */
309 private Vector headers;
310 }