JavaMail-1.1-changes.txt
上传用户:dinglihq
上传日期:2013-02-04
资源大小:99958k
文件大小:23k
源码类别:

Java编程

开发平台:

Java

  1. JavaMail 1.1
  2. ============
  3. Following is a description of the new APIs that are being
  4. introduced in JavaMail 1.1
  5. Please send comments and feedback to javamail@sun.com
  6. (1) MessageContext
  7. ==================
  8. In some cases it is desirable for the object representing the content
  9. of a BodyPart to know something about the "context" in which it is
  10. operating, e.g., what other data is contained in the same Multipart
  11. object, who sent the message containing the data, etc.  This allows
  12. for more interesting content types that know more about the message
  13. containing them and the mail system in general.
  14. Some uses of multipart/related might require these capabilities.
  15. For instance, the handler for a text/html body part contained in a
  16. multipart/related object might need to know about the containing
  17. object in order to find the related image data needed to display the
  18. HTML document.
  19. There is one particular case in the current implementation where
  20. this need arises.  (This is a bug in the current release.)  When
  21. constructing a MimeMessage object for a nested message contained
  22. in another message, the DataContentHandler needs the Session
  23. object in order to construct the new MimeMessage object.
  24. To solve these problems we introduce a new class, a new interface,
  25. and a number of new methods.
  26. The MessageContext class provides the basic information about the
  27. "context" in which a content object is operating:
  28. /**
  29.  * The context in which a piece of Message content is contained.  A
  30.  * <code>MessageContext</code> object is returned by the
  31.  * <code>getMessageContext</code> method of the
  32.  * <code>MessageAware</code> interface.  <code>MessageAware</code> is
  33.  * typically implemented by <code>DataSources</code> to allow a
  34.  * <code>DataContentHandler</code> to pass on information about the
  35.  * context in which a data content object is operating.
  36.  *
  37.  * @see javax.mail.MessageAware
  38.  * @see javax.activation.DataSource
  39.  * @see javax.activation.DataContentHandler
  40.  */
  41. public class MessageContext {
  42.     /**
  43.      * Create a MessageContext object describing the context of the 
  44.      * given Part.
  45.      */
  46.     public MessageContext(Part part)
  47.     /**
  48.      * Return the Part that contains the content.
  49.      *
  50.      * @return the containing Part, or null if not known
  51.      */
  52.     public Part getPart()
  53.     /**
  54.      * Return the Message that contains the content.
  55.      * Follows the parent chain up through containing Multipart
  56.      * objects until it comes to a Message object, or null.
  57.      *
  58.      * @return the containing Message, or null if not known
  59.      */
  60.     public Message getMessage()
  61.     /**
  62.      * Return the Session we're operating in.
  63.      *
  64.      * @return the Session, or null if not known
  65.      */
  66.     public Session getSession()
  67. }
  68. A MessageContext object can be obtained by a DataContentHandler from a
  69. DataSource that also implements the MessageAware interface:
  70. /**
  71.  * An interface optionally implemented by <code>DataSources</code> to
  72.  * supply information to a <code>DataContentHandler</code> about the
  73.  * message context in which the data content object is operating.
  74.  *
  75.  * @see javax.mail.MessageContext
  76.  * @see javax.activation.DataSource
  77.  * @see javax.activation.DataContentHandler
  78.  */
  79. public interface MessageAware {
  80.     /**
  81.      * Return the message context.
  82.      */
  83.     public MessageContext getMessageContext();
  84. }
  85. This new interface and class provides the basic information needed by
  86. the DataContentHandler to use in constructing more "interesting" objects
  87. representing a particular type of data.
  88. To allow navigation up the chain of components contained in a Message,
  89. we add the following methods.
  90. First, on BodyPart we add:
  91.     /**
  92.      * The <code>Multipart</code> object containing this 
  93.      * <code>BodyPart</code>, if known.
  94.      */
  95.     protected Multipart parent;
  96.     /**
  97.      * Return the containing <code>Multipart</code> object,
  98.      * or <code>null</code> if not known.
  99.      */
  100.     public Multipart getParent()
  101. On Multipart we add:
  102.     /**
  103.      * The <code>Part</code> containing this <code>Multipart</code>,
  104.      * if known.
  105.      */
  106.     protected Part parent;
  107.     /**
  108.      * Return the <code>Part</code> that contains this
  109.      * (cod<code>Multipart</c object, or <code>null</code> if not known.
  110.      */
  111.     public Part getParent()
  112.     /**
  113.      * Set the parent of this <code>Multipart</code> to be the specified
  114.      * <code>Part</code>.  Normally called by the <code>Message</code>
  115.      * or <code>BodyPart</code> <code>setContent(Multipart)</code>
  116.      * method. <p>
  117.      *
  118.      * <code>parent</code> may be <code>null</code> if the
  119.      * <code>Multipart</code> is being removed from its containing
  120.      * <code>Part</code>.
  121.      */
  122.     public void setParent(Part parent)
  123. To enable this new functionality we change the implementations of
  124. MimeBodyPart, MimeMessage, and MimeMultipart to maintain the "parent"
  125. links where possible.  We also change MimePartDataSource to implement
  126. the MessageAware interface.
  127. ===================================================================
  128. (2) MessageID
  129. =============
  130. The MimeMessage class requires a getMessageID() method.
  131. The client can now fetch it as a header, but since this is a "standard"
  132. RFC822 header, we want to provide an easier access method. 
  133. An added benefit is that protocols like IMAP, which provide this info
  134. as part of the ENVELOPE structure, can implement this method much more
  135. efficiently.
  136.  /**
  137.   * Returns the value of the "Message-ID" header field. Returns
  138.   * null if this field is unavailable or its value is absent. <p>
  139.   *
  140.   * The default implementation provided here uses the
  141.   * <code>getHeader()</code> method to return the value of the
  142.   * "Message-ID" field.
  143.   *
  144.   * @return  Message-ID
  145.   * @exception MessagingException, if the retrieval of this field
  146.   * causes any exception.
  147.   * @see javax.mail.search.MessageIDTerm
  148.   */
  149.   public String getMessageID() throws MessagingException;
  150. ===================================================================
  151. (3) UIDFolder
  152. =============
  153. The following methods in the UIDFolder interface have certain problems.
  154. We are proposing changes that will fix these problems. These are
  155. binary incompatible changes, but we think these changes are necessary for
  156. this interface to work in a useful manner. We are also not aware of
  157. anyone that has shipped a Store Provider that implements this interface,
  158. so we are hoping that the effect of this change is minimal (non-existent).
  159. (1) Message getMessageByUID(long uid)
  160. Description:
  161. Get the Message corresponding to the given UID. If no such
  162. message exists, the java.util.NoSuchElementException is thrown.
  163. Problem:
  164. A disconnected client can have a stash of UIDs from a
  165. previous session. Some of these UIDs may have been expunged from the
  166. server, but the disconnected client does not know this. It is quite
  167. reasonable (and expected) for a disconnected client to use this
  168. method when reconnecting - to check whether a UID is valid or not at
  169. the server.
  170. Since failure is an expected result here, using a
  171. RunTimeException to indicate it, seems wrong and counter-intuitive for
  172. the client.
  173. Solution:
  174. Our solution is to allow this method to return null to indicate
  175. that the requested UID is not valid anymore. Thus, this method will no
  176. longer throw the java.util.NoSuchElementException.
  177. (2)  Message[] getMessagesByUID(long start, long end)
  178. Description:
  179. Get the Messages corresponding to the given UID range. If any
  180. UID is invalid, the java.util.NoSuchElementException is thrown.
  181. Problem:
  182. Similar, but worse than (1). We think that disconnected clients
  183. (or clients that prefer to use UIDs) may issue 
  184. getMessagesByUID(1, LASTUID) 
  185. to get all the Messages at the server, especially when the client does
  186. not know the exact UIDs for this folder. In this case, we certainly
  187. do not want this method to fail if some id in the given range is 
  188. not a valid UID; rather we want it to return all available Messages from
  189. the server.
  190. Solution:
  191. Our solution is to remove the NoSuchElementException exception
  192. and allow this method to return Message objects in the given range.
  193. (3) Message[] getMessagesByUID(long[] uids)
  194. Description:
  195. Get the Messages corresponding to the given UID range. If any
  196. UID is invalid, the java.util.NoSuchElementException is thrown.
  197. Problem:
  198. Identical to (1).
  199. A disconnected client can have a stash of UIDs from a
  200. previous session. Some of these UIDs may have been expunged from the
  201. server, but the disconnected client does not know this. It is quite
  202. reasonable (and expected) for a disconnected client to use this
  203. method when reconnecting - to check whether a set of UIDs are valid
  204. or not at the server.
  205. Since failure can be an expected result, using a
  206. RunTimeException to indicate it, seems wrong and counter-intuitive for
  207. the client.
  208. Solution:
  209. Our solution is to allow this method to return null entries
  210. to indicate that a requested UID is not valid anymore. Thus, the
  211. message array returned by this method can have null entries for the
  212. invalid UIDs; and this method will no longer throw the 
  213. java.util.NoSuchElementException.
  214. Note that the size of the returned Message array is the same
  215. as the size of the request array of UIDs, and that each entry in the
  216. Message array corresponds to the same index entry in the UID array.
  217. ===================================================================
  218. (4) InternetAddress
  219. ===================
  220. The InternetAddress class needs the following protected field to
  221. properly support encoding of the "personal name".
  222. protected String encodedPersonal; // the encoded personal name
  223. No other API changes are associated with this. 
  224. This is a binary compatible change to JavaMail 1.0. However, there is
  225. a potential problem for any existing InternetAddress subclasses, which
  226. can cause them to break. This typically will affect only providers,
  227. not clients.
  228. Details:
  229. -------
  230. The InternetAddress implementation will use this field to store the
  231. encoded personal name. 
  232. The getPersonal() method will return the protected
  233. 'personal' field; if this field is null, it will check the 'encodedPersonal'
  234. field and decode its value and return it.
  235. The toString() method will use the protected 'encodedPersonal'
  236. field to create the RFC2047 compliant address string. If this field is
  237. null, it will check the 'personal' field, encode that if necessary and
  238. use it.
  239. This implies that, if an InternetAddress subclass changes either 
  240. the 'personal' or 'encodedPersonal' fields,  it should set the other
  241. to null to force its recomputation. Unfortunately, this also implies
  242. that existing subclasses of InternetAddress that directly set the
  243. 'personal' field can break in certain situations.
  244. We feel that the risk of this happening is minimal, since we
  245. don't expect that our users have subclassed InternetAddress. Also, this
  246. is necessary to properly support encoded personal names, so we feel that
  247. this has to be done.
  248. ================================================================
  249. (5) MimeCharset
  250. ================
  251. A utility method to convert java charsets into MIME charsets is
  252. needed.
  253. The JDK supports a variety of charsets. The JDK has names for these
  254. charsets, unfortunately they dont always match to their MIME or IANA
  255. equivalents. 
  256. It is necessary in some cases, (especially for providers) to map the
  257. JDK charset names into their MIME or IANA equivalents. This method does
  258. that.
  259. The API:
  260. -------
  261. This is a new static method to the javax.mail.internet.MimeUtility class
  262. /**
  263.  * Convert a java charset into its MIME charset name. <p>
  264.  *
  265.  * Note that a future version of JDK (post 1.2) might provide
  266.  * this functionality, in which case, we might deprecate this
  267.  * method then.
  268.  *
  269.  * @param   charset    the JDK charset
  270.  * @return the MIME/IANA equivalent. If a mapping
  271.  * is not possible, the passed in charset itself
  272.  * is returned.
  273.  */
  274. public static String mimeCharset(String charset);
  275. ====================================================================
  276. (6) getDefaultJavaCharset()
  277. ============================
  278. This method returns the default charset for the platform's locale, as
  279. a Java charset. This is a new static method to the MimeUtility class.
  280.     /**
  281.      * Get the default charset for this locale. <p>
  282.      *
  283.      * @return  the default charset of the platform's locale,
  284.      *          as a Java charset. (NOT a MIME charset)
  285.      */
  286.     public static String getDefaultJavaCharset()
  287. ====================================================================
  288. (7) Method to print out the nested Exceptions
  289. =============================================
  290. The MessagingException class currently allows nested exceptions. It
  291. would be nice to have one single method to dump out all the 
  292. nested exceptions' messages into System.out
  293. Proposal
  294. --------
  295. Override the getMessage() method from the superclass (Throwable), to
  296. append the messages from all nested Exceptions. This is similar to
  297. java.rmi.RemoteException.
  298. ==================================================================
  299. (8) New SearchTerms
  300. ====================
  301. The current address related search terms - AddressTerm, FromTerm and
  302. RecipientTerm are limited in that they operate on Address objects, not
  303. Strings. These terms use the equals() method to compare the addresses -
  304. which is not useful for the common case of substring comparisons.
  305. Hence we introduce three new SearchTerms:
  306. public AddressStringTerm extends StringTerm {
  307.     /**
  308.      * Constructor.
  309.      * @param pattern the address pattern to be compared
  310.      */
  311.     protected AddressStringTerm(String pattern);
  312.     /**
  313.      * Check whether the address pattern specified in the 
  314.      * constructor is a substring of the string representation of 
  315.      * the given Address object.
  316.      *
  317.      * @param address the address to match against
  318.      */
  319.     protected boolean match(Address address);
  320. }
  321. public FromStringTerm extends AddressStringTerm {
  322.     /**
  323.      * Constructor.
  324.      * @param address the address to be compared.
  325.      */
  326.     public FromStringTerm(String string);
  327.     /**
  328.      * Check whether the address specified in the constructor is
  329.      * a substring of the "From" attribute of this message.
  330.      *
  331.      * @param msg the address comparison is applied to this Message
  332.      */
  333.      public boolean match(Message msg);
  334. }
  335. public RecipientStringTerm extends AddressStringTerm {
  336.     /**
  337.      * Constructor.
  338.      *
  339.      * @param type      the recipient type
  340.      * @param address the address to be compared.
  341.      */
  342.     public RecipientStringTerm(Message.RecipientType type, String address);
  343.     /**
  344.      * Return the type of recipient to match with.
  345.      */
  346.     public Message.RecipientType getRecipientType();
  347.     /**
  348.      * Check whether the address specified in the constructor is
  349.      * a substring of the given Recipient attribute of this message.
  350.      *
  351.      * @param msg the address comparison is applied to this Message
  352.      */
  353.      public boolean match(Message msg);
  354. }
  355. ==================================================================
  356. (9) InternetAddress.toString(Address[] addresses, int used)
  357. ===========================================================
  358. As per RFC2047 (MIME), the length of a header field that contains
  359. encoded-words is limited to 76 characters.
  360. There are two methods in the InternetAddress class that generate
  361. RFC822 style address strings:
  362.  - The toString() method on InternetAddress, which generates
  363.  the string for one InternetAddress object
  364.  - The toString() static method, which generates a comma separated
  365.  string for the given array of InternetAddress objects.
  366. Both these methods currently do not honor the 76 character limit.
  367. Actually, the former does to an extent, since the encodedWord
  368. generator (i.e the MimeUtility.encodeWord() method) does break
  369. encoded words into multiples, if they stretch beyond 76 characters.
  370. Solution
  371. --------
  372. For the 1.1 release, we are planning to fix the the toString()
  373. static method as follows:
  374. Add a new static method 
  375. static String toString(Address[] address, int used)
  376. This method takes an array of Address objects and an integer representing
  377. the number of "used" character positions for the first line of this
  378. field. The typical use of this method is when setting RFC822 headers,
  379. like the "From" header. 'used' can be set to sizeof("From: ") in
  380. this case.
  381. When generating the string, this method starts a new line if the
  382. addition of the next address.toString() causes the current line's 
  383. line-length to go over 76.
  384. Note that this algorithm does not work right if the length of a single
  385. InternetAddress is itself more than 76 characters. Also, it does not
  386. optimally break an address field, so that the maximum characters are
  387. accommodated in a single line.
  388. So, essentially, this is an initial attempt to solve this problem. We
  389. will add more APIs in the next version to further refine this.
  390. ==================================================================
  391. (10) Folder.getMode()
  392. =====================
  393. It is currently not possible to tell whether a folder is open READ_ONLY
  394. or READ_WRITE without attempting to write it and catching the exception.
  395. We propose to add a protected field to Folder to store the open mode and
  396. a new method to Folder to return the open mode.  Because existing 
  397. subclasses will not use this new field, we can't guarantee that the 
  398. method will always return the correct value (although all Folder subclasses
  399. in the JavaMail package will be updated to return the correct value).
  400.     /**
  401.      * The open mode (<code>Folder.READ_ONLY</code>,
  402.      * <code>Folder.READ_WRITE</code>, or -1 if not known).
  403.      */
  404.     protected int mode = -1;
  405.     /**
  406.      * Return the open mode of this folder.  Returns
  407.      * <code>Folder.READ_ONLY</code>, <code>Folder.READ_WRITE</code>,
  408.      * or -1 if the open mode is not known (usually only because an older
  409.      * <code>Folder</code> provider has not been updated to use this new
  410.      * method).
  411.      *
  412.      * @exception IllegalStateException if this folder is not opened
  413.      * @return         the open mode of this folder
  414.      */
  415.     public int getMode() {
  416. if (!isOpen())
  417.     throw new IllegalStateException("Folder not open");
  418. return mode;
  419.     }
  420. ====================================================================
  421. (11) Folder.getURLName()
  422. ========================
  423. The URLName support in the JavaMail 1.0 API's is incomplete and
  424. inadequately specified.  While you can get a Folder from a Session
  425. given a URLName for the folder, you can't find out the URLName
  426. for a given Folder object.  We propose adding the following method
  427. to Folder:
  428.     /**
  429.      * Return a URLName representing this folder.  The returned URLName
  430.      * does <em>not</em> include the password used to access the store.
  431.      *
  432.      * @return the URLName representing this folder
  433.      * @see URLName
  434.      */
  435.     public URLName getURLName() throws MessagingException
  436. Previously it was not specified whether the URLName returned from
  437. the Store.getURLName method would include the password field or
  438. not, but sometimes it did.  We propose to tighen the specification
  439. and fix the implementation so that the password field is not returned:
  440.     /**
  441.      * Return a URLName representing this store.  The returned URLName
  442.      * does <em>not</em> include the password field.  <p>
  443.      *
  444.      * Subclasses should only override this method if their
  445.      * URLName does not follow the standard format.
  446.      *
  447.      * @return the URLName representing this store
  448.      * @see URLName
  449.      */
  450.     public URLName getURLName()
  451. Similarly for Transport.
  452. Previously it was unspecified how the Store and Transport connect
  453. methods interacted with the url field.  In some cases it would be
  454. updated and in other cases it would not.  We propose to tighen the
  455. specification as follows:
  456.     /**
  457.      * Connect to the specified address. This method provides a simple
  458.      * authentication scheme that requires a username and password. <p>
  459.      *
  460.      * If the connection is successful, an "open" ConnectionEvent is
  461.      * delivered to any ConnectionListeners on this Store. <p>
  462.      *
  463.      * It is an error to connect to an already connected Store. <p>
  464.      *
  465.      * The implementation in the Store class will collect defaults
  466.      * for the host, user, and password from the session, prompting the
  467.      * user if necessary, and will then call the protocolConnect method,
  468.      * which the subclass must override.  The subclass should also
  469.      * implement the <code>getURLName</code> method, or use the 
  470.      * implementation in this class. <p>
  471.      *
  472.      * On a successful connection, the <code>setURLName</code> method is
  473.      * called with a URLName that includes the information used to make
  474.      * the connection, including the password. <p>
  475.      *
  476.      * If the password passed in is null and this is the first successful
  477.      * connection to this store, the user name and the password
  478.      * collected from the user will be saved as defaults for subsequent
  479.      * connection attempts to this same store.  If the password passed
  480.      * in is not null, it is not saved, on the assumption that the 
  481.      * application is managing passwords explicitly.
  482.      *
  483.      * @param host  the host to connect to
  484.      * @param user the user name
  485.      * @param password this user's password
  486.      * @exception AuthenticationFailedException for authentication failures
  487.      * @exception MessagingException for other failures
  488.      * @exception IllegalStateException if the store is already connected
  489.      * @see javax.mail.event.ConnectionEvent
  490.      */
  491.     public void connect(String host, String user, String password)
  492. throws MessagingException
  493. And add this method to Store and Transport:
  494.     /**
  495.      * Set the URLName representing this store.
  496.      * Normally used to update the <code>url</code> field
  497.      * after a store has successfully connected. <p>
  498.      *
  499.      * Subclasses should only override this method if their
  500.      * URLName does not follow the standard format. <p>
  501.      *
  502.      * The implementation in the Store class simply sets the
  503.      * <code>url</code> field.
  504.      *
  505.      * @see URLName
  506.      */
  507.     protected void setURLName(URLName url)
  508. And finally, to simplify the implementation of Store and Transport,
  509. and make the common design patterns between them more clear, we're
  510. considering introducing a new Service class as a superclass of
  511. Store and Transport, and moving all common methods (the various
  512. connnect methods, URLName methods, and some listener methods) to
  513. the superclass.  Note that this is a binary compatible change.
  514. =====================================================================
  515. 12) New Service class
  516. ======================
  517. To emphasize the commonality in behavior between the Store and
  518. Transport classes, and to simplify maintenance of these classes, we
  519. propose moving many of the common methods to a new superclass called
  520. javax.mail.Service.  Store and Transport would then extend Service.
  521. These existing methods currently have identical implementations in the
  522. Store and Transport classes so moving them to a common superclass will
  523. not change the behavior of either Store or Transport.
  524. The Service class will contain all the methods and fields having to do
  525. with connecting, connection listeners, and naming via URLNames.  The
  526. Store class retains the methods for getting Folders and managing Store
  527. and Folder listeners.  The Transport class retains the methods for
  528. sending messages and managing Transport listeners.
  529. Note that this is a binary compatible change both for existing users of
  530. the Store and Transport classes, as well as for existing subclasses of
  531. these classes.
  532. ======================================================================