src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/mimepull/MIMEPart.java

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

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

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.xml.internal.org.jvnet.mimepull;
aoqi@0 27
aoqi@0 28 import java.io.File;
aoqi@0 29 import java.io.InputStream;
aoqi@0 30 import java.nio.ByteBuffer;
aoqi@0 31 import java.util.List;
aoqi@0 32 import java.util.logging.Level;
aoqi@0 33 import java.util.logging.Logger;
aoqi@0 34
aoqi@0 35 /**
aoqi@0 36 * Represents an attachment part in a MIME message. MIME message parsing is done
aoqi@0 37 * lazily using a pull parser, so the part may not have all the data. {@link #read}
aoqi@0 38 * and {@link #readOnce} may trigger the actual parsing the message. In fact,
aoqi@0 39 * parsing of an attachment part may be triggered by calling {@link #read} methods
aoqi@0 40 * on some other attachment parts. All this happens behind the scenes so the
aoqi@0 41 * application developer need not worry about these details.
aoqi@0 42 *
aoqi@0 43 * @author Jitendra Kotamraju, Martin Grebac
aoqi@0 44 */
aoqi@0 45 public class MIMEPart {
aoqi@0 46
aoqi@0 47 private static final Logger LOGGER = Logger.getLogger(MIMEPart.class.getName());
aoqi@0 48
aoqi@0 49 private volatile InternetHeaders headers;
aoqi@0 50 private volatile String contentId;
aoqi@0 51 private String contentType;
aoqi@0 52 private String contentTransferEncoding;
aoqi@0 53
aoqi@0 54 volatile boolean parsed; // part is parsed or not
aoqi@0 55 final MIMEMessage msg;
aoqi@0 56 private final DataHead dataHead;
aoqi@0 57
aoqi@0 58 MIMEPart(MIMEMessage msg) {
aoqi@0 59 this.msg = msg;
aoqi@0 60 this.dataHead = new DataHead(this);
aoqi@0 61 }
aoqi@0 62
aoqi@0 63 MIMEPart(MIMEMessage msg, String contentId) {
aoqi@0 64 this(msg);
aoqi@0 65 this.contentId = contentId;
aoqi@0 66 }
aoqi@0 67
aoqi@0 68 /**
aoqi@0 69 * Can get the attachment part's content multiple times. That means
aoqi@0 70 * the full content needs to be there in memory or on the file system.
aoqi@0 71 * Calling this method would trigger parsing for the part's data. So
aoqi@0 72 * do not call this unless it is required(otherwise, just wrap MIMEPart
aoqi@0 73 * into a object that returns InputStream for e.g DataHandler)
aoqi@0 74 *
aoqi@0 75 * @return data for the part's content
aoqi@0 76 */
aoqi@0 77 public InputStream read() {
aoqi@0 78 InputStream is = null;
aoqi@0 79 try {
aoqi@0 80 is = MimeUtility.decode(dataHead.read(), contentTransferEncoding);
aoqi@0 81 } catch (DecodingException ex) { //ignore
aoqi@0 82 if (LOGGER.isLoggable(Level.WARNING)) {
aoqi@0 83 LOGGER.log(Level.WARNING, null, ex);
aoqi@0 84 }
aoqi@0 85 }
aoqi@0 86 return is;
aoqi@0 87 }
aoqi@0 88
aoqi@0 89 /**
aoqi@0 90 * Cleans up any resources that are held by this part (for e.g. deletes
aoqi@0 91 * the temp file that is used to serve this part's content). After
aoqi@0 92 * calling this, one shouldn't call {@link #read()} or {@link #readOnce()}
aoqi@0 93 */
aoqi@0 94 public void close() {
aoqi@0 95 dataHead.close();
aoqi@0 96 }
aoqi@0 97
aoqi@0 98 /**
aoqi@0 99 * Can get the attachment part's content only once. The content
aoqi@0 100 * will be lost after the method. Content data is not be stored
aoqi@0 101 * on the file system or is not kept in the memory for the
aoqi@0 102 * following case:
aoqi@0 103 * - Attachement parts contents are accessed sequentially
aoqi@0 104 *
aoqi@0 105 * In general, take advantage of this when the data is used only
aoqi@0 106 * once.
aoqi@0 107 *
aoqi@0 108 * @return data for the part's content
aoqi@0 109 */
aoqi@0 110 public InputStream readOnce() {
aoqi@0 111 InputStream is = null;
aoqi@0 112 try {
aoqi@0 113 is = MimeUtility.decode(dataHead.readOnce(), contentTransferEncoding);
aoqi@0 114 } catch (DecodingException ex) { //ignore
aoqi@0 115 if (LOGGER.isLoggable(Level.WARNING)) {
aoqi@0 116 LOGGER.log(Level.WARNING, null, ex);
aoqi@0 117 }
aoqi@0 118 }
aoqi@0 119 return is;
aoqi@0 120 }
aoqi@0 121
aoqi@0 122 public void moveTo(File f) {
aoqi@0 123 dataHead.moveTo(f);
aoqi@0 124 }
aoqi@0 125
aoqi@0 126 /**
aoqi@0 127 * Returns Content-ID MIME header for this attachment part
aoqi@0 128 *
aoqi@0 129 * @return Content-ID of the part
aoqi@0 130 */
aoqi@0 131 public String getContentId() {
aoqi@0 132 if (contentId == null) {
aoqi@0 133 getHeaders();
aoqi@0 134 }
aoqi@0 135 return contentId;
aoqi@0 136 }
aoqi@0 137
aoqi@0 138 /**
aoqi@0 139 * Returns Content-Transfer-Encoding MIME header for this attachment part
aoqi@0 140 *
aoqi@0 141 * @return Content-Transfer-Encoding of the part
aoqi@0 142 */
aoqi@0 143 public String getContentTransferEncoding() {
aoqi@0 144 if (contentTransferEncoding == null) {
aoqi@0 145 getHeaders();
aoqi@0 146 }
aoqi@0 147 return contentTransferEncoding;
aoqi@0 148 }
aoqi@0 149
aoqi@0 150 /**
aoqi@0 151 * Returns Content-Type MIME header for this attachment part
aoqi@0 152 *
aoqi@0 153 * @return Content-Type of the part
aoqi@0 154 */
aoqi@0 155 public String getContentType() {
aoqi@0 156 if (contentType == null) {
aoqi@0 157 getHeaders();
aoqi@0 158 }
aoqi@0 159 return contentType;
aoqi@0 160 }
aoqi@0 161
aoqi@0 162 private void getHeaders() {
aoqi@0 163 // Trigger parsing for the part headers
aoqi@0 164 while(headers == null) {
aoqi@0 165 if (!msg.makeProgress()) {
aoqi@0 166 if (headers == null) {
aoqi@0 167 throw new IllegalStateException("Internal Error. Didn't get Headers even after complete parsing.");
aoqi@0 168 }
aoqi@0 169 }
aoqi@0 170 }
aoqi@0 171 }
aoqi@0 172
aoqi@0 173 /**
aoqi@0 174 * Return all the values for the specified header.
aoqi@0 175 * Returns <code>null</code> if no headers with the
aoqi@0 176 * specified name exist.
aoqi@0 177 *
aoqi@0 178 * @param name header name
aoqi@0 179 * @return list of header values, or null if none
aoqi@0 180 */
aoqi@0 181 public List<String> getHeader(String name) {
aoqi@0 182 getHeaders();
aoqi@0 183 assert headers != null;
aoqi@0 184 return headers.getHeader(name);
aoqi@0 185 }
aoqi@0 186
aoqi@0 187 /**
aoqi@0 188 * Return all the headers
aoqi@0 189 *
aoqi@0 190 * @return list of Header objects
aoqi@0 191 */
aoqi@0 192 public List<? extends Header> getAllHeaders() {
aoqi@0 193 getHeaders();
aoqi@0 194 assert headers != null;
aoqi@0 195 return headers.getAllHeaders();
aoqi@0 196 }
aoqi@0 197
aoqi@0 198 /**
aoqi@0 199 * Callback to set headers
aoqi@0 200 *
aoqi@0 201 * @param headers MIME headers for the part
aoqi@0 202 */
aoqi@0 203 void setHeaders(InternetHeaders headers) {
aoqi@0 204 this.headers = headers;
aoqi@0 205 List<String> ct = getHeader("Content-Type");
aoqi@0 206 this.contentType = (ct == null) ? "application/octet-stream" : ct.get(0);
aoqi@0 207 List<String> cte = getHeader("Content-Transfer-Encoding");
aoqi@0 208 this.contentTransferEncoding = (cte == null) ? "binary" : cte.get(0);
aoqi@0 209 }
aoqi@0 210
aoqi@0 211 /**
aoqi@0 212 * Callback to notify that there is a partial content for the part
aoqi@0 213 *
aoqi@0 214 * @param buf content data for the part
aoqi@0 215 */
aoqi@0 216 void addBody(ByteBuffer buf) {
aoqi@0 217 dataHead.addBody(buf);
aoqi@0 218 }
aoqi@0 219
aoqi@0 220 /**
aoqi@0 221 * Callback to indicate that parsing is done for this part
aoqi@0 222 * (no more update events for this part)
aoqi@0 223 */
aoqi@0 224 void doneParsing() {
aoqi@0 225 parsed = true;
aoqi@0 226 dataHead.doneParsing();
aoqi@0 227 }
aoqi@0 228
aoqi@0 229 /**
aoqi@0 230 * Callback to set Content-ID for this part
aoqi@0 231 * @param cid Content-ID of the part
aoqi@0 232 */
aoqi@0 233 void setContentId(String cid) {
aoqi@0 234 this.contentId = cid;
aoqi@0 235 }
aoqi@0 236
aoqi@0 237 /**
aoqi@0 238 * Callback to set Content-Transfer-Encoding for this part
aoqi@0 239 * @param cte Content-Transfer-Encoding of the part
aoqi@0 240 */
aoqi@0 241 void setContentTransferEncoding(String cte) {
aoqi@0 242 this.contentTransferEncoding = cte;
aoqi@0 243 }
aoqi@0 244
aoqi@0 245 @Override
aoqi@0 246 public String toString() {
aoqi@0 247 return "Part="+contentId+":"+contentTransferEncoding;
aoqi@0 248 }
aoqi@0 249
aoqi@0 250 }

mercurial