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 package javax.xml.soap;
020
021 import java.util.Iterator;
022 import java.util.Vector;
023
024 /**
025 * A container for <CODE>MimeHeader</CODE> objects, which represent the MIME headers present in a
026 * MIME part of a message.</P>
027 * <p/>
028 * <P>This class is used primarily when an application wants to retrieve specific attachments based
029 * on certain MIME headers and values. This class will most likely be used by implementations of
030 * <CODE>AttachmentPart</CODE> and other MIME dependent parts of the JAXM API.
031 *
032 * @see SOAPMessage#getAttachments() SOAPMessage.getAttachments()
033 * @see AttachmentPart AttachmentPart
034 */
035 public class MimeHeaders {
036
037 class MatchingIterator implements Iterator {
038
039 private Object nextMatch() {
040
041 label0:
042 while (iterator.hasNext()) {
043 MimeHeader mimeheader = (MimeHeader)iterator.next();
044
045 if (names == null) {
046 return match
047 ? null
048 : mimeheader;
049 }
050
051 for (int i = 0; i < names.length; i++) {
052 if (!mimeheader.getName().equalsIgnoreCase(names[i])) {
053 continue;
054 }
055
056 if (match) {
057 return mimeheader;
058 }
059
060 continue label0;
061 }
062
063 if (!match) {
064 return mimeheader;
065 }
066 }
067
068 return null;
069 }
070
071 public boolean hasNext() {
072
073 if (nextHeader == null) {
074 nextHeader = nextMatch();
075 }
076
077 return nextHeader != null;
078 }
079
080 public Object next() {
081
082 if (nextHeader != null) {
083 Object obj = nextHeader;
084
085 nextHeader = null;
086
087 return obj;
088 }
089
090 if (hasNext()) {
091 return nextHeader;
092 } else {
093 return null;
094 }
095 }
096
097 public void remove() {
098 iterator.remove();
099 }
100
101 private boolean match;
102
103 private Iterator iterator;
104
105 private String names[];
106
107 private Object nextHeader;
108
109 MatchingIterator(String as[], boolean flag) {
110
111 match = flag;
112 names = as;
113 iterator = headers.iterator();
114 }
115 }
116
117 /**
118 * Constructs a default <CODE>MimeHeaders</CODE> object initialized with an empty
119 * <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 array of <CODE>String</CODE>
127 * objects.
128 *
129 * @param name the name of the header for which values will be returned
130 * @return a <CODE>String</CODE> array with all of the values for the specified header
131 * @see #setHeader(String, String) setHeader(java.lang.String,
132 * 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 name matches the given name with
160 * the given value, adding a new header if no existing header name matches. This method also
161 * removes all matching headers after the first one.
162 * <p/>
163 * <P>Note that RFC822 headers can contain only US-ASCII characters.</P>
164 *
165 * @param name a <CODE>String</CODE> with the name of the header for which to search
166 * @param value a <CODE>String</CODE> with the value that will replace the current value of the
167 * specified header
168 * @throws IllegalArgumentException
169 * if there was a problem in the mime header name or the value being set
170 * @see #getHeader(String) getHeader(java.lang.String)
171 */
172 public void setHeader(String name, String value) {
173
174 boolean flag = false;
175
176 if ((name == null) || "".equals(name)) {
177 throw new IllegalArgumentException("Illegal MimeHeader name");
178 }
179
180 for (int i = 0; i < headers.size(); i++) {
181 MimeHeader mimeheader = (MimeHeader)headers.elementAt(i);
182
183 if (mimeheader.getName().equalsIgnoreCase(name)) {
184 if (!flag) {
185 headers.setElementAt(new MimeHeader(mimeheader
186 .getName(), value), i);
187
188 flag = true;
189 } else {
190 headers.removeElementAt(i--);
191 }
192 }
193 }
194
195 if (!flag) {
196 addHeader(name, value);
197 }
198 }
199
200 /**
201 * Adds a <CODE>MimeHeader</CODE> object with the specified name and value to this
202 * <CODE>MimeHeaders</CODE> object's list of headers.
203 * <p/>
204 * <P>Note that RFC822 headers can contain only US-ASCII characters.</P>
205 *
206 * @param name a <CODE>String</CODE> with the name of the header to be added
207 * @param value a <CODE>String</CODE> with the value of the header to be added
208 * @throws IllegalArgumentException
209 * if there was a problem in the mime header name or value being added
210 */
211 public void addHeader(String name, String value) {
212
213 if ((name == null) || "".equals(name)) {
214 throw new IllegalArgumentException("Illegal MimeHeader name");
215 }
216
217 int i = headers.size();
218
219 for (int j = i - 1; j >= 0; j--) {
220 MimeHeader mimeheader = (MimeHeader)headers.elementAt(j);
221
222 if (mimeheader.getName().equalsIgnoreCase(name)) {
223 headers.insertElementAt(new MimeHeader(name, value), j + 1);
224
225 return;
226 }
227 }
228
229 headers.addElement(new MimeHeader(name, value));
230 }
231
232 /**
233 * Remove all <CODE>MimeHeader</CODE> objects whose name matches the the given name.
234 *
235 * @param name a <CODE>String</CODE> with the name of the header for which to search
236 */
237 public void removeHeader(String name) {
238
239 for (int i = 0; i < headers.size(); i++) {
240 MimeHeader mimeheader = (MimeHeader)headers.elementAt(i);
241
242 if (mimeheader.getName().equalsIgnoreCase(name)) {
243 headers.removeElementAt(i--);
244 }
245 }
246 }
247
248 /** Removes all the header entries from this <CODE> MimeHeaders</CODE> object. */
249 public void removeAllHeaders() {
250 headers.removeAllElements();
251 }
252
253 /**
254 * Returns all the headers in this <CODE>MimeHeaders</CODE> object.
255 *
256 * @return an <CODE>Iterator</CODE> object over this <CODE> MimeHeaders</CODE> object's list of
257 * <CODE> MimeHeader</CODE> objects
258 */
259 public Iterator getAllHeaders() {
260 return headers.iterator();
261 }
262
263 /**
264 * Returns all the <CODE>MimeHeader</CODE> objects whose name matches a name in the given array
265 * of names.
266 *
267 * @param names an array of <CODE>String</CODE> objects with the names for which to search
268 * @return an <CODE>Iterator</CODE> object over the <CODE> MimeHeader</CODE> objects whose name
269 * matches one of the names in the given list
270 */
271 public Iterator getMatchingHeaders(String names[]) {
272 return new MatchingIterator(names, true);
273 }
274
275 /**
276 * Returns all of the <CODE>MimeHeader</CODE> objects whose name does not match a name in the
277 * given array of names.
278 *
279 * @param names an array of <CODE>String</CODE> objects with the names for which to search
280 * @return an <CODE>Iterator</CODE> object over the <CODE> MimeHeader</CODE> objects whose name
281 * does not match one of the names in the given list
282 */
283 public Iterator getNonMatchingHeaders(String names[]) {
284 return new MatchingIterator(names, false);
285 }
286
287 // fixme: does this need to be a Vector? Will a non-synchronized impl of
288 // List do?
289 /** A <code>Vector</code> containing the headers as <code>MimeHeader</code> instances. */
290 private Vector headers;
291 }