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