src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/soap/AttachmentPartImpl.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 545
ce46e4af2b1d
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     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     private final MimeHeaders headers;
    66     private MimeBodyPart rawContent = null;
    67     private DataHandler dataHandler = null;
    69     //alternate impl that uses a MIMEPart
    70     private MIMEPart mimePart = null;
    72     public AttachmentPartImpl() {
    73         headers = new MimeHeaders();
    75         // initialization from here should cover most of cases;
    76         // if not, it would be necessary to call
    77         //   AttachmentPartImpl.initializeJavaActivationHandlers()
    78         // explicitly by programmer
    79         initializeJavaActivationHandlers();
    80     }
    82     public AttachmentPartImpl(MIMEPart part) {
    83         headers = new MimeHeaders();
    84         mimePart = part;
    85         List<? extends com.sun.xml.internal.org.jvnet.mimepull.Header> hdrs = part.getAllHeaders();
    86         for (com.sun.xml.internal.org.jvnet.mimepull.Header hd : hdrs) {
    87             headers.addHeader(hd.getName(), hd.getValue());
    88         }
    89     }
    91     public int getSize() throws SOAPException {
    92         byte[] bytes;
    93         if (mimePart != null) {
    94             try {
    95                 return mimePart.read().available();
    96             } catch (IOException e) {
    97                 return -1;
    98             }
    99         }
   100         if ((rawContent == null) && (dataHandler == null))
   101             return 0;
   103         if (rawContent != null) {
   104             try {
   105                 return rawContent.getSize();
   106             } catch (Exception ex) {
   107                 log.log(
   108                     Level.SEVERE,
   109                     "SAAJ0573.soap.attachment.getrawbytes.ioexception",
   110                     new String[] { ex.getLocalizedMessage()});
   111                 throw new SOAPExceptionImpl("Raw InputStream Error: " + ex);
   112             }
   113         } else {
   114             ByteOutputStream bout = new ByteOutputStream();
   115             try {
   116                 dataHandler.writeTo(bout);
   117             } catch (IOException ex) {
   118                 log.log(
   119                     Level.SEVERE,
   120                     "SAAJ0501.soap.data.handler.err",
   121                     new String[] { ex.getLocalizedMessage()});
   122                 throw new SOAPExceptionImpl("Data handler error: " + ex);
   123             }
   124             return bout.size();
   125         }
   126     }
   128     public void clearContent() {
   129         if (mimePart != null) {
   130             mimePart.close();
   131             mimePart = null;
   132         }
   133         dataHandler = null;
   134         rawContent = null;
   135     }
   137     public Object getContent() throws SOAPException {
   138         try {
   139             if (mimePart != null) {
   140                 //return an inputstream
   141                 return mimePart.read();
   142             }
   143             if (dataHandler != null) {
   144                 return getDataHandler().getContent();
   145             } else if (rawContent != null) {
   146                 return rawContent.getContent();
   147             } else {
   148                 log.severe("SAAJ0572.soap.no.content.for.attachment");
   149                 throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
   150             }
   151         } catch (Exception ex) {
   152             log.log(Level.SEVERE, "SAAJ0575.soap.attachment.getcontent.exception", ex);
   153             throw new SOAPExceptionImpl(ex.getLocalizedMessage());
   154         }
   155     }
   157     public void setContent(Object object, String contentType)
   158         throws IllegalArgumentException {
   159         if (mimePart != null) {
   160             mimePart.close();
   161             mimePart = null;
   162         }
   163         DataHandler dh = new DataHandler(object, contentType);
   165         setDataHandler(dh);
   166     }
   169     public DataHandler getDataHandler() throws SOAPException {
   170         if (mimePart != null) {
   171             //return an inputstream
   172             return new DataHandler(new DataSource() {
   174                 public InputStream getInputStream() throws IOException {
   175                     return mimePart.read();
   176                 }
   178                 public OutputStream getOutputStream() throws IOException {
   179                     throw new UnsupportedOperationException("getOutputStream cannot be supported : You have enabled LazyAttachments Option");
   180                 }
   182                 public String getContentType() {
   183                     return mimePart.getContentType();
   184                 }
   186                 public String getName() {
   187                     return "MIMEPart Wrapper DataSource";
   188                 }
   189             });
   190         }
   191         if (dataHandler == null) {
   192             if (rawContent != null) {
   193                 return new DataHandler(new MimePartDataSource(rawContent));
   194             }
   195             log.severe("SAAJ0502.soap.no.handler.for.attachment");
   196             throw new SOAPExceptionImpl("No data handler associated with this attachment");
   197         }
   198         return dataHandler;
   199     }
   201     public void setDataHandler(DataHandler dataHandler)
   202         throws IllegalArgumentException {
   203         if (mimePart != null) {
   204             mimePart.close();
   205             mimePart = null;
   206         }
   207         if (dataHandler == null) {
   208             log.severe("SAAJ0503.soap.no.null.to.dataHandler");
   209             throw new IllegalArgumentException("Null dataHandler argument to setDataHandler");
   210         }
   211         this.dataHandler = dataHandler;
   212         rawContent = null;
   214         if (log.isLoggable(Level.FINE))
   215             log.log(Level.FINE, "SAAJ0580.soap.set.Content-Type",
   216                     new String[] { dataHandler.getContentType() });
   217         setMimeHeader("Content-Type", dataHandler.getContentType());
   218     }
   220     public void removeAllMimeHeaders() {
   221         headers.removeAllHeaders();
   222     }
   224     public void removeMimeHeader(String header) {
   225         headers.removeHeader(header);
   226     }
   228     public String[] getMimeHeader(String name) {
   229         return headers.getHeader(name);
   230     }
   232     public void setMimeHeader(String name, String value) {
   233         headers.setHeader(name, value);
   234     }
   236     public void addMimeHeader(String name, String value) {
   237         headers.addHeader(name, value);
   238     }
   240     public Iterator getAllMimeHeaders() {
   241         return headers.getAllHeaders();
   242     }
   244     public Iterator getMatchingMimeHeaders(String[] names) {
   245         return headers.getMatchingHeaders(names);
   246     }
   248     public Iterator getNonMatchingMimeHeaders(String[] names) {
   249         return headers.getNonMatchingHeaders(names);
   250     }
   252     boolean hasAllHeaders(MimeHeaders hdrs) {
   253         if (hdrs != null) {
   254             Iterator i = hdrs.getAllHeaders();
   255             while (i.hasNext()) {
   256                 MimeHeader hdr = (MimeHeader) i.next();
   257                 String[] values = headers.getHeader(hdr.getName());
   258                 boolean found = false;
   260                 if (values != null) {
   261                     for (int j = 0; j < values.length; j++)
   262                         if (hdr.getValue().equalsIgnoreCase(values[j])) {
   263                             found = true;
   264                             break;
   265                         }
   266                 }
   268                 if (!found) {
   269                     return false;
   270                 }
   271             }
   272         }
   273         return true;
   274     }
   276     MimeBodyPart getMimePart() throws SOAPException {
   277         try {
   278             if (this.mimePart != null) {
   279                 return new MimeBodyPart(mimePart);
   280             }
   281             if (rawContent != null) {
   282                 copyMimeHeaders(headers, rawContent);
   283                 return rawContent;
   284             }
   286             MimeBodyPart envelope = new MimeBodyPart();
   288             envelope.setDataHandler(dataHandler);
   289             copyMimeHeaders(headers, envelope);
   291             return envelope;
   292         } catch (Exception ex) {
   293             log.severe("SAAJ0504.soap.cannot.externalize.attachment");
   294             throw new SOAPExceptionImpl("Unable to externalize attachment", ex);
   295         }
   296     }
   298     public static void copyMimeHeaders(MimeHeaders headers, MimeBodyPart mbp)
   299         throws SOAPException {
   301         Iterator i = headers.getAllHeaders();
   303         while (i.hasNext())
   304             try {
   305                 MimeHeader mh = (MimeHeader) i.next();
   307                 mbp.setHeader(mh.getName(), mh.getValue());
   308             } catch (Exception ex) {
   309                 log.severe("SAAJ0505.soap.cannot.copy.mime.hdr");
   310                 throw new SOAPExceptionImpl("Unable to copy MIME header", ex);
   311             }
   312     }
   314     public static void copyMimeHeaders(MimeBodyPart mbp, AttachmentPartImpl ap)
   315         throws SOAPException {
   316         try {
   317             List hdr = mbp.getAllHeaders();
   318             int sz = hdr.size();
   319             for( int i=0; i<sz; i++ ) {
   320                 Header h = (Header)hdr.get(i);
   321                 if(h.getName().equalsIgnoreCase("Content-Type"))
   322                     continue;   // skip
   323                 ap.addMimeHeader(h.getName(), h.getValue());
   324             }
   325         } catch (Exception ex) {
   326             log.severe("SAAJ0506.soap.cannot.copy.mime.hdrs.into.attachment");
   327             throw new SOAPExceptionImpl(
   328                 "Unable to copy MIME headers into attachment",
   329                 ex);
   330         }
   331     }
   333     public  void setBase64Content(InputStream content, String contentType)
   334         throws SOAPException {
   336         if (mimePart != null) {
   337             mimePart.close();
   338             mimePart = null;
   339         }
   340         dataHandler = null;
   341         InputStream decoded = null;
   342         try {
   343             decoded = MimeUtility.decode(content, "base64");
   344             InternetHeaders hdrs = new InternetHeaders();
   345             hdrs.setHeader("Content-Type", contentType);
   346             //TODO: reading the entire attachment here is ineffcient. Somehow the MimeBodyPart
   347             // Ctor with inputStream causes problems based on the InputStream
   348             // has markSupported()==true
   349             ByteOutputStream bos = new ByteOutputStream();
   350             bos.write(decoded);
   351             rawContent = new MimeBodyPart(hdrs, bos.getBytes(), bos.getCount());
   352             setMimeHeader("Content-Type", contentType);
   353         } catch (Exception e) {
   354             log.log(Level.SEVERE, "SAAJ0578.soap.attachment.setbase64content.exception", e);
   355             throw new SOAPExceptionImpl(e.getLocalizedMessage());
   356         } finally {
   357             try {
   358                     decoded.close();
   359             } catch (IOException ex) {
   360                 throw new SOAPException(ex);
   361             }
   362         }
   363     }
   365     public  InputStream getBase64Content() throws SOAPException {
   366         InputStream stream;
   367         if (mimePart != null) {
   368             stream = mimePart.read();
   369         } else if (rawContent != null) {
   370             try {
   371                  stream = rawContent.getInputStream();
   372             } catch (Exception e) {
   373                 log.log(Level.SEVERE,"SAAJ0579.soap.attachment.getbase64content.exception", e);
   374                 throw new SOAPExceptionImpl(e.getLocalizedMessage());
   375             }
   376         } else if (dataHandler != null) {
   377             try {
   378                 stream = dataHandler.getInputStream();
   379             } catch (IOException e) {
   380                 log.severe("SAAJ0574.soap.attachment.datahandler.ioexception");
   381                 throw new SOAPExceptionImpl("DataHandler error" + e);
   382             }
   383         } else {
   384             log.severe("SAAJ0572.soap.no.content.for.attachment");
   385             throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
   386         }
   388         //TODO: Write a BASE64EncoderInputStream instead,
   389         // this code below is inefficient
   390         // where we are trying to read the whole attachment first
   391         int len;
   392         int size = 1024;
   393         byte [] buf;
   394         if (stream != null) {
   395             try {
   396                 ByteArrayOutputStream bos = new ByteArrayOutputStream(size);
   397                 //TODO: try and optimize this on the same lines as
   398                 // ByteOutputStream : to eliminate the temp buffer here
   399                 OutputStream ret = MimeUtility.encode(bos, "base64");
   400                 buf = new byte[size];
   401                 while ((len = stream.read(buf, 0, size)) != -1) {
   402                     ret.write(buf, 0, len);
   403                 }
   404                 ret.flush();
   405                 buf = bos.toByteArray();
   406                 return new ByteArrayInputStream(buf);
   407             } catch (Exception e) {
   408                 // throw new SOAPException
   409                 log.log(Level.SEVERE,"SAAJ0579.soap.attachment.getbase64content.exception", e);
   410                 throw new SOAPExceptionImpl(e.getLocalizedMessage());
   411             } finally {
   412                 try {
   413                     stream.close();
   414                 } catch (IOException ex) {
   415                   //close the stream
   416                 }
   417             }
   418         } else {
   419           //throw  new SOAPException
   420           log.log(Level.SEVERE,"SAAJ0572.soap.no.content.for.attachment");
   421           throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
   422         }
   423     }
   425     public void setRawContent(InputStream content, String contentType)
   426         throws SOAPException {
   427         if (mimePart != null) {
   428             mimePart.close();
   429             mimePart = null;
   430         }
   431         dataHandler = null;
   432         try {
   433             InternetHeaders hdrs = new InternetHeaders();
   434             hdrs.setHeader("Content-Type", contentType);
   435             //TODO: reading the entire attachment here is ineffcient. Somehow the MimeBodyPart
   436             // Ctor with inputStream causes problems based on whether the InputStream has
   437             // markSupported()==true or false
   438             ByteOutputStream bos = new ByteOutputStream();
   439             bos.write(content);
   440             rawContent = new MimeBodyPart(hdrs, bos.getBytes(), bos.getCount());
   441             setMimeHeader("Content-Type", contentType);
   442         } catch (Exception e) {
   443             log.log(Level.SEVERE, "SAAJ0576.soap.attachment.setrawcontent.exception", e);
   444             throw new SOAPExceptionImpl(e.getLocalizedMessage());
   445         } finally {
   446             try {
   447                 content.close();
   448             } catch (IOException ex) {
   449                 throw new SOAPException(ex);
   450             }
   451         }
   452     }
   454    /*
   455     public void setRawContentBytes(byte[] content, String contentType)
   456         throws SOAPException {
   457         if (content == null) {
   458             throw new SOAPExceptionImpl("Null content passed to setRawContentBytes");
   459         }
   460         dataHandler = null;
   461         try {
   462             InternetHeaders hdrs = new InternetHeaders();
   463             hdrs.setHeader("Content-Type", contentType);
   464             rawContent = new MimeBodyPart(hdrs, content, content.length);
   465             setMimeHeader("Content-Type", contentType);
   466         } catch (Exception e) {
   467             log.log(Level.SEVERE, "SAAJ0576.soap.attachment.setrawcontent.exception", e);
   468             throw new SOAPExceptionImpl(e.getLocalizedMessage());
   469         }
   470     } */
   472     public void setRawContentBytes(
   473         byte[] content, int off, int len, String contentType)
   474         throws SOAPException {
   475         if (mimePart != null) {
   476             mimePart.close();
   477             mimePart = null;
   478         }
   479         if (content == null) {
   480             throw new SOAPExceptionImpl("Null content passed to setRawContentBytes");
   481         }
   482         dataHandler = null;
   483         try {
   484             InternetHeaders hdrs = new InternetHeaders();
   485             hdrs.setHeader("Content-Type", contentType);
   486             rawContent = new MimeBodyPart(hdrs, content, off, len);
   487             setMimeHeader("Content-Type", contentType);
   488         } catch (Exception e) {
   489             log.log(Level.SEVERE,
   490                 "SAAJ0576.soap.attachment.setrawcontent.exception", e);
   491             throw new SOAPExceptionImpl(e.getLocalizedMessage());
   492         }
   493     }
   495     public  InputStream getRawContent() throws SOAPException {
   496         if (mimePart != null) {
   497             return mimePart.read();
   498         }
   499         if (rawContent != null) {
   500             try {
   501                 return rawContent.getInputStream();
   502             } catch (Exception e) {
   503                 log.log(Level.SEVERE,"SAAJ0577.soap.attachment.getrawcontent.exception", e);
   504                 throw new SOAPExceptionImpl(e.getLocalizedMessage());
   505             }
   506         } else if (dataHandler != null) {
   507             try {
   508                 return dataHandler.getInputStream();
   509             } catch (IOException e) {
   510                 log.severe("SAAJ0574.soap.attachment.datahandler.ioexception");
   511                 throw new SOAPExceptionImpl("DataHandler error" + e);
   512             }
   513         } else {
   514             log.severe("SAAJ0572.soap.no.content.for.attachment");
   515             throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
   516         }
   517     }
   519     public  byte[] getRawContentBytes() throws SOAPException {
   520         InputStream ret;
   521         if (mimePart != null) {
   522             try {
   523                 ret = mimePart.read();
   524                 return ASCIIUtility.getBytes(ret);
   525             } catch (IOException ex) {
   526                 log.log(Level.SEVERE,"SAAJ0577.soap.attachment.getrawcontent.exception", ex);
   527                 throw new SOAPExceptionImpl(ex);
   528             }
   529         }
   530         if (rawContent != null) {
   531             try {
   532                 ret = rawContent.getInputStream();
   533                 return ASCIIUtility.getBytes(ret);
   534             } catch (Exception e) {
   535                 log.log(Level.SEVERE,"SAAJ0577.soap.attachment.getrawcontent.exception", e);
   536                 throw new SOAPExceptionImpl(e);
   537             }
   538         } else if (dataHandler != null) {
   539             try {
   540                 ret = dataHandler.getInputStream();
   541                 return ASCIIUtility.getBytes(ret);
   542             } catch (IOException e) {
   543                 log.severe("SAAJ0574.soap.attachment.datahandler.ioexception");
   544                 throw new SOAPExceptionImpl("DataHandler error" + e);
   545             }
   546         } else {
   547             log.severe("SAAJ0572.soap.no.content.for.attachment");
   548             throw new SOAPExceptionImpl("No data handler/content associated with this attachment");
   549         }
   550     }
   552     // attachments are equal if they are the same reference
   553     public boolean equals(Object o) {
   554         return (this == o);
   555     }
   557     // In JDK 8 we get a warning if we implement equals() but not hashCode().
   558     // There is no intuitive value for this, the default one in Object is fine.
   559     public int hashCode() {
   560         return super.hashCode();
   561     }
   563     public MimeHeaders getMimeHeaders() {
   564         return headers;
   565     }
   567     public static void initializeJavaActivationHandlers() {
   568         // DataHandler.writeTo() may search for DCH. So adding some default ones.
   569         try {
   570             CommandMap map = CommandMap.getDefaultCommandMap();
   571             if (map instanceof MailcapCommandMap) {
   572                 MailcapCommandMap mailMap = (MailcapCommandMap) map;
   574                 // registering our DCH since javamail's DCH doesn't handle
   575                 if (!cmdMapInitialized(mailMap)) {
   576                     mailMap.addMailcap("text/xml;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler");
   577                     mailMap.addMailcap("application/xml;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler");
   578                     mailMap.addMailcap("application/fastinfoset;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.FastInfosetDataContentHandler");
   579                     // this handler seems to be not used according VCS history ...
   580                     // mailMap.addMailcap("multipart/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.MultipartDataContentHandler");
   581                     mailMap.addMailcap("image/*;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.ImageDataContentHandler");
   582                     mailMap.addMailcap("text/plain;;x-java-content-handler=com.sun.xml.internal.messaging.saaj.soap.StringDataContentHandler");
   583                 }
   584             }
   585         } catch (Throwable t) {
   586             // ignore the exception.
   587         }
   588     }
   590     private static boolean cmdMapInitialized(MailcapCommandMap mailMap) {
   592         // checking fastinfoset handler, since this one is specific to SAAJ
   593         CommandInfo[] commands = mailMap.getAllCommands("application/fastinfoset");
   594         if (commands == null || commands.length == 0) {
   595             return false;
   596         }
   598         String saajClassName = "com.sun.xml.internal.ws.binding.FastInfosetDataContentHandler";
   599         for (CommandInfo command : commands) {
   600             String commandClass = command.getCommandClass();
   601             if (saajClassName.equals(commandClass)) {
   602                 return true;
   603             }
   604         }
   605         return false;
   606     }
   607 }

mercurial