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 }