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
98 * Default constructor. An empty MimeMultipart object
99 * is created. Its content type is set to "multipart/mixed".
100 * A unique boundary string is generated and this string is
101 * setup as the "boundary" parameter for the
102 * <code>contentType</code> field. <p>
103 *
104 * MimeBodyParts may be added later.
105 */
106 public BMMimeMultipart() {
107 super();
108 //this("mixed");
109 }
110
111 /**
112 * Construct a MimeMultipart object of the given subtype.
113 * A unique boundary string is generated and this string is
114 * setup as the "boundary" parameter for the
115 * <code>contentType</code> field. <p>
116 *
117 * MimeBodyParts may be added later.
118 */
119 public BMMimeMultipart(String subtype) {
120 super(subtype);
121 /*
122 * Compute a boundary string.
123 String boundary = UniqueValue.getUniqueBoundaryValue();
124 ContentType cType = new ContentType("multipart", subtype, null);
125 contentType.setParameter("boundary", boundary);
126 */
127 }
128
129 /**
130 * Constructs a MimeMultipart object and its bodyparts from the
131 * given DataSource. <p>
132 *
133 * This constructor handles as a special case the situation where the
134 * given DataSource is a MultipartDataSource object. In this case, this
135 * method just invokes the superclass (i.e., Multipart) constructor
136 * that takes a MultipartDataSource object. <p>
137 *
138 * Otherwise, the DataSource is assumed to provide a MIME multipart
139 * byte stream. The <code>parsed</code> flag is set to false. When
140 * the data for the body parts are needed, the parser extracts the
141 * "boundary" parameter from the content type of this DataSource,
142 * skips the 'preamble' and reads bytes till the terminating
143 * boundary and creates MimeBodyParts for each part of the stream.
144 *
145 * @param ds DataSource, can be a MultipartDataSource
146 */
147 public BMMimeMultipart(DataSource ds, ContentType ct)
148 throws MessagingException {
149 super(ds,ct);
150 boundary = ct.getParameter("boundary");
151 /*
152 if (ds instanceof MultipartDataSource) {
153 // ask super to do this for us.
154 setMultipartDataSource((MultipartDataSource)ds);
155 return;
156 }
157
158 // 'ds' was not a MultipartDataSource, we have
159 // to parse this ourself.
160 parsed = false;
161 this.ds = ds;
162 if (ct==null)
163 contentType = new ContentType(ds.getContentType());
164 else
165 contentType = ct;
180 throw new MessagingException("No inputstream from datasource");
181 }
182
183 if (!in.markSupported()) {
184 throw new MessagingException(
185 "InputStream does not support Marking");
186 }
187 }
188 return in;
189 }
190
191 /**
192 * Parse the InputStream from our DataSource, constructing the
193 * appropriate MimeBodyParts. The <code>parsed</code> flag is
194 * set to true, and if true on entry nothing is done. This
195 * method is called by all other methods that need data for
196 * the body parts, to make sure the data has been parsed.
197 *
198 * @since JavaMail 1.2
199 */
200 protected void parse() throws MessagingException {
201 if (parsed)
202 return;
203
204 initStream();
205
206 SharedInputStream sin = null;
207 if (in instanceof SharedInputStream) {
208 sin = (SharedInputStream)in;
209 }
210
211 String bnd = "--" + boundary;
212 byte[] bndbytes = ASCIIUtility.getBytes(bnd);
213 try {
214 parse(in, bndbytes, sin);
215 } catch (IOException ioex) {
216 throw new MessagingException("IO Error", ioex);
217 } catch (Exception ex) {
218 throw new MessagingException("Error", ex);
219 }
677 gss[j - 1] = i;
678 } else {
679 // No match. The array has already been
680 // filled up with correct values before.
681 continue NEXT;
682 }
683 }
684 while (j > 0) {
685 gss[--j] = i;
686 }
687 }
688 gss[l - 1] = 1;
689 }
690
691
692 /**
693 * Iterates through all the parts and outputs each Mime part
694 * separated by a boundary.
695 */
696
697 public void writeTo(OutputStream os)
698 throws IOException, MessagingException {
699
700 // inputStream was not null
701 if (in != null) {
702 contentType.setParameter("boundary", this.boundary);
703 }
704
705 String bnd = "--" + contentType.getParameter("boundary");
706 for (int i = 0; i < parts.size(); i++) {
707 OutputUtil.writeln(bnd, os); // put out boundary
708 parts.get(i).writeTo(os);
709 OutputUtil.writeln(os); // put out empty line
710 }
711
712 if (in != null) {
713 OutputUtil.writeln(bnd, os); // put out boundary
714 if ((os instanceof ByteOutputStream) && lazyAttachments) {
715 ((ByteOutputStream) os).write(in);
716 } else {
|
1 /*
2 * Copyright (c) 1997, 2017, 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
98 * Default constructor. An empty MimeMultipart object
99 * is created. Its content type is set to "multipart/mixed".
100 * A unique boundary string is generated and this string is
101 * setup as the "boundary" parameter for the
102 * <code>contentType</code> field. <p>
103 *
104 * MimeBodyParts may be added later.
105 */
106 public BMMimeMultipart() {
107 super();
108 //this("mixed");
109 }
110
111 /**
112 * Construct a MimeMultipart object of the given subtype.
113 * A unique boundary string is generated and this string is
114 * setup as the "boundary" parameter for the
115 * <code>contentType</code> field. <p>
116 *
117 * MimeBodyParts may be added later.
118 *
119 * @param subtype subtype.
120 */
121 public BMMimeMultipart(String subtype) {
122 super(subtype);
123 /*
124 * Compute a boundary string.
125 String boundary = UniqueValue.getUniqueBoundaryValue();
126 ContentType cType = new ContentType("multipart", subtype, null);
127 contentType.setParameter("boundary", boundary);
128 */
129 }
130
131 /**
132 * Constructs a MimeMultipart object and its bodyparts from the
133 * given DataSource. <p>
134 *
135 * This constructor handles as a special case the situation where the
136 * given DataSource is a MultipartDataSource object. In this case, this
137 * method just invokes the superclass (i.e., Multipart) constructor
138 * that takes a MultipartDataSource object. <p>
139 *
140 * Otherwise, the DataSource is assumed to provide a MIME multipart
141 * byte stream. The <code>parsed</code> flag is set to false. When
142 * the data for the body parts are needed, the parser extracts the
143 * "boundary" parameter from the content type of this DataSource,
144 * skips the 'preamble' and reads bytes till the terminating
145 * boundary and creates MimeBodyParts for each part of the stream.
146 *
147 * @param ds DataSource, can be a MultipartDataSource.
148 * @param ct content type.
149 * @exception MessagingException in case of error.
150 */
151 public BMMimeMultipart(DataSource ds, ContentType ct)
152 throws MessagingException {
153 super(ds,ct);
154 boundary = ct.getParameter("boundary");
155 /*
156 if (ds instanceof MultipartDataSource) {
157 // ask super to do this for us.
158 setMultipartDataSource((MultipartDataSource)ds);
159 return;
160 }
161
162 // 'ds' was not a MultipartDataSource, we have
163 // to parse this ourself.
164 parsed = false;
165 this.ds = ds;
166 if (ct==null)
167 contentType = new ContentType(ds.getContentType());
168 else
169 contentType = ct;
184 throw new MessagingException("No inputstream from datasource");
185 }
186
187 if (!in.markSupported()) {
188 throw new MessagingException(
189 "InputStream does not support Marking");
190 }
191 }
192 return in;
193 }
194
195 /**
196 * Parse the InputStream from our DataSource, constructing the
197 * appropriate MimeBodyParts. The <code>parsed</code> flag is
198 * set to true, and if true on entry nothing is done. This
199 * method is called by all other methods that need data for
200 * the body parts, to make sure the data has been parsed.
201 *
202 * @since JavaMail 1.2
203 */
204 @Override
205 protected void parse() throws MessagingException {
206 if (parsed)
207 return;
208
209 initStream();
210
211 SharedInputStream sin = null;
212 if (in instanceof SharedInputStream) {
213 sin = (SharedInputStream)in;
214 }
215
216 String bnd = "--" + boundary;
217 byte[] bndbytes = ASCIIUtility.getBytes(bnd);
218 try {
219 parse(in, bndbytes, sin);
220 } catch (IOException ioex) {
221 throw new MessagingException("IO Error", ioex);
222 } catch (Exception ex) {
223 throw new MessagingException("Error", ex);
224 }
682 gss[j - 1] = i;
683 } else {
684 // No match. The array has already been
685 // filled up with correct values before.
686 continue NEXT;
687 }
688 }
689 while (j > 0) {
690 gss[--j] = i;
691 }
692 }
693 gss[l - 1] = 1;
694 }
695
696
697 /**
698 * Iterates through all the parts and outputs each Mime part
699 * separated by a boundary.
700 */
701
702 @Override
703 public void writeTo(OutputStream os)
704 throws IOException, MessagingException {
705
706 // inputStream was not null
707 if (in != null) {
708 contentType.setParameter("boundary", this.boundary);
709 }
710
711 String bnd = "--" + contentType.getParameter("boundary");
712 for (int i = 0; i < parts.size(); i++) {
713 OutputUtil.writeln(bnd, os); // put out boundary
714 parts.get(i).writeTo(os);
715 OutputUtil.writeln(os); // put out empty line
716 }
717
718 if (in != null) {
719 OutputUtil.writeln(bnd, os); // put out boundary
720 if ((os instanceof ByteOutputStream) && lazyAttachments) {
721 ((ByteOutputStream) os).write(in);
722 } else {
|