Skip to content

Package: Part

Part

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 jakarta.mail;
18:
19: import jakarta.activation.DataHandler;
20:
21: import java.io.IOException;
22: import java.io.InputStream;
23: import java.io.OutputStream;
24: import java.util.Enumeration;
25:
26: /**
27: * The <code>Part</code> interface is the common base interface for
28: * Messages and BodyParts. <p>
29: *
30: * Part consists of a set of attributes and a "Content".<p>
31: *
32: * <strong> Attributes: </strong> <p>
33: *
34: * The Jakarta Mail API defines a set of standard Part attributes that are
35: * considered to be common to most existing Mail systems. These
36: * attributes have their own settor and gettor methods. Mail systems
37: * may support other Part attributes as well, these are represented as
38: * name-value pairs where both the name and value are Strings.<p>
39: *
40: * <strong> Content: </strong> <p>
41: *
42: * The <strong>data type</strong> of the "content" is returned by
43: * the <code>getContentType()</code> method. The MIME typing system
44: * is used to name data types. <p>
45: *
46: * The "content" of a Part is available in various formats:
47: * <ul>
48: * <li> As a DataHandler - using the <code>getDataHandler()</code> method.
49: * The "content" of a Part is also available through a
50: * <code>jakarta.activation.DataHandler</code> object. The DataHandler
51: * object allows clients to discover the operations available on the
52: * content, and to instantiate the appropriate component to perform
53: * those operations.
54: *
55: * <li> As an input stream - using the <code>getInputStream()</code> method.
56: * Any mail-specific encodings are decoded before this stream is returned.
57: *
58: * <li> As a Java object - using the <code>getContent()</code> method.
59: * This method returns the "content" as a Java object.
60: * The returned object is of course dependent on the content
61: * itself. In particular, a "multipart" Part's content is always a
62: * Multipart or subclass thereof. That is, <code>getContent()</code> on a
63: * "multipart" type Part will always return a Multipart (or subclass) object.
64: * </ul>
65: *
66: * Part provides the <code>writeTo()</code> method that streams
67: * out its bytestream in mail-safe form suitable for transmission.
68: * This bytestream is typically an aggregation of the Part attributes
69: * and its content's bytestream. <p>
70: *
71: * Message and BodyPart implement the Part interface. Note that in
72: * MIME parlance, Part models an Entity (RFC 2045, Section 2.4).
73: *
74: * @author John Mani
75: */
76:
77: public interface Part {
78:
79: /**
80: * Return the size of the content of this part in bytes.
81: * Return -1 if the size cannot be determined. <p>
82: *
83: * Note that the size may not be an exact measure of the content
84: * size and may or may not account for any transfer encoding
85: * of the content. The size is appropriate for display in a
86: * user interface to give the user a rough idea of the size
87: * of this part.
88: *
89: * @return size of content in bytes
90: * @throws MessagingException for failures
91: */
92: int getSize() throws MessagingException;
93:
94: /**
95: * Return the number of lines in the content of this part.
96: * Return -1 if the number cannot be determined.
97: *
98: * Note that this number may not be an exact measure of the
99: * content length and may or may not account for any transfer
100: * encoding of the content.
101: *
102: * @return number of lines in the content.
103: * @throws MessagingException for failures
104: */
105: int getLineCount() throws MessagingException;
106:
107: /**
108: * Returns the Content-Type of the content of this part.
109: * Returns null if the Content-Type could not be determined. <p>
110: *
111: * The MIME typing system is used to name Content-types.
112: *
113: * @return The ContentType of this part
114: * @throws MessagingException for failures
115: * @see jakarta.activation.DataHandler
116: */
117: String getContentType() throws MessagingException;
118:
119: /**
120: * Is this Part of the specified MIME type? This method
121: * compares <strong>only the <code>primaryType</code> and
122: * <code>subType</code></strong>.
123: * The parameters of the content types are ignored. <p>
124: *
125: * For example, this method will return <code>true</code> when
126: * comparing a Part of content type <strong>"text/plain"</strong>
127: * with <strong>"text/plain; charset=foobar"</strong>. <p>
128: *
129: * If the <code>subType</code> of <code>mimeType</code> is the
130: * special character '*', then the subtype is ignored during the
131: * comparison.
132: *
133: * @param mimeType the MIME type to test
134: * @return true if this part is of the specified type
135: * @throws MessagingException for failures
136: */
137: boolean isMimeType(String mimeType) throws MessagingException;
138:
139: /**
140: * This part should be presented as an attachment.
141: *
142: * @see #getDisposition
143: * @see #setDisposition
144: */
145: String ATTACHMENT = "attachment";
146:
147: /**
148: * This part should be presented inline.
149: *
150: * @see #getDisposition
151: * @see #setDisposition
152: */
153: String INLINE = "inline";
154:
155: /**
156: * Return the disposition of this part. The disposition
157: * describes how the part should be presented to the user.
158: * (See RFC 2183.) The return value should be considered
159: * without regard to case. For example:
160: * <blockquote><pre>
161: * String disp = part.getDisposition();
162: * if (disp == null || disp.equalsIgnoreCase(Part.ATTACHMENT))
163: *         // treat as attachment if not first part
164: * </pre></blockquote>
165: *
166: * @return disposition of this part, or null if unknown
167: * @throws MessagingException for failures
168: * @see #ATTACHMENT
169: * @see #INLINE
170: * @see #getFileName
171: */
172: String getDisposition() throws MessagingException;
173:
174: /**
175: * Set the disposition of this part.
176: *
177: * @param disposition disposition of this part
178: * @throws IllegalWriteException if the underlying implementation
179: * does not support modification of this header
180: * @throws IllegalStateException if this Part is obtained
181: * from a READ_ONLY folder
182: * @throws MessagingException for other failures
183: * @see #ATTACHMENT
184: * @see #INLINE
185: * @see #setFileName
186: */
187: void setDisposition(String disposition) throws MessagingException;
188:
189: /**
190: * Return a description String for this part. This typically
191: * associates some descriptive information with this part.
192: * Returns null if none is available.
193: *
194: * @return description of this part
195: * @throws MessagingException for failures
196: */
197: String getDescription() throws MessagingException;
198:
199: /**
200: * Set a description String for this part. This typically
201: * associates some descriptive information with this part.
202: *
203: * @param description description of this part
204: * @throws IllegalWriteException if the underlying implementation
205: * does not support modification of this header
206: * @throws IllegalStateException if this Part is obtained
207: * from a READ_ONLY folder
208: * @throws MessagingException for other failures
209: */
210: void setDescription(String description) throws MessagingException;
211:
212: /**
213: * Get the filename associated with this part, if possible.
214: * Useful if this part represents an "attachment" that was
215: * loaded from a file. The filename will usually be a simple
216: * name, not including directory components.
217: *
218: * @return Filename to associate with this part
219: * @throws MessagingException for failures
220: */
221: String getFileName() throws MessagingException;
222:
223: /**
224: * Set the filename associated with this part, if possible.
225: * Useful if this part represents an "attachment" that was
226: * loaded from a file. The filename will usually be a simple
227: * name, not including directory components.
228: *
229: * @param filename Filename to associate with this part
230: * @throws IllegalWriteException if the underlying implementation
231: * does not support modification of this header
232: * @throws IllegalStateException if this Part is obtained
233: * from a READ_ONLY folder
234: * @throws MessagingException for other failures
235: */
236: void setFileName(String filename) throws MessagingException;
237:
238: /**
239: * Return an input stream for this part's "content". Any
240: * mail-specific transfer encodings will be decoded before the
241: * input stream is provided. <p>
242: *
243: * This is typically a convenience method that just invokes
244: * the DataHandler's <code>getInputStream()</code> method.
245: *
246: * @return an InputStream
247: * @throws IOException this is typically thrown by the
248: * DataHandler. Refer to the documentation for
249: * jakarta.activation.DataHandler for more details.
250: * @throws MessagingException for other failures
251: * @see #getDataHandler
252: * @see jakarta.activation.DataHandler#getInputStream
253: */
254: InputStream getInputStream()
255: throws IOException, MessagingException;
256:
257: /**
258: * Return a DataHandler for the content within this part. The
259: * DataHandler allows clients to operate on as well as retrieve
260: * the content.
261: *
262: * @return DataHandler for the content
263: * @throws MessagingException for failures
264: */
265: DataHandler getDataHandler() throws MessagingException;
266:
267: /**
268: * Return the content as a Java object. The type of the returned
269: * object is of course dependent on the content itself. For example,
270: * the object returned for "text/plain" content is usually a String
271: * object. The object returned for a "multipart" content is always a
272: * Multipart subclass. For content-types that are unknown to the
273: * DataHandler system, an input stream is returned as the content <p>
274: *
275: * This is a convenience method that just invokes the DataHandler's
276: * getContent() method
277: *
278: * @return Object
279: * @throws IOException this is typically thrown by the
280: * DataHandler. Refer to the documentation for
281: * jakarta.activation.DataHandler for more details.
282: * @throws MessagingException for other failures
283: * @see jakarta.activation.DataHandler#getContent
284: */
285: Object getContent() throws IOException, MessagingException;
286:
287: /**
288: * This method provides the mechanism to set this part's content.
289: * The DataHandler wraps around the actual content.
290: *
291: * @param dh The DataHandler for the content.
292: * @throws IllegalWriteException if the underlying implementation
293: * does not support modification of existing values
294: * @throws IllegalStateException if this Part is obtained
295: * from a READ_ONLY folder
296: * @throws MessagingException for other failures
297: */
298: void setDataHandler(DataHandler dh) throws MessagingException;
299:
300: /**
301: * A convenience method for setting this part's content. The part
302: * internally wraps the content in a DataHandler. <p>
303: *
304: * Note that a DataContentHandler class for the specified type should
305: * be available to the Jakarta Mail implementation for this to work right.
306: * i.e., to do <code>setContent(foobar, "application/x-foobar")</code>,
307: * a DataContentHandler for "application/x-foobar" should be installed.
308: * Refer to the Java Activation Framework for more information.
309: *
310: * @param obj A java object.
311: * @param type MIME type of this object.
312: * @throws IllegalWriteException if the underlying implementation
313: * does not support modification of existing values
314: * @throws IllegalStateException if this Part is obtained
315: * from a READ_ONLY folder
316: * @throws MessagingException for other failures
317: */
318: void setContent(Object obj, String type)
319: throws MessagingException;
320:
321: /**
322: * A convenience method that sets the given String as this
323: * part's content with a MIME type of "text/plain".
324: *
325: * @param text The text that is the Message's content.
326: * @throws IllegalWriteException if the underlying
327: * implementation does not support modification of
328: * existing values
329: * @throws IllegalStateException if this Part is obtained
330: * from a READ_ONLY folder
331: * @throws MessagingException for other failures
332: */
333: void setText(String text) throws MessagingException;
334:
335: /**
336: * This method sets the given Multipart object as this message's
337: * content.
338: *
339: * @param mp The multipart object that is the Message's content
340: * @throws IllegalWriteException if the underlying
341: * implementation        does not support modification of
342: * existing values
343: * @throws IllegalStateException if this Part is obtained
344: * from a READ_ONLY folder
345: * @throws MessagingException for other failures
346: */
347: void setContent(Multipart mp) throws MessagingException;
348:
349: /**
350: * Output a bytestream for this Part. This bytestream is
351: * typically an aggregration of the Part attributes and
352: * an appropriately encoded bytestream from its 'content'. <p>
353: *
354: * Classes that implement the Part interface decide on
355: * the appropriate encoding algorithm to be used. <p>
356: *
357: * The bytestream is typically used for sending.
358: *
359: * @param os the stream to write to
360: * @throws IOException if an error occurs writing to the
361: * stream or if an error is generated
362: * by the jakarta.activation layer.
363: * @throws MessagingException if an error occurs fetching the
364: * data to be written
365: * @see jakarta.activation.DataHandler#writeTo
366: */
367: void writeTo(OutputStream os) throws IOException, MessagingException;
368:
369: /**
370: * Get all the headers for this header name. Returns <code>null</code>
371: * if no headers for this header name are available.
372: *
373: * @param header_name the name of this header
374: * @return the value fields for all headers with
375: * this name
376: * @throws MessagingException for failures
377: */
378: String[] getHeader(String header_name)
379: throws MessagingException;
380:
381: /**
382: * Set the value for this header_name. Replaces all existing
383: * header values with this new value.
384: *
385: * @param header_name the name of this header
386: * @param header_value the value for this header
387: * @throws IllegalWriteException if the underlying
388: * implementation does not support modification
389: * of existing values
390: * @throws IllegalStateException if this Part is
391: * obtained from a READ_ONLY folder
392: * @throws MessagingException for other failures
393: */
394: void setHeader(String header_name, String header_value)
395: throws MessagingException;
396:
397: /**
398: * Add this value to the existing values for this header_name.
399: *
400: * @param header_name the name of this header
401: * @param header_value the value for this header
402: * @throws IllegalWriteException if the underlying
403: * implementation does not support modification
404: * of existing values
405: * @throws IllegalStateException if this Part is
406: * obtained from a READ_ONLY folder
407: * @throws MessagingException for other failures
408: */
409: void addHeader(String header_name, String header_value)
410: throws MessagingException;
411:
412: /**
413: * Remove all headers with this name.
414: *
415: * @param header_name the name of this header
416: * @throws IllegalWriteException if the underlying
417: * implementation does not support modification
418: * of existing values
419: * @throws IllegalStateException if this Part is
420: * obtained from a READ_ONLY folder
421: * @throws MessagingException for other failures
422: */
423: void removeHeader(String header_name)
424: throws MessagingException;
425:
426: /**
427: * Return all the headers from this part as an Enumeration of
428: * Header objects.
429: *
430: * @return enumeration of Header objects
431: * @throws MessagingException for failures
432: */
433: Enumeration<Header> getAllHeaders() throws MessagingException;
434:
435: /**
436: * Return matching headers from this part as an Enumeration of
437: * Header objects.
438: *
439: * @param header_names the headers to match
440: * @return enumeration of Header objects
441: * @throws MessagingException for failures
442: */
443: Enumeration<Header> getMatchingHeaders(String[] header_names)
444: throws MessagingException;
445:
446: /**
447: * Return non-matching headers from this envelope as an Enumeration
448: * of Header objects.
449: *
450: * @param header_names the headers to not match
451: * @return enumeration of Header objects
452: * @throws MessagingException for failures
453: */
454: Enumeration<Header> getNonMatchingHeaders(String[] header_names)
455: throws MessagingException;
456: }