1 /* |
1 /* |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
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. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
22 * or visit www.oracle.com if you need additional information or have any |
22 * or visit www.oracle.com if you need additional information or have any |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package com.sun.xml.internal.ws.encoding; |
26 package com.sun.xml.internal.ws.encoding; |
27 |
|
28 |
27 |
29 import com.sun.istack.internal.NotNull; |
28 import com.sun.istack.internal.NotNull; |
30 import com.sun.istack.internal.Nullable; |
29 import com.sun.istack.internal.Nullable; |
31 import com.sun.xml.internal.ws.api.message.Attachment; |
30 import com.sun.xml.internal.ws.api.message.Attachment; |
32 import com.sun.xml.internal.ws.api.message.AttachmentEx; |
31 import com.sun.xml.internal.ws.api.message.AttachmentEx; |
51 import java.io.OutputStream; |
50 import java.io.OutputStream; |
52 import java.util.HashMap; |
51 import java.util.HashMap; |
53 import java.util.Iterator; |
52 import java.util.Iterator; |
54 import java.util.List; |
53 import java.util.List; |
55 import java.util.Map; |
54 import java.util.Map; |
|
55 import java.util.logging.Level; |
|
56 import java.util.logging.Logger; |
56 |
57 |
57 /** |
58 /** |
58 * Parses Mime multipart message into primary part and attachment parts. It |
59 * Parses Mime multipart message into primary part and attachment parts. It |
59 * parses the stream lazily as and when required. |
60 * parses the stream lazily as and when required. |
60 * |
61 * |
64 public final class MimeMultipartParser { |
65 public final class MimeMultipartParser { |
65 |
66 |
66 private final String start; |
67 private final String start; |
67 private final MIMEMessage message; |
68 private final MIMEMessage message; |
68 private Attachment root; |
69 private Attachment root; |
|
70 private ContentTypeImpl contentType; |
69 |
71 |
70 // Attachments without root part |
72 // Attachments without root part |
71 private final Map<String, Attachment> attachments = new HashMap<String, Attachment>(); |
73 private final Map<String, Attachment> attachments = new HashMap<String, Attachment>(); |
72 |
74 |
73 private boolean gotAll; |
75 private boolean gotAll; |
74 |
76 |
75 public MimeMultipartParser(InputStream in, String contentType, StreamingAttachmentFeature feature) { |
77 public MimeMultipartParser(InputStream in, String cType, StreamingAttachmentFeature feature) { |
76 ContentType ct = new ContentType(contentType); |
78 this.contentType = new ContentTypeImpl(cType); |
77 String boundary = ct.getParameter("boundary"); |
79 // ContentType ct = new ContentType(cType); |
|
80 // String boundary = ct.getParameter("boundary"); |
|
81 String boundary = contentType.getBoundary(); |
78 if (boundary == null || boundary.equals("")) { |
82 if (boundary == null || boundary.equals("")) { |
79 throw new WebServiceException("MIME boundary parameter not found" + contentType); |
83 throw new WebServiceException("MIME boundary parameter not found" + contentType); |
80 } |
84 } |
81 message = (feature != null) |
85 message = (feature != null) |
82 ? new MIMEMessage(in, boundary, feature.getConfig()) |
86 ? new MIMEMessage(in, boundary, feature.getConfig()) |
83 : new MIMEMessage(in, boundary); |
87 : new MIMEMessage(in, boundary); |
84 // Strip <...> from root part's Content-ID |
88 // Strip <...> from root part's Content-ID |
85 String st = ct.getParameter("start"); |
89 // String st = ct.getParameter("start"); |
|
90 String st = contentType.getRootId(); |
86 if (st != null && st.length() > 2 && st.charAt(0) == '<' && st.charAt(st.length()-1) == '>') { |
91 if (st != null && st.length() > 2 && st.charAt(0) == '<' && st.charAt(st.length()-1) == '>') { |
87 st = st.substring(1, st.length()-1); |
92 st = st.substring(1, st.length()-1); |
88 } |
93 } |
89 start = st; |
94 start = st; |
90 } |
95 } |
114 if (!gotAll) { |
119 if (!gotAll) { |
115 MIMEPart rootPart = (start != null) ? message.getPart(start) : message.getPart(0); |
120 MIMEPart rootPart = (start != null) ? message.getPart(start) : message.getPart(0); |
116 List<MIMEPart> parts = message.getAttachments(); |
121 List<MIMEPart> parts = message.getAttachments(); |
117 for(MIMEPart part : parts) { |
122 for(MIMEPart part : parts) { |
118 if (part != rootPart) { |
123 if (part != rootPart) { |
119 PartAttachment attach = new PartAttachment(part); |
124 String cid = part.getContentId(); |
120 attachments.put(attach.getContentId(), attach); |
125 if (!attachments.containsKey(cid)) { |
|
126 PartAttachment attach = new PartAttachment(part); |
|
127 attachments.put(attach.getContentId(), attach); |
|
128 } |
121 } |
129 } |
122 } |
130 } |
123 gotAll = true; |
131 gotAll = true; |
124 } |
132 } |
125 return attachments; |
133 return attachments; |
145 |
153 |
146 static class PartAttachment implements AttachmentEx { |
154 static class PartAttachment implements AttachmentEx { |
147 |
155 |
148 final MIMEPart part; |
156 final MIMEPart part; |
149 byte[] buf; |
157 byte[] buf; |
|
158 private StreamingDataHandler streamingDataHandler; |
150 |
159 |
151 PartAttachment(MIMEPart part) { |
160 PartAttachment(MIMEPart part) { |
152 this.part = part; |
161 this.part = part; |
153 } |
162 } |
154 |
163 |
155 public @NotNull String getContentId() { |
164 public @NotNull @Override String getContentId() { |
156 return part.getContentId(); |
165 return part.getContentId(); |
157 } |
166 } |
158 |
167 |
159 public @NotNull String getContentType() { |
168 public @NotNull @Override String getContentType() { |
160 return part.getContentType(); |
169 return part.getContentType(); |
161 } |
170 } |
162 |
171 |
|
172 @Override |
163 public byte[] asByteArray() { |
173 public byte[] asByteArray() { |
164 if (buf == null) { |
174 if (buf == null) { |
165 ByteArrayBuffer baf = new ByteArrayBuffer(); |
175 ByteArrayBuffer baf = new ByteArrayBuffer(); |
166 try { |
176 try { |
167 baf.write(part.readOnce()); |
177 baf.write(part.readOnce()); |
168 } catch(IOException ioe) { |
178 } catch(IOException ioe) { |
169 throw new WebServiceException(ioe); |
179 throw new WebServiceException(ioe); |
|
180 } finally { |
|
181 if (baf != null) { |
|
182 try { |
|
183 baf.close(); |
|
184 } catch (IOException ex) { |
|
185 Logger.getLogger(MimeMultipartParser.class.getName()).log(Level.FINE, null, ex); |
|
186 } |
|
187 } |
170 } |
188 } |
171 buf = baf.toByteArray(); |
189 buf = baf.toByteArray(); |
172 } |
190 } |
173 return buf; |
191 return buf; |
174 } |
192 } |
175 |
193 |
|
194 @Override |
176 public DataHandler asDataHandler() { |
195 public DataHandler asDataHandler() { |
177 return (buf != null) |
196 if (streamingDataHandler == null) { |
178 ? new DataSourceStreamingDataHandler(new ByteArrayDataSource(buf,getContentType())) |
197 streamingDataHandler = (buf != null) |
179 : new MIMEPartStreamingDataHandler(part); |
198 ? new DataSourceStreamingDataHandler(new ByteArrayDataSource(buf,getContentType())) |
180 } |
199 : new MIMEPartStreamingDataHandler(part); |
181 |
200 } |
|
201 return streamingDataHandler; |
|
202 } |
|
203 |
|
204 @Override |
182 public Source asSource() { |
205 public Source asSource() { |
183 return (buf != null) |
206 return (buf != null) |
184 ? new StreamSource(new ByteArrayInputStream(buf)) |
207 ? new StreamSource(new ByteArrayInputStream(buf)) |
185 : new StreamSource(part.read()); |
208 : new StreamSource(part.read()); |
186 } |
209 } |
187 |
210 |
|
211 @Override |
188 public InputStream asInputStream() { |
212 public InputStream asInputStream() { |
189 return (buf != null) |
213 return (buf != null) |
190 ? new ByteArrayInputStream(buf) : part.read(); |
214 ? new ByteArrayInputStream(buf) : part.read(); |
191 } |
215 } |
192 |
216 |
|
217 @Override |
193 public void writeTo(OutputStream os) throws IOException { |
218 public void writeTo(OutputStream os) throws IOException { |
194 if (buf != null) { |
219 if (buf != null) { |
195 os.write(buf); |
220 os.write(buf); |
196 } else { |
221 } else { |
197 InputStream in = part.read(); |
222 InputStream in = part.read(); |
202 } |
227 } |
203 in.close(); |
228 in.close(); |
204 } |
229 } |
205 } |
230 } |
206 |
231 |
|
232 @Override |
207 public void writeTo(SOAPMessage saaj) throws SOAPException { |
233 public void writeTo(SOAPMessage saaj) throws SOAPException { |
208 saaj.createAttachmentPart().setDataHandler(asDataHandler()); |
234 saaj.createAttachmentPart().setDataHandler(asDataHandler()); |
209 } |
235 } |
210 |
236 |
211 // AttachmentEx methods begin here |
237 // AttachmentEx methods begin here |
|
238 @Override |
212 public Iterator<MimeHeader> getMimeHeaders() { |
239 public Iterator<MimeHeader> getMimeHeaders() { |
213 final Iterator<? extends Header> ih = part.getAllHeaders() |
240 final Iterator<? extends Header> ih = part.getAllHeaders() |
214 .iterator(); |
241 .iterator(); |
215 return new Iterator<MimeHeader>() { |
242 return new Iterator<MimeHeader>() { |
|
243 @Override |
216 public boolean hasNext() { |
244 public boolean hasNext() { |
217 return ih.hasNext(); |
245 return ih.hasNext(); |
218 } |
246 } |
219 |
247 |
|
248 @Override |
220 public MimeHeader next() { |
249 public MimeHeader next() { |
221 final Header hdr = ih.next(); |
250 final Header hdr = ih.next(); |
222 return new AttachmentEx.MimeHeader() { |
251 return new AttachmentEx.MimeHeader() { |
|
252 @Override |
223 public String getValue() { |
253 public String getValue() { |
224 return hdr.getValue(); |
254 return hdr.getValue(); |
225 } |
255 } |
|
256 @Override |
226 public String getName() { |
257 public String getName() { |
227 return hdr.getName(); |
258 return hdr.getName(); |
228 } |
259 } |
229 }; |
260 }; |
230 } |
261 } |
231 |
262 |
|
263 @Override |
232 public void remove() { |
264 public void remove() { |
233 throw new UnsupportedOperationException(); |
265 throw new UnsupportedOperationException(); |
234 } |
266 } |
235 }; |
267 }; |
236 } |
268 } |
237 } |
269 } |
238 |
270 |
|
271 public ContentTypeImpl getContentType() { |
|
272 return contentType; |
|
273 } |
|
274 |
239 } |
275 } |