diff -r 000000000000 -r 373ffda63c9a src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/MimeCodec.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/MimeCodec.java Wed Apr 27 01:27:09 2016 +0800 @@ -0,0 +1,211 @@ +/* + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.xml.internal.ws.encoding; + +import com.sun.xml.internal.ws.api.SOAPVersion; +import com.sun.xml.internal.ws.api.WSFeatureList; +import com.sun.xml.internal.ws.api.message.Attachment; +import com.sun.xml.internal.ws.api.message.AttachmentEx; +import com.sun.xml.internal.ws.api.message.Message; +import com.sun.xml.internal.ws.api.message.Packet; +import com.sun.xml.internal.ws.api.pipe.Codec; +import com.sun.xml.internal.ws.api.pipe.ContentType; +import com.sun.xml.internal.ws.developer.StreamingAttachmentFeature; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.channels.ReadableByteChannel; +import java.util.Iterator; +import java.util.UUID; + +/** + * {@link Codec}s that uses the MIME multipart as the underlying format. + * + *
+ * When the runtime needs to dynamically choose a {@link Codec}, and + * when there are more than one {@link Codec}s that use MIME multipart, + * it is often impossible to determine the right {@link Codec} unless + * you parse the multipart message to some extent. + * + *
+ * By having all such {@link Codec}s extending from this class,
+ * the "sniffer" can decode a multipart message partially, and then
+ * pass the partial parse result to the ultimately-responsible {@link Codec}.
+ * This improves the performance.
+ *
+ * @author Kohsuke Kawaguchi
+ */
+abstract class MimeCodec implements Codec {
+
+ public static final String MULTIPART_RELATED_MIME_TYPE = "multipart/related";
+
+ protected Codec mimeRootCodec;
+ protected final SOAPVersion version;
+ protected final WSFeatureList features;
+
+ protected MimeCodec(SOAPVersion version, WSFeatureList f) {
+ this.version = version;
+ this.features = f;
+ }
+
+ public String getMimeType() {
+ return MULTIPART_RELATED_MIME_TYPE;
+ }
+
+ protected Codec getMimeRootCodec(Packet packet) {
+ return mimeRootCodec;
+ }
+
+ // TODO: preencode String literals to byte[] so that they don't have to
+ // go through char[]->byte[] conversion at runtime.
+ public ContentType encode(Packet packet, OutputStream out) throws IOException {
+ Message msg = packet.getMessage();
+ if (msg == null) {
+ return null;
+ }
+ ContentTypeImpl ctImpl = (ContentTypeImpl)getStaticContentType(packet);
+ String boundary = ctImpl.getBoundary();
+ boolean hasAttachments = (boundary != null);
+ Codec rootCodec = getMimeRootCodec(packet);
+ if (hasAttachments) {
+ writeln("--"+boundary, out);
+ ContentType ct = rootCodec.getStaticContentType(packet);
+ String ctStr = (ct != null) ? ct.getContentType() : rootCodec.getMimeType();
+ writeln("Content-Type: " + ctStr, out);
+ writeln(out);
+ }
+ ContentType primaryCt = rootCodec.encode(packet, out);
+
+ if (hasAttachments) {
+ writeln(out);
+ // Encode all the attchments
+ for (Attachment att : msg.getAttachments()) {
+ writeln("--"+boundary, out);
+ //SAAJ's AttachmentPart.getContentId() returns content id already enclosed with
+ //angle brackets. For now put angle bracket only if its not there
+ String cid = att.getContentId();
+ if(cid != null && cid.length() >0 && cid.charAt(0) != '<')
+ cid = '<' + cid + '>';
+ writeln("Content-Id:" + cid, out);
+ writeln("Content-Type: " + att.getContentType(), out);
+ writeCustomMimeHeaders(att, out);
+ writeln("Content-Transfer-Encoding: binary", out);
+ writeln(out); // write \r\n
+ att.writeTo(out);
+ writeln(out); // write \r\n
+ }
+ writeAsAscii("--"+boundary, out);
+ writeAsAscii("--", out);
+ }
+ // TODO not returing correct multipart/related type(no boundary)
+ return hasAttachments ? ctImpl : primaryCt;
+ }
+
+ private void writeCustomMimeHeaders(Attachment att, OutputStream out) throws IOException {
+ if (att instanceof AttachmentEx) {
+ Iterator