Skip to content

Package: SunV3Multipart

SunV3Multipart

nameinstructionbranchcomplexitylinemethod
SunV3Multipart(DataSource)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
getBodyPart(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
parse()
M: 183 C: 0
0%
M: 40 C: 0
0%
M: 21 C: 0
0%
M: 52 C: 0
0%
M: 1 C: 0
0%
setSubType(String)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
updateHeaders()
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
writeTo(OutputStream)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.eclipse.angus.mail.mbox;
18:
19: import jakarta.activation.DataSource;
20: import jakarta.mail.BodyPart;
21: import jakarta.mail.MessagingException;
22: import jakarta.mail.MethodNotSupportedException;
23: import jakarta.mail.internet.InternetHeaders;
24: import jakarta.mail.internet.MimeMultipart;
25: import org.eclipse.angus.mail.util.LineInputStream;
26:
27: import java.io.BufferedInputStream;
28: import java.io.ByteArrayInputStream;
29: import java.io.ByteArrayOutputStream;
30: import java.io.IOException;
31: import java.io.InputStream;
32: import java.io.OutputStream;
33: import java.nio.charset.StandardCharsets;
34:
35: /**
36: * The SunV3Multipart class is an implementation of the abstract Multipart
37: * class that uses SunV3 conventions for the multipart data. <p>
38: *
39: * @author Bill Shannon
40: */
41:
42: public class SunV3Multipart extends MimeMultipart {
43: private boolean parsing;
44:
45: /**
46: * Constructs a SunV3Multipart object and its bodyparts from the
47: * given DataSource. <p>
48: *
49: * @param ds DataSource, can be a MultipartDataSource
50: */
51: public SunV3Multipart(DataSource ds) throws MessagingException {
52: super(ds);
53: }
54:
55: /**
56: * Set the subtype. Throws MethodNotSupportedException.
57: *
58: * @param subtype Subtype
59: */
60: public void setSubType(String subtype) throws MessagingException {
61: throw new MethodNotSupportedException(
62: "can't change SunV3Multipart subtype");
63: }
64:
65: /**
66: * Get the BodyPart referred to by the given ContentID (CID).
67: * Throws MethodNotSupportException.
68: */
69: public synchronized BodyPart getBodyPart(String CID)
70: throws MessagingException {
71: throw new MethodNotSupportedException(
72: "SunV3Multipart doesn't support Content-ID");
73: }
74:
75: /**
76: * Update headers. Throws MethodNotSupportException.
77: */
78: protected void updateHeaders() throws MessagingException {
79: throw new MethodNotSupportedException("SunV3Multipart not writable");
80: }
81:
82: /**
83: * Iterates through all the parts and outputs each SunV3 part
84: * separated by a boundary.
85: */
86: public void writeTo(OutputStream os)
87: throws IOException, MessagingException {
88: throw new MethodNotSupportedException(
89: "SunV3Multipart writeTo not supported");
90: }
91:
92: private static final String boundary = "----------";
93:
94: /*
95: * Parse the contents of this multipart message and create the
96: * child body parts.
97: */
98: protected synchronized void parse() throws MessagingException {
99: /*
100: * If the data has already been parsed, or we're in the middle of
101: * parsing it, there's nothing to do. The latter will occur when
102: * we call addBodyPart, which will call parse again. We really
103: * want to be able to call super.super.addBodyPart.
104: */
105:• if (parsed || parsing)
106: return;
107:
108: InputStream in = null;
109:
110: try {
111: in = ds.getInputStream();
112:• if (!(in instanceof ByteArrayInputStream) &&
113: !(in instanceof BufferedInputStream))
114: in = new BufferedInputStream(in);
115: } catch (IOException | RuntimeException ex) {
116: throw new MessagingException("No inputstream from datasource");
117: }
118:
119: byte[] bndbytes = boundary.getBytes(StandardCharsets.ISO_8859_1);
120: int bl = bndbytes.length;
121:
122: String line;
123: parsing = true;
124: try {
125: /*
126: * Skip any kind of junk until we get to the first
127: * boundary line.
128: */
129: LineInputStream lin = new LineInputStream(in);
130:• while ((line = lin.readLine()) != null) {
131:• if (line.trim().equals(boundary))
132: break;
133: }
134:• if (line == null)
135: throw new MessagingException("Missing start boundary");
136:
137: /*
138: * Read and process body parts until we see the
139: * terminating boundary line (or EOF).
140: */
141: for (; ; ) {
142: /*
143: * Collect the headers for this body part.
144: */
145: InternetHeaders headers = new InternetHeaders(in);
146:
147:• if (!in.markSupported())
148: throw new MessagingException("Stream doesn't support mark");
149:
150: ByteArrayOutputStream buf = new ByteArrayOutputStream();
151: int b;
152:
153: /*
154: * Read and save the content bytes in buf.
155: */
156:• while ((b = in.read()) >= 0) {
157:• if (b == '\r' || b == '\n') {
158: /*
159: * Found the end of a line, check whether the
160: * next line is a boundary.
161: */
162: int i;
163: in.mark(bl + 4 + 1); // "4" for possible "--\r\n"
164:• if (b == '\r' && in.read() != '\n') {
165: in.reset();
166: in.mark(bl + 4);
167: }
168: // read bytes, matching against the boundary
169:• for (i = 0; i < bl; i++)
170:• if (in.read() != bndbytes[i])
171: break;
172:• if (i == bl) {
173: int b2 = in.read();
174: // check for end of line
175:• if (b2 == '\n')
176: break; // got it! break out of the while loop
177:• if (b2 == '\r') {
178: in.mark(1);
179:• if (in.read() != '\n')
180: in.reset();
181: break; // got it! break out of the while loop
182: }
183: }
184: // failed to match, reset and proceed normally
185: in.reset();
186: }
187: buf.write(b);
188: }
189:
190: /*
191: * Create a SunV3BodyPart to represent this body part.
192: */
193: SunV3BodyPart body =
194: new SunV3BodyPart(headers, buf.toByteArray());
195: addBodyPart(body);
196:• if (b < 0)
197: break;
198: }
199: } catch (IOException e) {
200: throw new MessagingException("IO Error"); // XXX
201: } finally {
202: parsing = false;
203: }
204:
205: parsed = true;
206: }
207: }