1 /*
2 * Copyright (c) 1997, 2014, 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
76
77 //BM MimeMultipart can extend this
78 public class MimeMultipart {
79
80 /**
81 * The DataSource supplying our InputStream.
82 */
83 protected DataSource ds = null;
84
85 /**
86 * Have we parsed the data from our InputStream yet?
87 * Defaults to true; set to false when our constructor is
88 * given a DataSource with an InputStream that we need to
89 * parse.
90 */
91 protected boolean parsed = true;
92
93 /**
94 * Vector of MimeBodyPart objects.
95 */
96 protected FinalArrayList parts = new FinalArrayList(); // Holds BodyParts
97
98 /**
99 * This field specifies the content-type of this multipart
100 * object. It defaults to "multipart/mixed".
101 */
102 protected ContentType contentType;
103
104 /**
105 * The <code>MimeBodyPart</code> containing this <code>MimeMultipart</code>,
106 * if known.
107 * @since JavaMail 1.1
108 */
109 protected MimeBodyPart parent;
110
111 protected static final boolean ignoreMissingEndBoundary;
112 static {
113 ignoreMissingEndBoundary = SAAJUtil.getSystemBoolean("saaj.mime.multipart.ignoremissingendboundary");
114 }
115
116 /**
195 parse();
196 if (parts == null)
197 return 0;
198
199 return parts.size();
200 }
201
202 /**
203 * Get the specified MimeBodyPart. BodyParts are numbered starting at 0.
204 *
205 * @param index the index of the desired MimeBodyPart
206 * @return the MimeBodyPart
207 * @exception MessagingException if no such MimeBodyPart exists
208 */
209 public MimeBodyPart getBodyPart(int index)
210 throws MessagingException {
211 parse();
212 if (parts == null)
213 throw new IndexOutOfBoundsException("No such BodyPart");
214
215 return (MimeBodyPart)parts.get(index);
216 }
217
218 /**
219 * Get the MimeBodyPart referred to by the given ContentID (CID).
220 * Returns null if the part is not found.
221 *
222 * @param CID the ContentID of the desired part
223 * @return the MimeBodyPart
224 */
225 public MimeBodyPart getBodyPart(String CID)
226 throws MessagingException {
227 parse();
228
229 int count = getCount();
230 for (int i = 0; i < count; i++) {
231 MimeBodyPart part = getBodyPart(i);
232 String s = part.getContentID();
233 // Old versions of AXIS2 put angle brackets around the content
234 // id but not the start param
235 String sNoAngle = (s!= null) ? s.replaceFirst("^<", "").replaceFirst(">$", "")
242
243 /**
244 * Update headers. The default implementation here just
245 * calls the <code>updateHeaders</code> method on each of its
246 * children BodyParts. <p>
247 *
248 * Note that the boundary parameter is already set up when
249 * a new and empty MimeMultipart object is created. <p>
250 *
251 * This method is called when the <code>saveChanges</code>
252 * method is invoked on the Message object containing this
253 * MimeMultipart. This is typically done as part of the Message
254 * send process, however note that a client is free to call
255 * it any number of times. So if the header updating process is
256 * expensive for a specific MimeMultipart subclass, then it
257 * might itself want to track whether its internal state actually
258 * did change, and do the header updating only if necessary.
259 */
260 protected void updateHeaders() throws MessagingException {
261 for (int i = 0; i < parts.size(); i++)
262 ((MimeBodyPart)parts.get(i)).updateHeaders();
263 }
264
265 /**
266 * Iterates through all the parts and outputs each Mime part
267 * separated by a boundary.
268 */
269 public void writeTo(OutputStream os)
270 throws IOException, MessagingException {
271 parse();
272
273 String boundary = "--" + contentType.getParameter("boundary");
274
275 for (int i = 0; i < parts.size(); i++) {
276 OutputUtil.writeln(boundary, os); // put out boundary
277 getBodyPart(i).writeTo(os);
278 OutputUtil.writeln(os); // put out empty line
279 }
280
281 // put out last boundary
282 OutputUtil.writeAsAscii(boundary, os);
579 if (parts == null)
580 throw new MessagingException("No such body part");
581
582 boolean ret = parts.remove(part);
583 part.setParent(null);
584 return ret;
585 }
586
587 /**
588 * Remove the part at specified location (starting from 0).
589 * Shifts all the parts after the removed part down one.
590 *
591 * @param index Index of the part to remove
592 * @exception IndexOutOfBoundsException if the given index
593 * is out of range.
594 */
595 public void removeBodyPart(int index) {
596 if (parts == null)
597 throw new IndexOutOfBoundsException("No such BodyPart");
598
599 MimeBodyPart part = (MimeBodyPart)parts.get(index);
600 parts.remove(index);
601 part.setParent(null);
602 }
603
604 /**
605 * Adds a MimeBodyPart to the multipart. The MimeBodyPart is appended to
606 * the list of existing Parts.
607 *
608 * @param part The MimeBodyPart to be appended
609 */
610 public synchronized void addBodyPart(MimeBodyPart part) {
611 if (parts == null)
612 parts = new FinalArrayList();
613
614 parts.add(part);
615 part.setParent(this);
616 }
617
618 /**
619 * Adds a MimeBodyPart at position <code>index</code>.
620 * If <code>index</code> is not the last one in the list,
621 * the subsequent parts are shifted up. If <code>index</code>
622 * is larger than the number of parts present, the
623 * MimeBodyPart is appended to the end.
624 *
625 * @param part The MimeBodyPart to be inserted
626 * @param index Location where to insert the part
627 */
628 public synchronized void addBodyPart(MimeBodyPart part, int index) {
629 if (parts == null)
630 parts = new FinalArrayList();
631
632 parts.add(index,part);
633 part.setParent(this);
634 }
635
636 /**
637 * Return the <code>MimeBodyPart</code> that contains this <code>MimeMultipart</code>
638 * object, or <code>null</code> if not known.
639 * @since JavaMail 1.1
640 */
641 MimeBodyPart getParent() {
642 return parent;
643 }
644
645 /**
646 * Set the parent of this <code>MimeMultipart</code> to be the specified
647 * <code>MimeBodyPart</code>. Normally called by the <code>Message</code>
648 * or <code>MimeBodyPart</code> <code>setContent(MimeMultipart)</code> method.
649 * <code>parent</code> may be <code>null</code> if the
650 * <code>MimeMultipart</code> is being removed from its containing
|
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
76
77 //BM MimeMultipart can extend this
78 public class MimeMultipart {
79
80 /**
81 * The DataSource supplying our InputStream.
82 */
83 protected DataSource ds = null;
84
85 /**
86 * Have we parsed the data from our InputStream yet?
87 * Defaults to true; set to false when our constructor is
88 * given a DataSource with an InputStream that we need to
89 * parse.
90 */
91 protected boolean parsed = true;
92
93 /**
94 * Vector of MimeBodyPart objects.
95 */
96 protected FinalArrayList<MimeBodyPart> parts = new FinalArrayList<MimeBodyPart>(); // Holds BodyParts
97
98 /**
99 * This field specifies the content-type of this multipart
100 * object. It defaults to "multipart/mixed".
101 */
102 protected ContentType contentType;
103
104 /**
105 * The <code>MimeBodyPart</code> containing this <code>MimeMultipart</code>,
106 * if known.
107 * @since JavaMail 1.1
108 */
109 protected MimeBodyPart parent;
110
111 protected static final boolean ignoreMissingEndBoundary;
112 static {
113 ignoreMissingEndBoundary = SAAJUtil.getSystemBoolean("saaj.mime.multipart.ignoremissingendboundary");
114 }
115
116 /**
195 parse();
196 if (parts == null)
197 return 0;
198
199 return parts.size();
200 }
201
202 /**
203 * Get the specified MimeBodyPart. BodyParts are numbered starting at 0.
204 *
205 * @param index the index of the desired MimeBodyPart
206 * @return the MimeBodyPart
207 * @exception MessagingException if no such MimeBodyPart exists
208 */
209 public MimeBodyPart getBodyPart(int index)
210 throws MessagingException {
211 parse();
212 if (parts == null)
213 throw new IndexOutOfBoundsException("No such BodyPart");
214
215 return parts.get(index);
216 }
217
218 /**
219 * Get the MimeBodyPart referred to by the given ContentID (CID).
220 * Returns null if the part is not found.
221 *
222 * @param CID the ContentID of the desired part
223 * @return the MimeBodyPart
224 */
225 public MimeBodyPart getBodyPart(String CID)
226 throws MessagingException {
227 parse();
228
229 int count = getCount();
230 for (int i = 0; i < count; i++) {
231 MimeBodyPart part = getBodyPart(i);
232 String s = part.getContentID();
233 // Old versions of AXIS2 put angle brackets around the content
234 // id but not the start param
235 String sNoAngle = (s!= null) ? s.replaceFirst("^<", "").replaceFirst(">$", "")
242
243 /**
244 * Update headers. The default implementation here just
245 * calls the <code>updateHeaders</code> method on each of its
246 * children BodyParts. <p>
247 *
248 * Note that the boundary parameter is already set up when
249 * a new and empty MimeMultipart object is created. <p>
250 *
251 * This method is called when the <code>saveChanges</code>
252 * method is invoked on the Message object containing this
253 * MimeMultipart. This is typically done as part of the Message
254 * send process, however note that a client is free to call
255 * it any number of times. So if the header updating process is
256 * expensive for a specific MimeMultipart subclass, then it
257 * might itself want to track whether its internal state actually
258 * did change, and do the header updating only if necessary.
259 */
260 protected void updateHeaders() throws MessagingException {
261 for (int i = 0; i < parts.size(); i++)
262 parts.get(i).updateHeaders();
263 }
264
265 /**
266 * Iterates through all the parts and outputs each Mime part
267 * separated by a boundary.
268 */
269 public void writeTo(OutputStream os)
270 throws IOException, MessagingException {
271 parse();
272
273 String boundary = "--" + contentType.getParameter("boundary");
274
275 for (int i = 0; i < parts.size(); i++) {
276 OutputUtil.writeln(boundary, os); // put out boundary
277 getBodyPart(i).writeTo(os);
278 OutputUtil.writeln(os); // put out empty line
279 }
280
281 // put out last boundary
282 OutputUtil.writeAsAscii(boundary, os);
579 if (parts == null)
580 throw new MessagingException("No such body part");
581
582 boolean ret = parts.remove(part);
583 part.setParent(null);
584 return ret;
585 }
586
587 /**
588 * Remove the part at specified location (starting from 0).
589 * Shifts all the parts after the removed part down one.
590 *
591 * @param index Index of the part to remove
592 * @exception IndexOutOfBoundsException if the given index
593 * is out of range.
594 */
595 public void removeBodyPart(int index) {
596 if (parts == null)
597 throw new IndexOutOfBoundsException("No such BodyPart");
598
599 MimeBodyPart part = parts.get(index);
600 parts.remove(index);
601 part.setParent(null);
602 }
603
604 /**
605 * Adds a MimeBodyPart to the multipart. The MimeBodyPart is appended to
606 * the list of existing Parts.
607 *
608 * @param part The MimeBodyPart to be appended
609 */
610 public synchronized void addBodyPart(MimeBodyPart part) {
611 if (parts == null)
612 parts = new FinalArrayList<MimeBodyPart>();
613
614 parts.add(part);
615 part.setParent(this);
616 }
617
618 /**
619 * Adds a MimeBodyPart at position <code>index</code>.
620 * If <code>index</code> is not the last one in the list,
621 * the subsequent parts are shifted up. If <code>index</code>
622 * is larger than the number of parts present, the
623 * MimeBodyPart is appended to the end.
624 *
625 * @param part The MimeBodyPart to be inserted
626 * @param index Location where to insert the part
627 */
628 public synchronized void addBodyPart(MimeBodyPart part, int index) {
629 if (parts == null)
630 parts = new FinalArrayList<MimeBodyPart>();
631
632 parts.add(index,part);
633 part.setParent(this);
634 }
635
636 /**
637 * Return the <code>MimeBodyPart</code> that contains this <code>MimeMultipart</code>
638 * object, or <code>null</code> if not known.
639 * @since JavaMail 1.1
640 */
641 MimeBodyPart getParent() {
642 return parent;
643 }
644
645 /**
646 * Set the parent of this <code>MimeMultipart</code> to be the specified
647 * <code>MimeBodyPart</code>. Normally called by the <code>Message</code>
648 * or <code>MimeBodyPart</code> <code>setContent(MimeMultipart)</code> method.
649 * <code>parent</code> may be <code>null</code> if the
650 * <code>MimeMultipart</code> is being removed from its containing
|