1 /* 2 * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.xml.soap; 27 28 import java.util.Iterator; 29 import java.util.Vector; 30 31 /** 32 * A container for {@code MimeHeader} objects, which represent 33 * the MIME headers present in a MIME part of a message. 34 * 35 * <p>This class is used primarily when an application wants to 36 * retrieve specific attachments based on certain MIME headers and 37 * values. This class will most likely be used by implementations of 38 * {@code AttachmentPart} and other MIME dependent parts of the SAAJ 39 * API. 40 * @see SOAPMessage#getAttachments 41 * @see AttachmentPart 42 * @since 1.6 43 */ 44 public class MimeHeaders { 45 private Vector headers; 46 47 /** 48 * Constructs a default {@code MimeHeaders} object initialized with 49 * an empty {@code Vector} object. 50 */ 51 public MimeHeaders() { 52 headers = new Vector(); 53 } 54 55 /** 56 * Returns all of the values for the specified header as an array of 57 * {@code String} objects. 58 * 59 * @param name the name of the header for which values will be returned 60 * @return a {@code String} array with all of the values for the 61 * specified header 62 * @see #setHeader 63 */ 64 public String[] getHeader(String name) { 65 Vector values = new Vector(); 66 67 for(int i = 0; i < headers.size(); i++) { 68 MimeHeader hdr = (MimeHeader) headers.elementAt(i); 69 if (hdr.getName().equalsIgnoreCase(name) 70 && hdr.getValue() != null) 71 values.addElement(hdr.getValue()); 72 } 73 74 if (values.size() == 0) 75 return null; 76 77 String r[] = new String[values.size()]; 78 values.copyInto(r); 79 return r; 80 } 81 82 /** 83 * Replaces the current value of the first header entry whose name matches 84 * the given name with the given value, adding a new header if no existing header 85 * name matches. This method also removes all matching headers after the first one. 86 * <P> 87 * Note that RFC822 headers can contain only US-ASCII characters. 88 * 89 * @param name a {@code String} with the name of the header for 90 * which to search 91 * @param value a {@code String} with the value that will replace the 92 * current value of the specified header 93 * 94 * @exception IllegalArgumentException if there was a problem in the 95 * mime header name or the value being set 96 * @see #getHeader 97 */ 98 public void setHeader(String name, String value) 99 { 100 boolean found = false; 101 102 if ((name == null) || name.equals("")) 103 throw new IllegalArgumentException("Illegal MimeHeader name"); 104 105 for(int i = 0; i < headers.size(); i++) { 106 MimeHeader hdr = (MimeHeader) headers.elementAt(i); 107 if (hdr.getName().equalsIgnoreCase(name)) { 108 if (!found) { 109 headers.setElementAt(new MimeHeader(hdr.getName(), 110 value), i); 111 found = true; 112 } 113 else 114 headers.removeElementAt(i--); 115 } 116 } 117 118 if (!found) 119 addHeader(name, value); 120 } 121 122 /** 123 * Adds a {@code MimeHeader} object with the specified name and value 124 * to this {@code MimeHeaders} object's list of headers. 125 * <P> 126 * Note that RFC822 headers can contain only US-ASCII characters. 127 * 128 * @param name a {@code String} with the name of the header to 129 * be added 130 * @param value a {@code String} with the value of the header to 131 * be added 132 * 133 * @exception IllegalArgumentException if there was a problem in the 134 * mime header name or value being added 135 */ 136 public void addHeader(String name, String value) 137 { 138 if ((name == null) || name.equals("")) 139 throw new IllegalArgumentException("Illegal MimeHeader name"); 140 141 int pos = headers.size(); 142 143 for(int i = pos - 1 ; i >= 0; i--) { 144 MimeHeader hdr = (MimeHeader) headers.elementAt(i); 145 if (hdr.getName().equalsIgnoreCase(name)) { 146 headers.insertElementAt(new MimeHeader(name, value), 147 i+1); 148 return; 149 } 150 } 151 headers.addElement(new MimeHeader(name, value)); 152 } 153 154 /** 155 * Remove all {@code MimeHeader} objects whose name matches the 156 * given name. 157 * 158 * @param name a {@code String} with the name of the header for 159 * which to search 160 */ 161 public void removeHeader(String name) { 162 for(int i = 0; i < headers.size(); i++) { 163 MimeHeader hdr = (MimeHeader) headers.elementAt(i); 164 if (hdr.getName().equalsIgnoreCase(name)) 165 headers.removeElementAt(i--); 166 } 167 } 168 169 /** 170 * Removes all the header entries from this {@code MimeHeaders} object. 171 */ 172 public void removeAllHeaders() { 173 headers.removeAllElements(); 174 } 175 176 177 /** 178 * Returns all the {@code MimeHeader}s in this {@code MimeHeaders} object. 179 * 180 * @return an {@code Iterator} object over this {@code MimeHeaders} 181 * object's list of {@code MimeHeader} objects 182 */ 183 public Iterator getAllHeaders() { 184 return headers.iterator(); 185 } 186 187 class MatchingIterator implements Iterator { 188 private boolean match; 189 private Iterator iterator; 190 private String[] names; 191 private Object nextHeader; 192 193 MatchingIterator(String[] names, boolean match) { 194 this.match = match; 195 this.names = names; 196 this.iterator = headers.iterator(); 197 } 198 199 private Object nextMatch() { 200 next: 201 while (iterator.hasNext()) { 202 MimeHeader hdr = (MimeHeader) iterator.next(); 203 204 if (names == null) 205 return match ? null : hdr; 206 207 for(int i = 0; i < names.length; i++) 208 if (hdr.getName().equalsIgnoreCase(names[i])) 209 if (match) 210 return hdr; 211 else 212 continue next; 213 if (!match) 214 return hdr; 215 } 216 return null; 217 } 218 219 220 public boolean hasNext() { 221 if (nextHeader == null) 222 nextHeader = nextMatch(); 223 return nextHeader != null; 224 } 225 226 public Object next() { 227 // hasNext should've prefetched the header for us, 228 // return it. 229 if (nextHeader != null) { 230 Object ret = nextHeader; 231 nextHeader = null; 232 return ret; 233 } 234 if (hasNext()) 235 return nextHeader; 236 return null; 237 } 238 239 public void remove() { 240 iterator.remove(); 241 } 242 } 243 244 245 /** 246 * Returns all the {@code MimeHeader} objects whose name matches 247 * a name in the given array of names. 248 * 249 * @param names an array of {@code String} objects with the names 250 * for which to search 251 * @return an {@code Iterator} object over the {@code MimeHeader} 252 * objects whose name matches one of the names in the given list 253 */ 254 public Iterator getMatchingHeaders(String[] names) { 255 return new MatchingIterator(names, true); 256 } 257 258 /** 259 * Returns all of the {@code MimeHeader} objects whose name does not 260 * match a name in the given array of names. 261 * 262 * @param names an array of {@code String} objects with the names 263 * for which to search 264 * @return an {@code Iterator} object over the {@code MimeHeader} 265 * objects whose name does not match one of the names in the given list 266 */ 267 public Iterator getNonMatchingHeaders(String[] names) { 268 return new MatchingIterator(names, false); 269 } 270 }