View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package javax.xml.soap;
17  
18  import java.util.Iterator;
19  import java.util.Vector;
20  
21  /**
22   * A container for <CODE>MimeHeader</CODE> objects, which
23   *   represent the MIME headers present in a MIME part of a
24   *   message.</P>
25   *
26   *   <P>This class is used primarily when an application wants to
27   *   retrieve specific attachments based on certain MIME headers and
28   *   values. This class will most likely be used by implementations
29   *   of <CODE>AttachmentPart</CODE> and other MIME dependent parts
30   *   of the JAXM API.
31   * @see SOAPMessage#getAttachments() SOAPMessage.getAttachments()
32   * @see AttachmentPart AttachmentPart
33   */
34  public class MimeHeaders {
35  
36      class MatchingIterator implements Iterator {
37  
38          private Object nextMatch() {
39  
40              label0:
41              while (iterator.hasNext()) {
42                  MimeHeader mimeheader = (MimeHeader) iterator.next();
43  
44                  if (names == null) {
45                      return match
46                             ? null
47                             : mimeheader;
48                  }
49  
50                  for (int i = 0; i < names.length; i++) {
51                      if (!mimeheader.getName().equalsIgnoreCase(names[i])) {
52                          continue;
53                      }
54  
55                      if (match) {
56                          return mimeheader;
57                      }
58  
59                      continue label0;
60                  }
61  
62                  if (!match) {
63                      return mimeheader;
64                  }
65              }
66  
67              return null;
68          }
69  
70          public boolean hasNext() {
71  
72              if (nextHeader == null) {
73                  nextHeader = nextMatch();
74              }
75  
76              return nextHeader != null;
77          }
78  
79          public Object next() {
80  
81              if (nextHeader != null) {
82                  Object obj = nextHeader;
83  
84                  nextHeader = null;
85  
86                  return obj;
87              }
88  
89              if (hasNext()) {
90                  return nextHeader;
91              } else {
92                  return null;
93              }
94          }
95  
96          public void remove() {
97              iterator.remove();
98          }
99  
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 }