Mon, 04 May 2009 21:10:41 -0700
6658158: Mutable statics in SAAJ (findbugs)
6658163: txw2.DatatypeWriter.BUILDIN is a mutable static (findbugs)
Reviewed-by: darcy
1 /*
2 * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25 /*
26 * $Id: AttachmentPartImpl.java,v 1.1.1.1.2.1 2007/11/27 07:19:29 kumarjayanti Exp $
27 * $Revision: 1.1.1.1.2.1 $
28 * $Date: 2007/11/27 07:19:29 $
29 */
32 package com.sun.xml.internal.messaging.saaj.soap;
34 import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl;
36 import com.sun.xml.internal.messaging.saaj.packaging.mime.util.ASCIIUtility;
38 import com.sun.xml.internal.messaging.saaj.packaging.mime.Header;
39 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimePartDataSource;
40 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.InternetHeaders;
41 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeBodyPart;
42 import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility;
43 import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
44 import com.sun.xml.internal.messaging.saaj.util.LogDomainConstants;
46 import javax.activation.CommandMap;
47 import javax.activation.DataHandler;
48 import javax.activation.MailcapCommandMap;
49 import javax.xml.soap.AttachmentPart;
50 import javax.xml.soap.MimeHeader;
51 import javax.xml.soap.MimeHeaders;
52 import javax.xml.soap.SOAPException;
53 import java.io.IOException;
54 import java.io.InputStream;
55 import java.io.ByteArrayOutputStream;
56 import java.io.ByteArrayInputStream;
57 import java.io.OutputStream;
58 import java.util.Iterator;
59 import java.util.List;
60 import java.util.logging.Level;
61 import java.util.logging.Logger;
63 import javax.activation.*;
64 import javax.xml.soap.*;
66 /**
67 * Implementation of attachments.
68 *
69 * @author Anil Vijendran (akv@eng.sun.com)
70 */
71 public class AttachmentPartImpl extends AttachmentPart {
73 protected static final Logger log =
74 Logger.getLogger(LogDomainConstants.SOAP_DOMAIN,
75 "com.sun.xml.internal.messaging.saaj.soap.LocalStrings");
77 static {
78 try {
79 CommandMap map = CommandMap.getDefaultCommandMap();
80 if (map instanceof MailcapCommandMap) {
81 MailcapCommandMap mailMap = (MailcapCommandMap) map;
82 String hndlrStr = ";;x-java-content-handler=";
83 mailMap.addMailcap(
84 "text/xml"
85 + hndlrStr
86 + "com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler");
87 mailMap.addMailcap(
88 "application/xml"
89 + hndlrStr
90 + "com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler");
91 mailMap.addMailcap(
92 "application/fastinfoset"
93 + hndlrStr
94 + "com.sun.xml.internal.messaging.saaj.soap.FastInfosetDataContentHandler");
95 /* Image DataContentHandler handles all image types
96 mailMap.addMailcap(
97 "image/jpeg"
98 + hndlrStr
99 + "com.sun.xml.internal.messaging.saaj.soap.JpegDataContentHandler");
100 mailMap.addMailcap(
101 "image/gif"
102 + hndlrStr
103 + "com.sun.xml.internal.messaging.saaj.soap.GifDataContentHandler");*/
104 /*mailMap.addMailcap(
105 "multipart/*"
106 + hndlrStr
107 + "com.sun.xml.internal.messaging.saaj.soap.MultipartDataContentHandler");*/
108 mailMap.addMailcap(
109 "image/*"
110 + hndlrStr
111 + "com.sun.xml.internal.messaging.saaj.soap.ImageDataContentHandler");
112 mailMap.addMailcap(
113 "text/plain"
114 + hndlrStr
115 + "com.sun.xml.internal.messaging.saaj.soap.StringDataContentHandler");
116 } else {
117 throw new SOAPExceptionImpl("Default CommandMap is not a MailcapCommandMap");
118 }
119 } catch (Throwable t) {
120 log.log(
121 Level.SEVERE,
122 "SAAJ0508.soap.cannot.register.handlers",
123 t);
124 if (t instanceof RuntimeException) {
125 throw (RuntimeException) t;
126 } else {
127 throw new RuntimeException(t.getLocalizedMessage());
128 }
129 }
130 };
132 private final MimeHeaders headers;
133 private MimeBodyPart rawContent = null;
134 private DataHandler dataHandler = null;
136 public AttachmentPartImpl() {
137 headers = new MimeHeaders();
138 }
140 public int getSize() throws SOAPException {
141 byte[] bytes;
143 if ((rawContent == null) && (dataHandler == null))
144 return 0;
146 if (rawContent != null) {
147 try {
148 return rawContent.getSize();
149 } catch (Exception ex) {
150 log.log(
151 Level.SEVERE,
152 "SAAJ0573.soap.attachment.getrawbytes.ioexception",
153 new String[] { ex.getLocalizedMessage()});
154 throw new SOAPExceptionImpl("Raw InputStream Error: " + ex);
155 }
156 } else {
157 ByteOutputStream bout = new ByteOutputStream();
158 try {
159 dataHandler.writeTo(bout);
160 } catch (IOException ex) {
161 log.log(
162 Level.SEVERE,
163 "SAAJ0501.soap.data.handler.err",
164 new String[] { ex.getLocalizedMessage()});
165 throw new SOAPExceptionImpl("Data handler error: " + ex);
166 }
167 bytes = bout.getBytes();
168 if (bytes != null)
169 return bytes.length;
170 }
171 return -1;
172 }
174 public void clearContent() {
175 dataHandler = null;
176 rawContent = null;
177 }
179 public Object getContent() throws SOAPException {
180 try {
181 if (dataHandler != null) {
182 return getDataHandler().getContent();
183 } else if (rawContent != null) {
184 return rawContent.getContent();
185 } else {
186 log.severe("SAAJ0572.soap.no.content.for.attachment");
187 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
188 }
189 } catch (Exception ex) {
190 log.log(Level.SEVERE, "SAAJ0575.soap.attachment.getcontent.exception", ex);
191 throw new SOAPExceptionImpl(ex.getLocalizedMessage());
192 }
193 }
195 public void setContent(Object object, String contentType)
196 throws IllegalArgumentException {
197 DataHandler dh = new DataHandler(object, contentType);
199 setDataHandler(dh);
200 }
203 public DataHandler getDataHandler() throws SOAPException {
204 if (dataHandler == null) {
205 if (rawContent != null) {
206 return new DataHandler(new MimePartDataSource(rawContent));
207 }
208 log.severe("SAAJ0502.soap.no.handler.for.attachment");
209 throw new SOAPExceptionImpl("No data handler associated with this attachment");
210 }
211 return dataHandler;
212 }
214 public void setDataHandler(DataHandler dataHandler)
215 throws IllegalArgumentException {
216 if (dataHandler == null) {
217 log.severe("SAAJ0503.soap.no.null.to.dataHandler");
218 throw new IllegalArgumentException("Null dataHandler argument to setDataHandler");
219 }
220 this.dataHandler = dataHandler;
221 rawContent = null;
223 log.log(
224 Level.FINE,
225 "SAAJ0580.soap.set.Content-Type",
226 new String[] { dataHandler.getContentType()});
227 setMimeHeader("Content-Type", dataHandler.getContentType());
228 }
230 public void removeAllMimeHeaders() {
231 headers.removeAllHeaders();
232 }
234 public void removeMimeHeader(String header) {
235 headers.removeHeader(header);
236 }
238 public String[] getMimeHeader(String name) {
239 return headers.getHeader(name);
240 }
242 public void setMimeHeader(String name, String value) {
243 headers.setHeader(name, value);
244 }
246 public void addMimeHeader(String name, String value) {
247 headers.addHeader(name, value);
248 }
250 public Iterator getAllMimeHeaders() {
251 return headers.getAllHeaders();
252 }
254 public Iterator getMatchingMimeHeaders(String[] names) {
255 return headers.getMatchingHeaders(names);
256 }
258 public Iterator getNonMatchingMimeHeaders(String[] names) {
259 return headers.getNonMatchingHeaders(names);
260 }
262 boolean hasAllHeaders(MimeHeaders hdrs) {
263 if (hdrs != null) {
264 Iterator i = hdrs.getAllHeaders();
265 while (i.hasNext()) {
266 MimeHeader hdr = (MimeHeader) i.next();
267 String[] values = headers.getHeader(hdr.getName());
268 boolean found = false;
270 if (values != null) {
271 for (int j = 0; j < values.length; j++)
272 if (hdr.getValue().equalsIgnoreCase(values[j])) {
273 found = true;
274 break;
275 }
276 }
278 if (!found) {
279 return false;
280 }
281 }
282 }
283 return true;
284 }
286 MimeBodyPart getMimePart() throws SOAPException {
287 try {
288 if (rawContent != null) {
289 copyMimeHeaders(headers, rawContent);
290 return rawContent;
291 }
293 MimeBodyPart envelope = new MimeBodyPart();
295 envelope.setDataHandler(dataHandler);
296 copyMimeHeaders(headers, envelope);
298 return envelope;
299 } catch (Exception ex) {
300 log.severe("SAAJ0504.soap.cannot.externalize.attachment");
301 throw new SOAPExceptionImpl("Unable to externalize attachment", ex);
302 }
303 }
305 public static void copyMimeHeaders(MimeHeaders headers, MimeBodyPart mbp)
306 throws SOAPException {
308 Iterator i = headers.getAllHeaders();
310 while (i.hasNext())
311 try {
312 MimeHeader mh = (MimeHeader) i.next();
314 mbp.setHeader(mh.getName(), mh.getValue());
315 } catch (Exception ex) {
316 log.severe("SAAJ0505.soap.cannot.copy.mime.hdr");
317 throw new SOAPExceptionImpl("Unable to copy MIME header", ex);
318 }
319 }
321 public static void copyMimeHeaders(MimeBodyPart mbp, AttachmentPartImpl ap)
322 throws SOAPException {
323 try {
324 List hdr = mbp.getAllHeaders();
325 int sz = hdr.size();
326 for( int i=0; i<sz; i++ ) {
327 Header h = (Header)hdr.get(i);
328 if(h.getName().equalsIgnoreCase("Content-Type"))
329 continue; // skip
330 ap.addMimeHeader(h.getName(), h.getValue());
331 }
332 } catch (Exception ex) {
333 log.severe("SAAJ0506.soap.cannot.copy.mime.hdrs.into.attachment");
334 throw new SOAPExceptionImpl(
335 "Unable to copy MIME headers into attachment",
336 ex);
337 }
338 }
340 public void setBase64Content(InputStream content, String contentType)
341 throws SOAPException {
342 dataHandler = null;
343 try {
344 InputStream decoded = MimeUtility.decode(content, "base64");
345 InternetHeaders hdrs = new InternetHeaders();
346 hdrs.setHeader("Content-Type", contentType);
347 //TODO: reading the entire attachment here is ineffcient. Somehow the MimeBodyPart
348 // Ctor with inputStream causes problems based on the InputStream
349 // has markSupported()==true
350 ByteOutputStream bos = new ByteOutputStream();
351 bos.write(decoded);
352 rawContent = new MimeBodyPart(hdrs, bos.getBytes(), bos.getCount());
353 setMimeHeader("Content-Type", contentType);
354 } catch (Exception e) {
355 log.log(Level.SEVERE, "SAAJ0578.soap.attachment.setbase64content.exception", e);
356 throw new SOAPExceptionImpl(e.getLocalizedMessage());
357 }
358 }
360 public InputStream getBase64Content() throws SOAPException {
361 InputStream stream;
362 if (rawContent != null) {
363 try {
364 stream = rawContent.getInputStream();
365 } catch (Exception e) {
366 log.log(Level.SEVERE,"SAAJ0579.soap.attachment.getbase64content.exception", e);
367 throw new SOAPExceptionImpl(e.getLocalizedMessage());
368 }
369 } else if (dataHandler != null) {
370 try {
371 stream = dataHandler.getInputStream();
372 } catch (IOException e) {
373 log.severe("SAAJ0574.soap.attachment.datahandler.ioexception");
374 throw new SOAPExceptionImpl("DataHandler error" + e);
375 }
376 } else {
377 log.severe("SAAJ0572.soap.no.content.for.attachment");
378 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
379 }
381 //TODO: Write a BASE64EncoderInputStream instead,
382 // this code below is inefficient
383 // where we are trying to read the whole attachment first
384 int len;
385 int size = 1024;
386 byte [] buf;
387 if (stream != null) {
388 try {
389 ByteArrayOutputStream bos = new ByteArrayOutputStream(size);
390 //TODO: try and optimize this on the same lines as
391 // ByteOutputStream : to eliminate the temp buffer here
392 OutputStream ret = MimeUtility.encode(bos, "base64");
393 buf = new byte[size];
394 while ((len = stream.read(buf, 0, size)) != -1) {
395 ret.write(buf, 0, len);
396 }
397 ret.flush();
398 buf = bos.toByteArray();
399 return new ByteArrayInputStream(buf);
400 } catch (Exception e) {
401 // throw new SOAPException
402 log.log(Level.SEVERE,"SAAJ0579.soap.attachment.getbase64content.exception", e);
403 throw new SOAPExceptionImpl(e.getLocalizedMessage());
404 }
405 } else {
406 //throw new SOAPException
407 log.log(Level.SEVERE,"SAAJ0572.soap.no.content.for.attachment");
408 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
409 }
410 }
412 public void setRawContent(InputStream content, String contentType)
413 throws SOAPException {
414 dataHandler = null;
415 try {
416 InternetHeaders hdrs = new InternetHeaders();
417 hdrs.setHeader("Content-Type", contentType);
418 //TODO: reading the entire attachment here is ineffcient. Somehow the MimeBodyPart
419 // Ctor with inputStream causes problems based on whether the InputStream has
420 // markSupported()==true or false
421 ByteOutputStream bos = new ByteOutputStream();
422 bos.write(content);
423 rawContent = new MimeBodyPart(hdrs, bos.getBytes(), bos.getCount());
424 setMimeHeader("Content-Type", contentType);
425 } catch (Exception e) {
426 log.log(Level.SEVERE, "SAAJ0576.soap.attachment.setrawcontent.exception", e);
427 throw new SOAPExceptionImpl(e.getLocalizedMessage());
428 }
429 }
431 /*
432 public void setRawContentBytes(byte[] content, String contentType)
433 throws SOAPException {
434 if (content == null) {
435 throw new SOAPExceptionImpl("Null content passed to setRawContentBytes");
436 }
437 dataHandler = null;
438 try {
439 InternetHeaders hdrs = new InternetHeaders();
440 hdrs.setHeader("Content-Type", contentType);
441 rawContent = new MimeBodyPart(hdrs, content, content.length);
442 setMimeHeader("Content-Type", contentType);
443 } catch (Exception e) {
444 log.log(Level.SEVERE, "SAAJ0576.soap.attachment.setrawcontent.exception", e);
445 throw new SOAPExceptionImpl(e.getLocalizedMessage());
446 }
447 } */
449 public void setRawContentBytes(
450 byte[] content, int off, int len, String contentType)
451 throws SOAPException {
452 if (content == null) {
453 throw new SOAPExceptionImpl("Null content passed to setRawContentBytes");
454 }
455 dataHandler = null;
456 try {
457 InternetHeaders hdrs = new InternetHeaders();
458 hdrs.setHeader("Content-Type", contentType);
459 rawContent = new MimeBodyPart(hdrs, content, off, len);
460 setMimeHeader("Content-Type", contentType);
461 } catch (Exception e) {
462 log.log(Level.SEVERE,
463 "SAAJ0576.soap.attachment.setrawcontent.exception", e);
464 throw new SOAPExceptionImpl(e.getLocalizedMessage());
465 }
466 }
468 public InputStream getRawContent() throws SOAPException {
469 if (rawContent != null) {
470 try {
471 return rawContent.getInputStream();
472 } catch (Exception e) {
473 log.log(Level.SEVERE,"SAAJ0577.soap.attachment.getrawcontent.exception", e);
474 throw new SOAPExceptionImpl(e.getLocalizedMessage());
475 }
476 } else if (dataHandler != null) {
477 try {
478 return dataHandler.getInputStream();
479 } catch (IOException e) {
480 log.severe("SAAJ0574.soap.attachment.datahandler.ioexception");
481 throw new SOAPExceptionImpl("DataHandler error" + e);
482 }
483 } else {
484 log.severe("SAAJ0572.soap.no.content.for.attachment");
485 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
486 }
487 }
489 //TODO: investigate size differences in mime.AttachImageTest
490 public byte[] getRawContentBytes() throws SOAPException {
491 InputStream ret;
492 if (rawContent != null) {
493 try {
494 ret = rawContent.getInputStream();
495 return ASCIIUtility.getBytes(ret);
496 } catch (Exception e) {
497 log.log(Level.SEVERE,"SAAJ0577.soap.attachment.getrawcontent.exception", e);
498 throw new SOAPExceptionImpl(e.getLocalizedMessage());
499 }
500 } else if (dataHandler != null) {
501 try {
502 ret = dataHandler.getInputStream();
503 return ASCIIUtility.getBytes(ret);
504 } catch (IOException e) {
505 log.severe("SAAJ0574.soap.attachment.datahandler.ioexception");
506 throw new SOAPExceptionImpl("DataHandler error" + e);
507 }
508 } else {
509 log.severe("SAAJ0572.soap.no.content.for.attachment");
510 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
511 }
512 }
514 // attachments are equal if they are the same reference
515 public boolean equals(Object o) {
516 return (this == o);
517 }
519 public MimeHeaders getMimeHeaders() {
520 return headers;
521 }
523 }