JavaMail-1.1-changes.txt
资源名称:某公司的java培训教材 [点击查看]
上传用户:dinglihq
上传日期:2013-02-04
资源大小:99958k
文件大小:23k
源码类别:
Java编程
开发平台:
Java
- JavaMail 1.1
- ============
- Following is a description of the new APIs that are being
- introduced in JavaMail 1.1
- Please send comments and feedback to javamail@sun.com
- (1) MessageContext
- ==================
- In some cases it is desirable for the object representing the content
- of a BodyPart to know something about the "context" in which it is
- operating, e.g., what other data is contained in the same Multipart
- object, who sent the message containing the data, etc. This allows
- for more interesting content types that know more about the message
- containing them and the mail system in general.
- Some uses of multipart/related might require these capabilities.
- For instance, the handler for a text/html body part contained in a
- multipart/related object might need to know about the containing
- object in order to find the related image data needed to display the
- HTML document.
- There is one particular case in the current implementation where
- this need arises. (This is a bug in the current release.) When
- constructing a MimeMessage object for a nested message contained
- in another message, the DataContentHandler needs the Session
- object in order to construct the new MimeMessage object.
- To solve these problems we introduce a new class, a new interface,
- and a number of new methods.
- The MessageContext class provides the basic information about the
- "context" in which a content object is operating:
- /**
- * The context in which a piece of Message content is contained. A
- * <code>MessageContext</code> object is returned by the
- * <code>getMessageContext</code> method of the
- * <code>MessageAware</code> interface. <code>MessageAware</code> is
- * typically implemented by <code>DataSources</code> to allow a
- * <code>DataContentHandler</code> to pass on information about the
- * context in which a data content object is operating.
- *
- * @see javax.mail.MessageAware
- * @see javax.activation.DataSource
- * @see javax.activation.DataContentHandler
- */
- public class MessageContext {
- /**
- * Create a MessageContext object describing the context of the
- * given Part.
- */
- public MessageContext(Part part)
- /**
- * Return the Part that contains the content.
- *
- * @return the containing Part, or null if not known
- */
- public Part getPart()
- /**
- * Return the Message that contains the content.
- * Follows the parent chain up through containing Multipart
- * objects until it comes to a Message object, or null.
- *
- * @return the containing Message, or null if not known
- */
- public Message getMessage()
- /**
- * Return the Session we're operating in.
- *
- * @return the Session, or null if not known
- */
- public Session getSession()
- }
- A MessageContext object can be obtained by a DataContentHandler from a
- DataSource that also implements the MessageAware interface:
- /**
- * An interface optionally implemented by <code>DataSources</code> to
- * supply information to a <code>DataContentHandler</code> about the
- * message context in which the data content object is operating.
- *
- * @see javax.mail.MessageContext
- * @see javax.activation.DataSource
- * @see javax.activation.DataContentHandler
- */
- public interface MessageAware {
- /**
- * Return the message context.
- */
- public MessageContext getMessageContext();
- }
- This new interface and class provides the basic information needed by
- the DataContentHandler to use in constructing more "interesting" objects
- representing a particular type of data.
- To allow navigation up the chain of components contained in a Message,
- we add the following methods.
- First, on BodyPart we add:
- /**
- * The <code>Multipart</code> object containing this
- * <code>BodyPart</code>, if known.
- */
- protected Multipart parent;
- /**
- * Return the containing <code>Multipart</code> object,
- * or <code>null</code> if not known.
- */
- public Multipart getParent()
- On Multipart we add:
- /**
- * The <code>Part</code> containing this <code>Multipart</code>,
- * if known.
- */
- protected Part parent;
- /**
- * Return the <code>Part</code> that contains this
- * (cod<code>Multipart</c object, or <code>null</code> if not known.
- */
- public Part getParent()
- /**
- * Set the parent of this <code>Multipart</code> to be the specified
- * <code>Part</code>. Normally called by the <code>Message</code>
- * or <code>BodyPart</code> <code>setContent(Multipart)</code>
- * method. <p>
- *
- * <code>parent</code> may be <code>null</code> if the
- * <code>Multipart</code> is being removed from its containing
- * <code>Part</code>.
- */
- public void setParent(Part parent)
- To enable this new functionality we change the implementations of
- MimeBodyPart, MimeMessage, and MimeMultipart to maintain the "parent"
- links where possible. We also change MimePartDataSource to implement
- the MessageAware interface.
- ===================================================================
- (2) MessageID
- =============
- The MimeMessage class requires a getMessageID() method.
- The client can now fetch it as a header, but since this is a "standard"
- RFC822 header, we want to provide an easier access method.
- An added benefit is that protocols like IMAP, which provide this info
- as part of the ENVELOPE structure, can implement this method much more
- efficiently.
- /**
- * Returns the value of the "Message-ID" header field. Returns
- * null if this field is unavailable or its value is absent. <p>
- *
- * The default implementation provided here uses the
- * <code>getHeader()</code> method to return the value of the
- * "Message-ID" field.
- *
- * @return Message-ID
- * @exception MessagingException, if the retrieval of this field
- * causes any exception.
- * @see javax.mail.search.MessageIDTerm
- */
- public String getMessageID() throws MessagingException;
- ===================================================================
- (3) UIDFolder
- =============
- The following methods in the UIDFolder interface have certain problems.
- We are proposing changes that will fix these problems. These are
- binary incompatible changes, but we think these changes are necessary for
- this interface to work in a useful manner. We are also not aware of
- anyone that has shipped a Store Provider that implements this interface,
- so we are hoping that the effect of this change is minimal (non-existent).
- (1) Message getMessageByUID(long uid)
- Description:
- Get the Message corresponding to the given UID. If no such
- message exists, the java.util.NoSuchElementException is thrown.
- Problem:
- A disconnected client can have a stash of UIDs from a
- previous session. Some of these UIDs may have been expunged from the
- server, but the disconnected client does not know this. It is quite
- reasonable (and expected) for a disconnected client to use this
- method when reconnecting - to check whether a UID is valid or not at
- the server.
- Since failure is an expected result here, using a
- RunTimeException to indicate it, seems wrong and counter-intuitive for
- the client.
- Solution:
- Our solution is to allow this method to return null to indicate
- that the requested UID is not valid anymore. Thus, this method will no
- longer throw the java.util.NoSuchElementException.
- (2) Message[] getMessagesByUID(long start, long end)
- Description:
- Get the Messages corresponding to the given UID range. If any
- UID is invalid, the java.util.NoSuchElementException is thrown.
- Problem:
- Similar, but worse than (1). We think that disconnected clients
- (or clients that prefer to use UIDs) may issue
- getMessagesByUID(1, LASTUID)
- to get all the Messages at the server, especially when the client does
- not know the exact UIDs for this folder. In this case, we certainly
- do not want this method to fail if some id in the given range is
- not a valid UID; rather we want it to return all available Messages from
- the server.
- Solution:
- Our solution is to remove the NoSuchElementException exception
- and allow this method to return Message objects in the given range.
- (3) Message[] getMessagesByUID(long[] uids)
- Description:
- Get the Messages corresponding to the given UID range. If any
- UID is invalid, the java.util.NoSuchElementException is thrown.
- Problem:
- Identical to (1).
- A disconnected client can have a stash of UIDs from a
- previous session. Some of these UIDs may have been expunged from the
- server, but the disconnected client does not know this. It is quite
- reasonable (and expected) for a disconnected client to use this
- method when reconnecting - to check whether a set of UIDs are valid
- or not at the server.
- Since failure can be an expected result, using a
- RunTimeException to indicate it, seems wrong and counter-intuitive for
- the client.
- Solution:
- Our solution is to allow this method to return null entries
- to indicate that a requested UID is not valid anymore. Thus, the
- message array returned by this method can have null entries for the
- invalid UIDs; and this method will no longer throw the
- java.util.NoSuchElementException.
- Note that the size of the returned Message array is the same
- as the size of the request array of UIDs, and that each entry in the
- Message array corresponds to the same index entry in the UID array.
- ===================================================================
- (4) InternetAddress
- ===================
- The InternetAddress class needs the following protected field to
- properly support encoding of the "personal name".
- protected String encodedPersonal; // the encoded personal name
- No other API changes are associated with this.
- This is a binary compatible change to JavaMail 1.0. However, there is
- a potential problem for any existing InternetAddress subclasses, which
- can cause them to break. This typically will affect only providers,
- not clients.
- Details:
- -------
- The InternetAddress implementation will use this field to store the
- encoded personal name.
- The getPersonal() method will return the protected
- 'personal' field; if this field is null, it will check the 'encodedPersonal'
- field and decode its value and return it.
- The toString() method will use the protected 'encodedPersonal'
- field to create the RFC2047 compliant address string. If this field is
- null, it will check the 'personal' field, encode that if necessary and
- use it.
- This implies that, if an InternetAddress subclass changes either
- the 'personal' or 'encodedPersonal' fields, it should set the other
- to null to force its recomputation. Unfortunately, this also implies
- that existing subclasses of InternetAddress that directly set the
- 'personal' field can break in certain situations.
- We feel that the risk of this happening is minimal, since we
- don't expect that our users have subclassed InternetAddress. Also, this
- is necessary to properly support encoded personal names, so we feel that
- this has to be done.
- ================================================================
- (5) MimeCharset
- ================
- A utility method to convert java charsets into MIME charsets is
- needed.
- The JDK supports a variety of charsets. The JDK has names for these
- charsets, unfortunately they dont always match to their MIME or IANA
- equivalents.
- It is necessary in some cases, (especially for providers) to map the
- JDK charset names into their MIME or IANA equivalents. This method does
- that.
- The API:
- -------
- This is a new static method to the javax.mail.internet.MimeUtility class
- /**
- * Convert a java charset into its MIME charset name. <p>
- *
- * Note that a future version of JDK (post 1.2) might provide
- * this functionality, in which case, we might deprecate this
- * method then.
- *
- * @param charset the JDK charset
- * @return the MIME/IANA equivalent. If a mapping
- * is not possible, the passed in charset itself
- * is returned.
- */
- public static String mimeCharset(String charset);
- ====================================================================
- (6) getDefaultJavaCharset()
- ============================
- This method returns the default charset for the platform's locale, as
- a Java charset. This is a new static method to the MimeUtility class.
- /**
- * Get the default charset for this locale. <p>
- *
- * @return the default charset of the platform's locale,
- * as a Java charset. (NOT a MIME charset)
- */
- public static String getDefaultJavaCharset()
- ====================================================================
- (7) Method to print out the nested Exceptions
- =============================================
- The MessagingException class currently allows nested exceptions. It
- would be nice to have one single method to dump out all the
- nested exceptions' messages into System.out
- Proposal
- --------
- Override the getMessage() method from the superclass (Throwable), to
- append the messages from all nested Exceptions. This is similar to
- java.rmi.RemoteException.
- ==================================================================
- (8) New SearchTerms
- ====================
- The current address related search terms - AddressTerm, FromTerm and
- RecipientTerm are limited in that they operate on Address objects, not
- Strings. These terms use the equals() method to compare the addresses -
- which is not useful for the common case of substring comparisons.
- Hence we introduce three new SearchTerms:
- public AddressStringTerm extends StringTerm {
- /**
- * Constructor.
- * @param pattern the address pattern to be compared
- */
- protected AddressStringTerm(String pattern);
- /**
- * Check whether the address pattern specified in the
- * constructor is a substring of the string representation of
- * the given Address object.
- *
- * @param address the address to match against
- */
- protected boolean match(Address address);
- }
- public FromStringTerm extends AddressStringTerm {
- /**
- * Constructor.
- * @param address the address to be compared.
- */
- public FromStringTerm(String string);
- /**
- * Check whether the address specified in the constructor is
- * a substring of the "From" attribute of this message.
- *
- * @param msg the address comparison is applied to this Message
- */
- public boolean match(Message msg);
- }
- public RecipientStringTerm extends AddressStringTerm {
- /**
- * Constructor.
- *
- * @param type the recipient type
- * @param address the address to be compared.
- */
- public RecipientStringTerm(Message.RecipientType type, String address);
- /**
- * Return the type of recipient to match with.
- */
- public Message.RecipientType getRecipientType();
- /**
- * Check whether the address specified in the constructor is
- * a substring of the given Recipient attribute of this message.
- *
- * @param msg the address comparison is applied to this Message
- */
- public boolean match(Message msg);
- }
- ==================================================================
- (9) InternetAddress.toString(Address[] addresses, int used)
- ===========================================================
- As per RFC2047 (MIME), the length of a header field that contains
- encoded-words is limited to 76 characters.
- There are two methods in the InternetAddress class that generate
- RFC822 style address strings:
- - The toString() method on InternetAddress, which generates
- the string for one InternetAddress object
- - The toString() static method, which generates a comma separated
- string for the given array of InternetAddress objects.
- Both these methods currently do not honor the 76 character limit.
- Actually, the former does to an extent, since the encodedWord
- generator (i.e the MimeUtility.encodeWord() method) does break
- encoded words into multiples, if they stretch beyond 76 characters.
- Solution
- --------
- For the 1.1 release, we are planning to fix the the toString()
- static method as follows:
- Add a new static method
- static String toString(Address[] address, int used)
- This method takes an array of Address objects and an integer representing
- the number of "used" character positions for the first line of this
- field. The typical use of this method is when setting RFC822 headers,
- like the "From" header. 'used' can be set to sizeof("From: ") in
- this case.
- When generating the string, this method starts a new line if the
- addition of the next address.toString() causes the current line's
- line-length to go over 76.
- Note that this algorithm does not work right if the length of a single
- InternetAddress is itself more than 76 characters. Also, it does not
- optimally break an address field, so that the maximum characters are
- accommodated in a single line.
- So, essentially, this is an initial attempt to solve this problem. We
- will add more APIs in the next version to further refine this.
- ==================================================================
- (10) Folder.getMode()
- =====================
- It is currently not possible to tell whether a folder is open READ_ONLY
- or READ_WRITE without attempting to write it and catching the exception.
- We propose to add a protected field to Folder to store the open mode and
- a new method to Folder to return the open mode. Because existing
- subclasses will not use this new field, we can't guarantee that the
- method will always return the correct value (although all Folder subclasses
- in the JavaMail package will be updated to return the correct value).
- /**
- * The open mode (<code>Folder.READ_ONLY</code>,
- * <code>Folder.READ_WRITE</code>, or -1 if not known).
- */
- protected int mode = -1;
- /**
- * Return the open mode of this folder. Returns
- * <code>Folder.READ_ONLY</code>, <code>Folder.READ_WRITE</code>,
- * or -1 if the open mode is not known (usually only because an older
- * <code>Folder</code> provider has not been updated to use this new
- * method).
- *
- * @exception IllegalStateException if this folder is not opened
- * @return the open mode of this folder
- */
- public int getMode() {
- if (!isOpen())
- throw new IllegalStateException("Folder not open");
- return mode;
- }
- ====================================================================
- (11) Folder.getURLName()
- ========================
- The URLName support in the JavaMail 1.0 API's is incomplete and
- inadequately specified. While you can get a Folder from a Session
- given a URLName for the folder, you can't find out the URLName
- for a given Folder object. We propose adding the following method
- to Folder:
- /**
- * Return a URLName representing this folder. The returned URLName
- * does <em>not</em> include the password used to access the store.
- *
- * @return the URLName representing this folder
- * @see URLName
- */
- public URLName getURLName() throws MessagingException
- Previously it was not specified whether the URLName returned from
- the Store.getURLName method would include the password field or
- not, but sometimes it did. We propose to tighen the specification
- and fix the implementation so that the password field is not returned:
- /**
- * Return a URLName representing this store. The returned URLName
- * does <em>not</em> include the password field. <p>
- *
- * Subclasses should only override this method if their
- * URLName does not follow the standard format.
- *
- * @return the URLName representing this store
- * @see URLName
- */
- public URLName getURLName()
- Similarly for Transport.
- Previously it was unspecified how the Store and Transport connect
- methods interacted with the url field. In some cases it would be
- updated and in other cases it would not. We propose to tighen the
- specification as follows:
- /**
- * Connect to the specified address. This method provides a simple
- * authentication scheme that requires a username and password. <p>
- *
- * If the connection is successful, an "open" ConnectionEvent is
- * delivered to any ConnectionListeners on this Store. <p>
- *
- * It is an error to connect to an already connected Store. <p>
- *
- * The implementation in the Store class will collect defaults
- * for the host, user, and password from the session, prompting the
- * user if necessary, and will then call the protocolConnect method,
- * which the subclass must override. The subclass should also
- * implement the <code>getURLName</code> method, or use the
- * implementation in this class. <p>
- *
- * On a successful connection, the <code>setURLName</code> method is
- * called with a URLName that includes the information used to make
- * the connection, including the password. <p>
- *
- * If the password passed in is null and this is the first successful
- * connection to this store, the user name and the password
- * collected from the user will be saved as defaults for subsequent
- * connection attempts to this same store. If the password passed
- * in is not null, it is not saved, on the assumption that the
- * application is managing passwords explicitly.
- *
- * @param host the host to connect to
- * @param user the user name
- * @param password this user's password
- * @exception AuthenticationFailedException for authentication failures
- * @exception MessagingException for other failures
- * @exception IllegalStateException if the store is already connected
- * @see javax.mail.event.ConnectionEvent
- */
- public void connect(String host, String user, String password)
- throws MessagingException
- And add this method to Store and Transport:
- /**
- * Set the URLName representing this store.
- * Normally used to update the <code>url</code> field
- * after a store has successfully connected. <p>
- *
- * Subclasses should only override this method if their
- * URLName does not follow the standard format. <p>
- *
- * The implementation in the Store class simply sets the
- * <code>url</code> field.
- *
- * @see URLName
- */
- protected void setURLName(URLName url)
- And finally, to simplify the implementation of Store and Transport,
- and make the common design patterns between them more clear, we're
- considering introducing a new Service class as a superclass of
- Store and Transport, and moving all common methods (the various
- connnect methods, URLName methods, and some listener methods) to
- the superclass. Note that this is a binary compatible change.
- =====================================================================
- 12) New Service class
- ======================
- To emphasize the commonality in behavior between the Store and
- Transport classes, and to simplify maintenance of these classes, we
- propose moving many of the common methods to a new superclass called
- javax.mail.Service. Store and Transport would then extend Service.
- These existing methods currently have identical implementations in the
- Store and Transport classes so moving them to a common superclass will
- not change the behavior of either Store or Transport.
- The Service class will contain all the methods and fields having to do
- with connecting, connection listeners, and naming via URLNames. The
- Store class retains the methods for getting Folders and managing Store
- and Folder listeners. The Transport class retains the methods for
- sending messages and managing Transport listeners.
- Note that this is a binary compatible change both for existing users of
- the Store and Transport classes, as well as for existing subclasses of
- these classes.
- ======================================================================