Tue, 09 Apr 2013 14:51:13 +0100
8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com
1 /*
2 * Copyright (c) 1997, 2013, 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 */
26 package com.sun.xml.internal.messaging.saaj.soap;
28 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl;
30 import com.sun.xml.internal.messaging.saaj.packaging.mime.util.ASCIIUtility;
32 import com.sun.xml.internal.messaging.saaj.packaging.mime.Header;
33 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimePartDataSource;
34 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.InternetHeaders;
35 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeBodyPart;
36 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility;
37 import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
38 import com.sun.xml.internal.messaging.saaj.util.LogDomainConstants;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.io.ByteArrayOutputStream;
43 import java.io.ByteArrayInputStream;
44 import java.io.OutputStream;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.logging.Level;
48 import java.util.logging.Logger;
50 import javax.activation.*;
51 import javax.xml.soap.*;
52 import com.sun.xml.internal.org.jvnet.mimepull.MIMEPart;
54 /**
55 * Implementation of attachments.
56 *
57 * @author Anil Vijendran (akv@eng.sun.com)
58 */
59 public class AttachmentPartImpl extends AttachmentPart {
61 protected static final Logger log =
62 Logger.getLogger(LogDomainConstants.SOAP_DOMAIN,
63 "com.sun.xml.internal.messaging.saaj.soap.LocalStrings");
65 static {
66 try {
67 CommandMap map = CommandMap.getDefaultCommandMap();
68 if (map instanceof MailcapCommandMap) {
69 MailcapCommandMap mailMap = (MailcapCommandMap) map;
70 String hndlrStr = ";;x-java-content-handler=";
71 mailMap.addMailcap(
72 "text/xml"
73 + hndlrStr
74 + "com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler");
75 mailMap.addMailcap(
76 "application/xml"
77 + hndlrStr
78 + "com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler");
79 mailMap.addMailcap(
80 "application/fastinfoset"
81 + hndlrStr
82 + "com.sun.xml.internal.messaging.saaj.soap.FastInfosetDataContentHandler");
83 /* Image DataContentHandler handles all image types
84 mailMap.addMailcap(
85 "image/jpeg"
86 + hndlrStr
87 + "com.sun.xml.internal.messaging.saaj.soap.JpegDataContentHandler");
88 mailMap.addMailcap(
89 "image/gif"
90 + hndlrStr
91 + "com.sun.xml.internal.messaging.saaj.soap.GifDataContentHandler"); */
92 /*mailMap.addMailcap(
93 "multipart/*"
94 + hndlrStr
95 + "com.sun.xml.internal.messaging.saaj.soap.MultipartDataContentHandler");*/
96 mailMap.addMailcap(
97 "image/*"
98 + hndlrStr
99 + "com.sun.xml.internal.messaging.saaj.soap.ImageDataContentHandler");
100 mailMap.addMailcap(
101 "text/plain"
102 + hndlrStr
103 + "com.sun.xml.internal.messaging.saaj.soap.StringDataContentHandler");
104 } else {
105 throw new SOAPExceptionImpl("Default CommandMap is not a MailcapCommandMap");
106 }
107 } catch (Throwable t) {
108 log.log(
109 Level.SEVERE,
110 "SAAJ0508.soap.cannot.register.handlers",
111 t);
112 if (t instanceof RuntimeException) {
113 throw (RuntimeException) t;
114 } else {
115 throw new RuntimeException(t.getLocalizedMessage());
116 }
117 }
118 };
120 private final MimeHeaders headers;
121 private MimeBodyPart rawContent = null;
122 private DataHandler dataHandler = null;
124 //alternate impl that uses a MIMEPart
125 private MIMEPart mimePart = null;
127 public AttachmentPartImpl() {
128 headers = new MimeHeaders();
129 }
131 public AttachmentPartImpl(MIMEPart part) {
132 headers = new MimeHeaders();
133 mimePart = part;
134 List<? extends com.sun.xml.internal.org.jvnet.mimepull.Header> hdrs = part.getAllHeaders();
135 for (com.sun.xml.internal.org.jvnet.mimepull.Header hd : hdrs) {
136 headers.addHeader(hd.getName(), hd.getValue());
137 }
138 }
140 public int getSize() throws SOAPException {
141 byte[] bytes;
142 if (mimePart != null) {
143 try {
144 return mimePart.read().available();
145 } catch (IOException e) {
146 return -1;
147 }
148 }
149 if ((rawContent == null) && (dataHandler == null))
150 return 0;
152 if (rawContent != null) {
153 try {
154 return rawContent.getSize();
155 } catch (Exception ex) {
156 log.log(
157 Level.SEVERE,
158 "SAAJ0573.soap.attachment.getrawbytes.ioexception",
159 new String[] { ex.getLocalizedMessage()});
160 throw new SOAPExceptionImpl("Raw InputStream Error: " + ex);
161 }
162 } else {
163 ByteOutputStream bout = new ByteOutputStream();
164 try {
165 dataHandler.writeTo(bout);
166 } catch (IOException ex) {
167 log.log(
168 Level.SEVERE,
169 "SAAJ0501.soap.data.handler.err",
170 new String[] { ex.getLocalizedMessage()});
171 throw new SOAPExceptionImpl("Data handler error: " + ex);
172 }
173 return bout.size();
174 }
175 }
177 public void clearContent() {
178 if (mimePart != null) {
179 mimePart.close();
180 mimePart = null;
181 }
182 dataHandler = null;
183 rawContent = null;
184 }
186 public Object getContent() throws SOAPException {
187 try {
188 if (mimePart != null) {
189 //return an inputstream
190 return mimePart.read();
191 }
192 if (dataHandler != null) {
193 return getDataHandler().getContent();
194 } else if (rawContent != null) {
195 return rawContent.getContent();
196 } else {
197 log.severe("SAAJ0572.soap.no.content.for.attachment");
198 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
199 }
200 } catch (Exception ex) {
201 log.log(Level.SEVERE, "SAAJ0575.soap.attachment.getcontent.exception", ex);
202 throw new SOAPExceptionImpl(ex.getLocalizedMessage());
203 }
204 }
206 public void setContent(Object object, String contentType)
207 throws IllegalArgumentException {
208 if (mimePart != null) {
209 mimePart.close();
210 mimePart = null;
211 }
212 DataHandler dh = new DataHandler(object, contentType);
214 setDataHandler(dh);
215 }
218 public DataHandler getDataHandler() throws SOAPException {
219 if (mimePart != null) {
220 //return an inputstream
221 return new DataHandler(new DataSource() {
223 public InputStream getInputStream() throws IOException {
224 return mimePart.read();
225 }
227 public OutputStream getOutputStream() throws IOException {
228 throw new UnsupportedOperationException("getOutputStream cannot be supported : You have enabled LazyAttachments Option");
229 }
231 public String getContentType() {
232 return mimePart.getContentType();
233 }
235 public String getName() {
236 return "MIMEPart Wrapper DataSource";
237 }
238 });
239 }
240 if (dataHandler == null) {
241 if (rawContent != null) {
242 return new DataHandler(new MimePartDataSource(rawContent));
243 }
244 log.severe("SAAJ0502.soap.no.handler.for.attachment");
245 throw new SOAPExceptionImpl("No data handler associated with this attachment");
246 }
247 return dataHandler;
248 }
250 public void setDataHandler(DataHandler dataHandler)
251 throws IllegalArgumentException {
252 if (mimePart != null) {
253 mimePart.close();
254 mimePart = null;
255 }
256 if (dataHandler == null) {
257 log.severe("SAAJ0503.soap.no.null.to.dataHandler");
258 throw new IllegalArgumentException("Null dataHandler argument to setDataHandler");
259 }
260 this.dataHandler = dataHandler;
261 rawContent = null;
263 if (log.isLoggable(Level.FINE))
264 log.log(Level.FINE, "SAAJ0580.soap.set.Content-Type",
265 new String[] { dataHandler.getContentType() });
266 setMimeHeader("Content-Type", dataHandler.getContentType());
267 }
269 public void removeAllMimeHeaders() {
270 headers.removeAllHeaders();
271 }
273 public void removeMimeHeader(String header) {
274 headers.removeHeader(header);
275 }
277 public String[] getMimeHeader(String name) {
278 return headers.getHeader(name);
279 }
281 public void setMimeHeader(String name, String value) {
282 headers.setHeader(name, value);
283 }
285 public void addMimeHeader(String name, String value) {
286 headers.addHeader(name, value);
287 }
289 public Iterator getAllMimeHeaders() {
290 return headers.getAllHeaders();
291 }
293 public Iterator getMatchingMimeHeaders(String[] names) {
294 return headers.getMatchingHeaders(names);
295 }
297 public Iterator getNonMatchingMimeHeaders(String[] names) {
298 return headers.getNonMatchingHeaders(names);
299 }
301 boolean hasAllHeaders(MimeHeaders hdrs) {
302 if (hdrs != null) {
303 Iterator i = hdrs.getAllHeaders();
304 while (i.hasNext()) {
305 MimeHeader hdr = (MimeHeader) i.next();
306 String[] values = headers.getHeader(hdr.getName());
307 boolean found = false;
309 if (values != null) {
310 for (int j = 0; j < values.length; j++)
311 if (hdr.getValue().equalsIgnoreCase(values[j])) {
312 found = true;
313 break;
314 }
315 }
317 if (!found) {
318 return false;
319 }
320 }
321 }
322 return true;
323 }
325 MimeBodyPart getMimePart() throws SOAPException {
326 try {
327 if (this.mimePart != null) {
328 return new MimeBodyPart(mimePart);
329 }
330 if (rawContent != null) {
331 copyMimeHeaders(headers, rawContent);
332 return rawContent;
333 }
335 MimeBodyPart envelope = new MimeBodyPart();
337 envelope.setDataHandler(dataHandler);
338 copyMimeHeaders(headers, envelope);
340 return envelope;
341 } catch (Exception ex) {
342 log.severe("SAAJ0504.soap.cannot.externalize.attachment");
343 throw new SOAPExceptionImpl("Unable to externalize attachment", ex);
344 }
345 }
347 public static void copyMimeHeaders(MimeHeaders headers, MimeBodyPart mbp)
348 throws SOAPException {
350 Iterator i = headers.getAllHeaders();
352 while (i.hasNext())
353 try {
354 MimeHeader mh = (MimeHeader) i.next();
356 mbp.setHeader(mh.getName(), mh.getValue());
357 } catch (Exception ex) {
358 log.severe("SAAJ0505.soap.cannot.copy.mime.hdr");
359 throw new SOAPExceptionImpl("Unable to copy MIME header", ex);
360 }
361 }
363 public static void copyMimeHeaders(MimeBodyPart mbp, AttachmentPartImpl ap)
364 throws SOAPException {
365 try {
366 List hdr = mbp.getAllHeaders();
367 int sz = hdr.size();
368 for( int i=0; i<sz; i++ ) {
369 Header h = (Header)hdr.get(i);
370 if(h.getName().equalsIgnoreCase("Content-Type"))
371 continue; // skip
372 ap.addMimeHeader(h.getName(), h.getValue());
373 }
374 } catch (Exception ex) {
375 log.severe("SAAJ0506.soap.cannot.copy.mime.hdrs.into.attachment");
376 throw new SOAPExceptionImpl(
377 "Unable to copy MIME headers into attachment",
378 ex);
379 }
380 }
382 public void setBase64Content(InputStream content, String contentType)
383 throws SOAPException {
385 if (mimePart != null) {
386 mimePart.close();
387 mimePart = null;
388 }
389 dataHandler = null;
390 InputStream decoded = null;
391 try {
392 decoded = MimeUtility.decode(content, "base64");
393 InternetHeaders hdrs = new InternetHeaders();
394 hdrs.setHeader("Content-Type", contentType);
395 //TODO: reading the entire attachment here is ineffcient. Somehow the MimeBodyPart
396 // Ctor with inputStream causes problems based on the InputStream
397 // has markSupported()==true
398 ByteOutputStream bos = new ByteOutputStream();
399 bos.write(decoded);
400 rawContent = new MimeBodyPart(hdrs, bos.getBytes(), bos.getCount());
401 setMimeHeader("Content-Type", contentType);
402 } catch (Exception e) {
403 log.log(Level.SEVERE, "SAAJ0578.soap.attachment.setbase64content.exception", e);
404 throw new SOAPExceptionImpl(e.getLocalizedMessage());
405 } finally {
406 try {
407 decoded.close();
408 } catch (IOException ex) {
409 throw new SOAPException(ex);
410 }
411 }
412 }
414 public InputStream getBase64Content() throws SOAPException {
415 InputStream stream;
416 if (mimePart != null) {
417 stream = mimePart.read();
418 } else if (rawContent != null) {
419 try {
420 stream = rawContent.getInputStream();
421 } catch (Exception e) {
422 log.log(Level.SEVERE,"SAAJ0579.soap.attachment.getbase64content.exception", e);
423 throw new SOAPExceptionImpl(e.getLocalizedMessage());
424 }
425 } else if (dataHandler != null) {
426 try {
427 stream = dataHandler.getInputStream();
428 } catch (IOException e) {
429 log.severe("SAAJ0574.soap.attachment.datahandler.ioexception");
430 throw new SOAPExceptionImpl("DataHandler error" + e);
431 }
432 } else {
433 log.severe("SAAJ0572.soap.no.content.for.attachment");
434 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
435 }
437 //TODO: Write a BASE64EncoderInputStream instead,
438 // this code below is inefficient
439 // where we are trying to read the whole attachment first
440 int len;
441 int size = 1024;
442 byte [] buf;
443 if (stream != null) {
444 try {
445 ByteArrayOutputStream bos = new ByteArrayOutputStream(size);
446 //TODO: try and optimize this on the same lines as
447 // ByteOutputStream : to eliminate the temp buffer here
448 OutputStream ret = MimeUtility.encode(bos, "base64");
449 buf = new byte[size];
450 while ((len = stream.read(buf, 0, size)) != -1) {
451 ret.write(buf, 0, len);
452 }
453 ret.flush();
454 buf = bos.toByteArray();
455 return new ByteArrayInputStream(buf);
456 } catch (Exception e) {
457 // throw new SOAPException
458 log.log(Level.SEVERE,"SAAJ0579.soap.attachment.getbase64content.exception", e);
459 throw new SOAPExceptionImpl(e.getLocalizedMessage());
460 } finally {
461 try {
462 stream.close();
463 } catch (IOException ex) {
464 //close the stream
465 }
466 }
467 } else {
468 //throw new SOAPException
469 log.log(Level.SEVERE,"SAAJ0572.soap.no.content.for.attachment");
470 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
471 }
472 }
474 public void setRawContent(InputStream content, String contentType)
475 throws SOAPException {
476 if (mimePart != null) {
477 mimePart.close();
478 mimePart = null;
479 }
480 dataHandler = null;
481 try {
482 InternetHeaders hdrs = new InternetHeaders();
483 hdrs.setHeader("Content-Type", contentType);
484 //TODO: reading the entire attachment here is ineffcient. Somehow the MimeBodyPart
485 // Ctor with inputStream causes problems based on whether the InputStream has
486 // markSupported()==true or false
487 ByteOutputStream bos = new ByteOutputStream();
488 bos.write(content);
489 rawContent = new MimeBodyPart(hdrs, bos.getBytes(), bos.getCount());
490 setMimeHeader("Content-Type", contentType);
491 } catch (Exception e) {
492 log.log(Level.SEVERE, "SAAJ0576.soap.attachment.setrawcontent.exception", e);
493 throw new SOAPExceptionImpl(e.getLocalizedMessage());
494 } finally {
495 try {
496 content.close();
497 } catch (IOException ex) {
498 throw new SOAPException(ex);
499 }
500 }
501 }
503 /*
504 public void setRawContentBytes(byte[] content, String contentType)
505 throws SOAPException {
506 if (content == null) {
507 throw new SOAPExceptionImpl("Null content passed to setRawContentBytes");
508 }
509 dataHandler = null;
510 try {
511 InternetHeaders hdrs = new InternetHeaders();
512 hdrs.setHeader("Content-Type", contentType);
513 rawContent = new MimeBodyPart(hdrs, content, content.length);
514 setMimeHeader("Content-Type", contentType);
515 } catch (Exception e) {
516 log.log(Level.SEVERE, "SAAJ0576.soap.attachment.setrawcontent.exception", e);
517 throw new SOAPExceptionImpl(e.getLocalizedMessage());
518 }
519 } */
521 public void setRawContentBytes(
522 byte[] content, int off, int len, String contentType)
523 throws SOAPException {
524 if (mimePart != null) {
525 mimePart.close();
526 mimePart = null;
527 }
528 if (content == null) {
529 throw new SOAPExceptionImpl("Null content passed to setRawContentBytes");
530 }
531 dataHandler = null;
532 try {
533 InternetHeaders hdrs = new InternetHeaders();
534 hdrs.setHeader("Content-Type", contentType);
535 rawContent = new MimeBodyPart(hdrs, content, off, len);
536 setMimeHeader("Content-Type", contentType);
537 } catch (Exception e) {
538 log.log(Level.SEVERE,
539 "SAAJ0576.soap.attachment.setrawcontent.exception", e);
540 throw new SOAPExceptionImpl(e.getLocalizedMessage());
541 }
542 }
544 public InputStream getRawContent() throws SOAPException {
545 if (mimePart != null) {
546 return mimePart.read();
547 }
548 if (rawContent != null) {
549 try {
550 return rawContent.getInputStream();
551 } catch (Exception e) {
552 log.log(Level.SEVERE,"SAAJ0577.soap.attachment.getrawcontent.exception", e);
553 throw new SOAPExceptionImpl(e.getLocalizedMessage());
554 }
555 } else if (dataHandler != null) {
556 try {
557 return dataHandler.getInputStream();
558 } catch (IOException e) {
559 log.severe("SAAJ0574.soap.attachment.datahandler.ioexception");
560 throw new SOAPExceptionImpl("DataHandler error" + e);
561 }
562 } else {
563 log.severe("SAAJ0572.soap.no.content.for.attachment");
564 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
565 }
566 }
568 public byte[] getRawContentBytes() throws SOAPException {
569 InputStream ret;
570 if (mimePart != null) {
571 try {
572 ret = mimePart.read();
573 return ASCIIUtility.getBytes(ret);
574 } catch (IOException ex) {
575 log.log(Level.SEVERE,"SAAJ0577.soap.attachment.getrawcontent.exception", ex);
576 throw new SOAPExceptionImpl(ex);
577 }
578 }
579 if (rawContent != null) {
580 try {
581 ret = rawContent.getInputStream();
582 return ASCIIUtility.getBytes(ret);
583 } catch (Exception e) {
584 log.log(Level.SEVERE,"SAAJ0577.soap.attachment.getrawcontent.exception", e);
585 throw new SOAPExceptionImpl(e);
586 }
587 } else if (dataHandler != null) {
588 try {
589 ret = dataHandler.getInputStream();
590 return ASCIIUtility.getBytes(ret);
591 } catch (IOException e) {
592 log.severe("SAAJ0574.soap.attachment.datahandler.ioexception");
593 throw new SOAPExceptionImpl("DataHandler error" + e);
594 }
595 } else {
596 log.severe("SAAJ0572.soap.no.content.for.attachment");
597 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
598 }
599 }
601 // attachments are equal if they are the same reference
602 public boolean equals(Object o) {
603 return (this == o);
604 }
606 // In JDK 8 we get a warning if we implement equals() but not hashCode().
607 // There is no intuitive value for this, the default one in Object is fine.
608 public int hashCode() {
609 return super.hashCode();
610 }
612 public MimeHeaders getMimeHeaders() {
613 return headers;
614 }
616 }