Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 76305 invoked from network); 19 Jan 2005 03:44:35 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 19 Jan 2005 03:44:35 -0000 Received: (qmail 89925 invoked by uid 500); 19 Jan 2005 03:44:34 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 89916 invoked by uid 500); 19 Jan 2005 03:44:34 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Reply-To: dev@geronimo.apache.org Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 89902 invoked by uid 99); 19 Jan 2005 03:44:34 -0000 X-ASF-Spam-Status: No, hits=-9.8 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from minotaur.apache.org (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Tue, 18 Jan 2005 19:44:30 -0800 Received: (qmail 76256 invoked by uid 65534); 19 Jan 2005 03:44:28 -0000 Date: 19 Jan 2005 03:44:28 -0000 Message-ID: <20050119034428.76252.qmail@minotaur.apache.org> From: jboynes@apache.org To: scm@geronimo.apache.org Subject: svn commit: r125583 - in geronimo/trunk: etc specs/javamail/src/java/javax/mail specs/javamail/src/java/javax/mail/event specs/javamail/src/java/javax/mail/internet specs/javamail/src/java/javax/mail/search specs/javamail/src/test/javax/mail/event specs/javamail/src/test/javax/mail/internet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Author: jboynes Date: Tue Jan 18 19:44:27 2005 New Revision: 125583 URL: http://svn.apache.org/viewcvs?view=rev&rev=125583 Log: first tweaks to JavaMail Modified: geronimo/trunk/etc/project.properties geronimo/trunk/specs/javamail/src/java/javax/mail/Address.java geronimo/trunk/specs/javamail/src/java/javax/mail/FetchProfile.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionAdapter.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionEvent.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionListener.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderAdapter.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderEvent.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/MailEvent.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageChangedEvent.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountAdapter.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountEvent.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/StoreEvent.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportAdapter.java geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportEvent.java geronimo/trunk/specs/javamail/src/java/javax/mail/internet/InternetAddress.java geronimo/trunk/specs/javamail/src/java/javax/mail/internet/MailDateFormat.java geronimo/trunk/specs/javamail/src/java/javax/mail/internet/NewsAddress.java geronimo/trunk/specs/javamail/src/java/javax/mail/search/AddressStringTerm.java geronimo/trunk/specs/javamail/src/java/javax/mail/search/SearchTerm.java geronimo/trunk/specs/javamail/src/java/javax/mail/search/StringTerm.java geronimo/trunk/specs/javamail/src/test/javax/mail/event/ConnectionEventTest.java geronimo/trunk/specs/javamail/src/test/javax/mail/event/FolderEventTest.java geronimo/trunk/specs/javamail/src/test/javax/mail/event/MessageChangedEventTest.java geronimo/trunk/specs/javamail/src/test/javax/mail/event/TransportEventTest.java geronimo/trunk/specs/javamail/src/test/javax/mail/internet/InternetAddressTest.java Modified: geronimo/trunk/etc/project.properties Url: http://svn.apache.org/viewcvs/geronimo/trunk/etc/project.properties?view=diff&rev=125583&p1=geronimo/trunk/etc/project.properties&r1=125582&p2=geronimo/trunk/etc/project.properties&r2=125583 ============================================================================== --- geronimo/trunk/etc/project.properties (original) +++ geronimo/trunk/etc/project.properties Tue Jan 18 19:44:27 2005 @@ -82,7 +82,7 @@ geronimo_spec_j2ee_deployment_version=1.1-rc3 geronimo_spec_j2ee_jacc_version=1.0-rc3 geronimo_spec_j2ee_management_version=1.0-rc3 -geronimo_spec_javamail_version=1.3.1-rc3 +geronimo_spec_javamail_version=1.3.1-SNAPSHOT geronimo_spec_jaxr_version=1.0-rc3 geronimo_spec_jms_version=1.1-rc3 geronimo_spec_jsp_version=2.0-rc3 Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/Address.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/Address.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/Address.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/Address.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/Address.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/Address.java Tue Jan 18 19:44:27 2005 @@ -20,12 +20,29 @@ import java.io.Serializable; /** + * This abstract class models the addresses in a message. + * Addresses are Serializable so that they may be serialized along with other search terms. + * * @version $Rev$ $Date$ */ public abstract class Address implements Serializable { + /** + * Subclasses must provide a suitable implementation of equals(). + * + * @param object the object to compare t + * @return true if the subclass determines the other object is equal to this Address + */ public abstract boolean equals(Object object); + /** + * Return a String that identifies this address type. + * @return the type of this address + */ public abstract String getType(); + /** + * Subclasses must provide a suitable representation of their address. + * @return a representation of an Address as a String + */ public abstract String toString(); } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/FetchProfile.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/FetchProfile.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/FetchProfile.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/FetchProfile.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/FetchProfile.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/FetchProfile.java Tue Jan 18 19:44:27 2005 @@ -17,59 +17,106 @@ package javax.mail; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; /** + * A FetchProfile defines a list of message attributes that a client wishes to prefetch + * from the server during a fetch operation. + * + * Clients can either specify individual headers, or can reference common profiles + * as defined by {@link FetchProfile.Item FetchProfile.Item}. + * * @version $Rev$ $Date$ */ public class FetchProfile { + /** + * Inner class that defines sets of headers that are commonly bundled together + * in a FetchProfile. + */ public static class Item { - // Should match Content-Type, Content-Description, Content-Disposition, Size, Line-Count + /** + * Item for fetching information about the content of the message. + * + * This includes all the headers about the content including but not limited to: + * Content-Type, Content-Disposition, Content-Description, Size and Line-Count + */ public static final Item CONTENT_INFO = new Item("Content-Info"); - // Should match From, To, Cc, Bcc, Reply-To, Subject, Date, Envelope, Envelope-To - public static final Item ENVELOPE = new Item("Envelope-To"); - // Can't find any standards for this? - public static final Item FLAGS = new Item("X-Flags"); - private String _header; - - protected Item(String header) { - if (header == null) { - throw new IllegalArgumentException("Header cannot be null"); - } - _header = header; - } - String getHeader() { - return _header; + /** + * Item for fetching information about the envelope of the message. + * + * This includes all the headers comprising the envelope including but not limited to: + * From, To, Cc, Bcc, Reply-To, Subject and Date + * + * For IMAP4, this should also include the ENVELOPE data item. + * + */ + public static final Item ENVELOPE = new Item("Envelope"); + + /** + * Item for fetching information about message flags. + * Generall corresponds to the X-Flags header. + */ + public static final Item FLAGS = new Item("Flags"); + + protected Item(String name) { + // hmmm, name is passed in but we are not allowed to provide accessors + // or to override equals/hashCode so what use is it? } } - private static final String[] headersType = new String[0]; - private static final Item[] itemsType = new Item[0]; - private Map _items = new HashMap(); - + // use Lists as we don't expect contains to be called often and the number of elements should be small + private final List items = new ArrayList(); + private final List headers = new ArrayList(); + + /** + * Add a predefined profile of headers. + * + * @param item the profile to add + */ public void add(Item item) { - _items.put(item._header, item); + items.add(item); } + /** + * Add a specific header. + * @param header the header whose value should be prefetched + */ public void add(String header) { - _items.put(header, new Item(header)); + headers.add(header); } + /** + * Determine if the given profile item is already included. + * @param item the profile to check for + * @return true if the profile item is already included + */ public boolean contains(Item item) { - return _items.containsKey(item._header); + return items.contains(item); } + /** + * Determine if the specified header is already included. + * @param header the header to check for + * @return true if the header is already included + */ public boolean contains(String header) { - return _items.containsKey(header); + return headers.contains(header); } - public String[] getHeaderNames() { - return (String[]) _items.keySet().toArray(headersType); + /** + * Get the profile items already included. + * @return the items already added to this profile + */ + public Item[] getItems() { + return (Item[]) items.toArray(new Item[items.size()]); } - public Item[] getItems() { - return (Item[]) _items.values().toArray(itemsType); + /** Get the headers that have already been included. + * @return the headers already added to this profile + */ + public String[] getHeaderNames() { + return (String[]) headers.toArray(new String[headers.size()]); } } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionAdapter.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionAdapter.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionAdapter.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionAdapter.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionAdapter.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionAdapter.java Tue Jan 18 19:44:27 2005 @@ -18,6 +18,9 @@ package javax.mail.event; /** + * An adaptor that receives connection events. + * This is a default implementation where the handlers perform no action. + * * @version $Rev$ $Date$ */ public abstract class ConnectionAdapter implements ConnectionListener { Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionEvent.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionEvent.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionEvent.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionEvent.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionEvent.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionEvent.java Tue Jan 18 19:44:27 2005 @@ -21,34 +21,47 @@ * @version $Rev$ $Date$ */ public class ConnectionEvent extends MailEvent { - public static final int CLOSED = 3; - public static final int DISCONNECTED = 2; + /** + * A connection was opened. + */ public static final int OPENED = 1; + + /** + * A connection was disconnected. + */ + public static final int DISCONNECTED = 2; + + /** + * A connection was closed. + */ + public static final int CLOSED = 3; + protected int type; public ConnectionEvent(Object source, int type) { super(source); this.type = type; - if (type != DISCONNECTED && type != OPENED && type != CLOSED) { - throw new IllegalArgumentException("Unknown type " + type); - } + } + + public int getType() { + return type; } public void dispatch(Object listener) { // assume that it is the right listener type ConnectionListener l = (ConnectionListener) listener; - if (type == OPENED) { + switch (type) { + case OPENED: l.opened(this); - } else if (type == DISCONNECTED) { + break; + case DISCONNECTED: l.disconnected(this); - } else if (type == CLOSED) { + break; + case CLOSED: l.closed(this); - } else { - throw new IllegalArgumentException("Unknown type " + type); + break; + default: + throw new IllegalArgumentException("Invalid type " + type); } - } - - public int getType() { - return type; } } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionListener.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionListener.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionListener.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionListener.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionListener.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/ConnectionListener.java Tue Jan 18 19:44:27 2005 @@ -20,12 +20,23 @@ import java.util.EventListener; /** + * Listener for handling connection events. + * * @version $Rev$ $Date$ */ public interface ConnectionListener extends EventListener { - public abstract void closed(ConnectionEvent event); + /** + * Called when a connection is opened. + */ + public abstract void opened(ConnectionEvent event); + /** + * Called when a connection is disconnected. + */ public abstract void disconnected(ConnectionEvent event); - public abstract void opened(ConnectionEvent event); + /** + * Called when a connection is closed. + */ + public abstract void closed(ConnectionEvent event); } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderAdapter.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderAdapter.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderAdapter.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderAdapter.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderAdapter.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderAdapter.java Tue Jan 18 19:44:27 2005 @@ -18,6 +18,9 @@ package javax.mail.event; /** + * An adaptor that receives connection events. + * This is a default implementation where the handlers perform no action. + * * @version $Rev$ $Date$ */ public abstract class FolderAdapter implements FolderListener { Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderEvent.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderEvent.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderEvent.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderEvent.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderEvent.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/FolderEvent.java Tue Jan 18 19:44:27 2005 @@ -26,49 +26,74 @@ public static final int CREATED = 1; public static final int DELETED = 2; public static final int RENAMED = 3; + protected transient Folder folder; protected transient Folder newFolder; protected int type; - public FolderEvent(Object source, - Folder oldFolder, - Folder newFolder, - int type) { + /** + * Constructor used for RENAMED events. + * + * @param source the source of the event + * @param oldFolder the folder that was renamed + * @param newFolder the folder with the new name + * @param type the event type + */ + public FolderEvent(Object source, Folder oldFolder, Folder newFolder, int type) { super(source); folder = oldFolder; this.newFolder = newFolder; this.type = type; - if (type != CREATED && type != DELETED && type != RENAMED) { - throw new IllegalArgumentException("Unknown type " + type); - } } + /** + * Constructor other events. + * + * @param source the source of the event + * @param folder the folder affected + * @param type the event type + */ public FolderEvent(Object source, Folder folder, int type) { this(source, folder, null, type); } public void dispatch(Object listener) { - // assume that it is the right listener type FolderListener l = (FolderListener) listener; - if (type == CREATED) { + switch (type) { + case CREATED: l.folderCreated(this); - } else if (type == DELETED) { + break; + case DELETED: l.folderDeleted(this); - } else if (type == RENAMED) { + break; + case RENAMED: l.folderRenamed(this); - } else { - throw new IllegalArgumentException("Unknown type " + type); + break; + default: + throw new IllegalArgumentException("Invalid type " + type); } } + /** + * Return the affected folder. + * @return the affected folder + */ public Folder getFolder() { return folder; } + /** + * Return the new folder; only applicable to RENAMED events. + * @return the new folder + */ public Folder getNewFolder() { return newFolder; } + /** + * Return the event type. + * @return the event type + */ public int getType() { return type; } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/MailEvent.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/MailEvent.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/MailEvent.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/MailEvent.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/MailEvent.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/MailEvent.java Tue Jan 18 19:44:27 2005 @@ -20,6 +20,8 @@ import java.util.EventObject; /** + * Common base class for mail events. + * * @version $Rev$ $Date$ */ public abstract class MailEvent extends EventObject { Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageChangedEvent.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageChangedEvent.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageChangedEvent.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageChangedEvent.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageChangedEvent.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageChangedEvent.java Tue Jan 18 19:44:27 2005 @@ -23,30 +23,49 @@ * @version $Rev$ $Date$ */ public class MessageChangedEvent extends MailEvent { - public static final int ENVELOPE_CHANGED = 2; + /** + * The message's flags changed. + */ public static final int FLAGS_CHANGED = 1; + + /** + * The messages envelope changed. + */ + public static final int ENVELOPE_CHANGED = 2; + protected transient Message msg; protected int type; + /** + * Constructor. + * + * @param source the folder that owns the message + * @param type the event type + * @param message the affected message + */ public MessageChangedEvent(Object source, int type, Message message) { super(source); msg = message; this.type = type; - if (type != ENVELOPE_CHANGED && type != FLAGS_CHANGED) { - throw new IllegalArgumentException("Unknown type " + type); - } } public void dispatch(Object listener) { - // assume that it is the right listener type MessageChangedListener l = (MessageChangedListener) listener; l.messageChanged(this); } + /** + * Return the affected message. + * @return the affected message + */ public Message getMessage() { return msg; } + /** + * Return the type of change. + * @return the event type + */ public int getMessageChangeType() { return type; } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountAdapter.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountAdapter.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountAdapter.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountAdapter.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountAdapter.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountAdapter.java Tue Jan 18 19:44:27 2005 @@ -18,6 +18,9 @@ package javax.mail.event; /** + * An adaptor that receives message count events. + * This is a default implementation where the handlers perform no action. + * * @version $Rev$ $Date$ */ public abstract class MessageCountAdapter implements MessageCountListener { Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountEvent.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountEvent.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountEvent.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountEvent.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountEvent.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/MessageCountEvent.java Tue Jan 18 19:44:27 2005 @@ -21,46 +21,90 @@ import javax.mail.Message; /** + * Event indicating a change in the number of messages in a folder. + * * @version $Rev$ $Date$ */ public class MessageCountEvent extends MailEvent { + /** + * Messages were added to the folder. + */ public static final int ADDED = 1; + + /** + * Messages were removed from the folder. + */ public static final int REMOVED = 2; + + /** + * The affected messages. + */ protected transient Message msgs[]; - protected boolean removed; + + /** + * The event type. + */ protected int type; - public MessageCountEvent(Folder folder, - int type, - boolean removed, - Message messages[]) { + /** + * If true, then messages were expunged from the folder by this client + * and message numbers reflect the deletion; if false, then the change + * was the result of an expunge by a different client. + */ + protected boolean removed; + + /** + * Construct a new event. + * + * @param folder the folder containing the messages + * @param type the event type + * @param removed indicator of whether messages were expunged by this client + * @param messages the affected messages + */ + public MessageCountEvent(Folder folder, int type, boolean removed, Message messages[]) { super(folder); - msgs = messages; + this.msgs = messages; this.type = type; this.removed = removed; } - public void dispatch(Object listener) { - // assume that it is the right listener type - MessageCountListener l = (MessageCountListener) listener; - if (type == ADDED) { - l.messagesAdded(this); - } else if (type == REMOVED) { - l.messagesRemoved(this); - } else { - throw new IllegalArgumentException("Unknown type " + type); - } - } - - public Message[] getMessages() { - return msgs; - } - + /** + * Return the event type. + * + * @return the event type + */ public int getType() { return type; } + /** + * @return whether this event was the result of an expunge by this client + * @see MessageCountEvent#removed + */ public boolean isRemoved() { return removed; + } + + /** + * Return the affected messages. + * + * @return the affected messages + */ + public Message[] getMessages() { + return msgs; + } + + public void dispatch(Object listener) { + MessageCountListener l = (MessageCountListener) listener; + switch (type) { + case ADDED: + l.messagesAdded(this); + break; + case REMOVED: + l.messagesRemoved(this); + break; + default: + throw new IllegalArgumentException("Invalid type " + type); + } } } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/StoreEvent.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/StoreEvent.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/StoreEvent.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/StoreEvent.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/StoreEvent.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/StoreEvent.java Tue Jan 18 19:44:27 2005 @@ -20,24 +20,58 @@ import javax.mail.Store; /** + * Event representing motifications from the Store connection. + * * @version $Rev$ $Date$ */ public class StoreEvent extends MailEvent { + /** + * Indicates that this message is an alert. + */ public static final int ALERT = 1; + + /** + * Indicates that this message is a notice. + */ public static final int NOTICE = 2; + + /** + * The message type. + */ protected int type; + + /** + * The text to be presented to the user. + */ protected String message; + /** + * Construct a new event. + * + * @param store the Store that initiated the notification + * @param type the message type + * @param message the text to be presented to the user + */ public StoreEvent(Store store, int type, String message) { super(store); this.type = type; this.message = message; } + /** + * Return the message type. + * + * @return the message type + */ public int getMessageType() { return type; } + /** + * Return the text to be displayed to the user. + * + * @return the text to be displayed to the user + */ public String getMessage() { return message; } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportAdapter.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportAdapter.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportAdapter.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportAdapter.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportAdapter.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportAdapter.java Tue Jan 18 19:44:27 2005 @@ -18,6 +18,9 @@ package javax.mail.event; /** + * An adaptor that receives transport events. + * This is a default implementation where the handlers perform no action. + * * @version $Rev$ $Date$ */ public abstract class TransportAdapter implements TransportListener { Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportEvent.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportEvent.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportEvent.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportEvent.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportEvent.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/event/TransportEvent.java Tue Jan 18 19:44:27 2005 @@ -25,31 +25,65 @@ * @version $Rev$ $Date$ */ public class TransportEvent extends MailEvent { + /** + * Indicates that the message has successfully been delivered to all + * recipients. + */ public static final int MESSAGE_DELIVERED = 1; + + /** + * Indicates that no messages could be delivered. + */ public static final int MESSAGE_NOT_DELIVERED = 2; + + /** + * Indicates that some of the messages were successfully delivered + * but that some failed. + */ public static final int MESSAGE_PARTIALLY_DELIVERED = 3; + + /** + * The event type. + */ protected int type; + + /** + * Addresses to which the message was successfully delivered. + */ protected transient Address[] validSent; + + /** + * Addresses which are valid but to which the message was not sent. + */ protected transient Address[] validUnsent; + + /** + * Addresses that are invalid. + */ protected transient Address[] invalid; + + /** + * The message associated with this event. + */ protected transient Message msg; - public TransportEvent(Transport transport, - int type, - Address[] validSent, - Address[] validUnsent, - Address[] invalid, - Message message) { + /** + * Construct a new event, + * + * @param transport the transport attempting to deliver the message + * @param type the event type + * @param validSent addresses to which the message was successfully delivered + * @param validUnsent addresses which are valid but to which the message was not sent + * @param invalid invalid addresses + * @param message the associated message + */ + public TransportEvent(Transport transport, int type, Address[] validSent, Address[] validUnsent, Address[] invalid, Message message) { super(transport); this.type = type; this.validSent = validSent; this.validUnsent = validUnsent; this.invalid = invalid; - if (type != MESSAGE_DELIVERED - && type != MESSAGE_NOT_DELIVERED - && type != MESSAGE_PARTIALLY_DELIVERED) { - throw new IllegalArgumentException("Unknown type " + type); - } + this.msg = message; } public Address[] getValidSentAddresses() { @@ -73,16 +107,19 @@ } public void dispatch(Object listener) { - // assume that it is the right listener type TransportListener l = (TransportListener) listener; - if (type == MESSAGE_DELIVERED) { + switch (type) { + case MESSAGE_DELIVERED: l.messageDelivered(this); - } else if (type == MESSAGE_NOT_DELIVERED) { + break; + case MESSAGE_NOT_DELIVERED: l.messageNotDelivered(this); - } else if (type == MESSAGE_PARTIALLY_DELIVERED) { + break; + case MESSAGE_PARTIALLY_DELIVERED: l.messagePartiallyDelivered(this); - } else { - throw new IllegalArgumentException("Unknown type " + type); + break; + default: + throw new IllegalArgumentException("Invalid type " + type); } } } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/internet/InternetAddress.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/internet/InternetAddress.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/internet/InternetAddress.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/internet/InternetAddress.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/internet/InternetAddress.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/internet/InternetAddress.java Tue Jan 18 19:44:27 2005 @@ -19,209 +19,624 @@ import java.io.UnsupportedEncodingException; import java.net.InetAddress; -import java.util.LinkedList; +import java.net.UnknownHostException; +import java.util.ArrayList; import java.util.List; -import java.util.Properties; import java.util.StringTokenizer; import javax.mail.Address; import javax.mail.Session; /** + * A representation of an Internet email address as specified by RFC822 in + * conjunction with a human-readable personal name that can be encoded as + * specified by RFC2047. + * A typical address is "user@host.domain" and personal name "Joe User" + * * @version $Rev$ $Date$ */ public class InternetAddress extends Address implements Cloneable { - private static final InternetAddress[] IA_ARRAY = new InternetAddress[0]; + /** + * The address in RFC822 format. + */ + protected String address; - public static InternetAddress getLocalAddress(Session session) { - try { - Properties properties = session.getProperties(); - String mailFrom = properties.getProperty("mail.from"); - if (mailFrom == null) { - String mailUser = properties.getProperty("mail.user"); - String mailHost = properties.getProperty("mail.host"); - if (mailUser == null) { - mailUser = System.getProperty("user.name"); - } - if (mailHost == null) { - try { - mailHost = InetAddress.getLocalHost().getHostName(); - } catch (SecurityException e) { - mailHost = "localhost"; - } - } - return new InternetAddress(mailUser + "@" + mailHost); - } else { - return new InternetAddress(mailFrom); - } - } catch (Exception e) { - return null; - } + /** + * The personal name in RFC2047 format. + * Subclasses must ensure that this field is updated if the personal field + * is updated; alternatively, it can be invalidated by setting to null + * which will cause it to be recomputed. + */ + protected String encodedPersonal; + + /** + * The personal name as a Java String. + * Subclasses must ensure that this field is updated if the encodedPersonal field + * is updated; alternatively, it can be invalidated by setting to null + * which will cause it to be recomputed. + */ + protected String personal; + + public InternetAddress() { } - public static InternetAddress[] parse(String address) - throws AddressException { - return parse(address, true); - } - - public static InternetAddress[] parse(String addresses, boolean strict) - throws AddressException { - // split up address into component parts - // addresses are name or addr (name), sometimes with name in quotes - // comma separated - List result = new LinkedList(); - StringTokenizer tokenizer = new StringTokenizer(addresses, ","); - while (tokenizer.hasMoreTokens()) { - String address = tokenizer.nextToken(); - result.add(new InternetAddress(address)); - } - return (InternetAddress[]) result.toArray(IA_ARRAY); - } - - public static InternetAddress[] parseHeader(String addresses, - boolean strict) - throws AddressException { - return parse(addresses, strict); + public InternetAddress(String address) throws AddressException { + this(address, true); } - public static String toString(Address[] addresses) { - StringBuffer result = new StringBuffer(); - boolean first = true; - for (int a = 0; a < addresses.length; a++) { - Address address = addresses[a]; - if (first) { - first = false; - } else { - result.append(","); - } - result.append(address.toString()); + public InternetAddress(String address, boolean strict) throws AddressException { + init(this, address); + if (strict) { + validate(); } - return result.toString(); } - public static String toString(Address[] addresses, int used) { - String result = toString(addresses); - if (result.length() > used) { - // TODO No idea what to do here + public InternetAddress(String address, String personal) throws UnsupportedEncodingException { + this(address, personal, null); + } + + public InternetAddress(String address, String personal, String charset) throws UnsupportedEncodingException { + this.address = address; + setPersonal(personal, charset); + } + + /** + * Clone this object. + * + * @return a copy of this object as created by Object.clone() + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new Error(); } - return result; } - protected String address; - protected String encodedPersonal; - protected String personal; + /** + * Return the type of this address. + * + * @return the type of this address; always "rfc822" + */ + public String getType() { + return "rfc822"; + } - public InternetAddress() { + /** + * Set the address. + * No validation is performed; validate() can be used to check if it is valid. + * + * @param address the address to set + */ + public void setAddress(String address) { + this.address = address; } - public InternetAddress(String address) throws AddressException { - int lt = address.indexOf("<"); - int gt = address.indexOf(">"); - if (lt != -1 && gt != -1) { - setAddress(address.substring(lt + 1, gt)); - // everyting else is the name + /** + * Set the personal name. + * The name is first checked to see if it can be encoded; if this fails then an + * UnsupportedEncodingException is thrown and no fields are modified. + * + * @param name the new personal name + * @param charset the charset to use; see {@link MimeUtility#encodeWord(String, String, String) MimeUtilityencodeWord} + * @throws UnsupportedEncodingException if the name cannot be encoded + */ + public void setPersonal(String name, String charset) throws UnsupportedEncodingException { + encodedPersonal = MimeUtility.encodeWord(name, charset, null); + personal = name; + } + + /** + * Set the personal name. + * The name is first checked to see if it can be encoded using {@link MimeUtility#encodeWord(String)}; if this fails then an + * UnsupportedEncodingException is thrown and no fields are modified. + * + * @param name the new personal name + * @throws UnsupportedEncodingException if the name cannot be encoded + */ + public void setPersonal(String name) throws UnsupportedEncodingException { + encodedPersonal = MimeUtility.encodeWord(name); + personal = name; + } + + /** + * Return the address. + * + * @return the address + */ + public String getAddress() { + return address; + } + + /** + * Return the personal name. + * If the personal field is null, then an attempt is made to decode the encodedPersonal + * field using {@link MimeUtility#decodeWord(String)}; if this is sucessful, then + * the personal field is updated with that value and returned; if there is a problem + * decoding the text then the raw value from encodedPersonal is returned. + * + * @return the personal name + */ + public String getPersonal() { + if (personal == null && encodedPersonal != null) { try { - setPersonal((address.substring(0, lt) + address.substring(gt + 1)) - .trim()); + personal = MimeUtility.decodeWord(encodedPersonal); + } catch (ParseException e) { + return encodedPersonal; } catch (UnsupportedEncodingException e) { - throw new AddressException(e.getMessage()); + return encodedPersonal; } - } else { - setAddress(address); } + return personal; } - public InternetAddress(String address, boolean strict) - throws AddressException { - // parse address strictly? + /** + * Return the encoded form of the personal name. + * If the encodedPersonal field is null, then an attempt is made to encode the + * personal field using {@link MimeUtility#encodeWord(String)}; if this is + * successful then the encodedPersonal field is updated with that value and returned; + * if there is a problem encoding the text then null is returned. + * + * @return the encoded form of the personal name + */ + private String getEncodedPersonal() { + if (encodedPersonal == null && personal != null) { + try { + encodedPersonal = MimeUtility.encodeWord(personal); + } catch (UnsupportedEncodingException e) { + // as we could not encode this, return null + return null; + } + } + return encodedPersonal; } - public InternetAddress(String address, String personal) - throws UnsupportedEncodingException { - this(address, personal, MimeUtility.getDefaultJavaCharset()); + /** + * Add RFC822 quotes to a String if needed. + * It is assumed the text passed in has already been converted to US-ASCII. + * + * @param buf a buffer to write into + * @param text the text to quote + * @return the supplied buffer + */ + private StringBuffer quote(StringBuffer buf, String text) { + boolean noQuotesNeeded = true; + for (int i = 0; i < text.length() && noQuotesNeeded; i++) { + noQuotesNeeded = isAtom(text.charAt(i)); + } + if (noQuotesNeeded) { + buf.append(text); + } else { + buf.append('"'); + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + if (c == '"' || c == '\\') { + buf.append('\\'); + } + buf.append(c); + } + buf.append('"'); + } + return buf; } - public InternetAddress(String address, String personal, String charset) - throws UnsupportedEncodingException { - this.address = address; - this.personal = personal; - // TODO Encode personal with given charset + /** + * Return a string representation of this address using only US-ASCII characters. + * + * @return a string representation of this address + */ + public String toString() { + String p = getEncodedPersonal(); + if (p == null) { + return address; + } else { + StringBuffer buf = new StringBuffer(p.length() + 8 + address.length() + 3); + quote(buf, p).append("< ").append(address).append(">"); + return buf.toString(); + } } - public Object clone() { - InternetAddress ia = new InternetAddress(); - ia.address = address; - ia.personal = personal; - ia.encodedPersonal = encodedPersonal; - return ia; + /** + * Return a string representation of this address using Unicode characters. + * + * @return a string representation of this address + */ + public String toUnicodeString() { + String p = getPersonal(); + if (p == null) { + return address; + } else { + StringBuffer buf = new StringBuffer(p.length() + 8 + address.length() + 3); + quote(buf, p).append("< ").append(address).append(">"); + return buf.toString(); + } } - public String getAddress() { - return address; - } + /** + * Compares two addresses for equality. + * We define this as true if the other object is an InternetAddress + * and the two values returned by getAddress() are equal in a + * case-insensitive comparison. + * + * @param o the other object + * @return true if the addresses are the same + */ + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof InternetAddress)) return false; - public InternetAddress[] getGroup(boolean strict) throws AddressException { - // TODO Not implemented - return null; + InternetAddress other = (InternetAddress) o; + String myAddress = getAddress(); + return myAddress == null ? (other.getAddress() == null) : myAddress.equalsIgnoreCase(other.getAddress()); } - public String getPersonal() { - return personal; + /** + * Return the hashCode for this address. + * We define this to be the hashCode of the address after conversion to lowercase. + * + * @return a hashCode for this address + */ + public int hashCode() { + return (address == null) ? 0 : address.toLowerCase().hashCode(); } - public String getType() { - return "rfc822"; + /** + * Return true is this address is an RFC822 group address in the format + * phrase ":" [#mailbox] ";". + * We check this by seeing stripping the leading phrase (which, for tolerance, + * we consider optional) and then checking if the first and last characters are + * ':' and ';' respectively. + * + * @return true is this address represents a group + */ + public boolean isGroup() { + if (address == null) { + return false; + } + + int start = skipSpace(address, 0); + int index = expectPhrase(address, start); + if (index > start) { + start = skipSpace(address, index); + } + + return address.charAt(start) == ':' && address.charAt(address.length() - 1) == ';'; } - public boolean isGroup() { - // TODO Not implemented - return false; + /** + * Return the members of a group address. + * + * If strict is true and the address does not contain an initial phrase then an AddressException is thrown. + * Otherwise the phrase is skipped and the remainder of the address is checked to see if it is a group. + * If it is, the content and strict flag are passed to parseHeader to extract the list of addresses; + * if it is not a group then null is returned. + * + * @param strict whether strict RFC822 checking should be performed + * @return an array of InternetAddress objects for the group members, or null if this address is not a group + * @throws AddressException if there was a problem parsing the header + */ + public InternetAddress[] getGroup(boolean strict) throws AddressException { + if (address == null) { + return null; + } + int start = skipSpace(address, 0); + int index = expectPhrase(address, start); + if (index == start && strict) { + throw new AddressException("Missing phrase"); + } else if (index > start) { + start = skipSpace(address, index); + } + if (address.charAt(start) == ':' && address.charAt(address.length() - 1) == ';') { + return parseHeader(address.substring(1, address.length() - 1), strict); + } else { + return null; + } } - public void setAddress(String address) { - this.address = address; + /** + * Return an InternetAddress representing the current user. + *

+ * If session is not null, we first look for an address specified in its + * "mail.from" property; if this is not set, we look at its "mail.user" + * and "mail.host" properties and if both are not null then an address of + * the form "${mail.user}@${mail.host}" is created. + * If this fails to give an address, then an attempt is made to create + * an address by combining the value of the "user.name" System property + * with the value returned from InetAddress.getLocalHost().getHostName(). + * Any SecurityException raised accessing the system property or any + * UnknownHostException raised getting the hostname are ignored. + *

+ * Finally, an attempt is made to convert the value obtained above to + * an InternetAddress. If this fails, then null is returned. + * + * @param session used to obtain mail properties + * @return an InternetAddress for the current user, or null if it cannot be determined + */ + public static InternetAddress getLocalAddress(Session session) { + String address = null; + if (session != null) { + address = session.getProperty("mail.from"); + if (address == null) { + String user = session.getProperty("mail.user"); + String host = session.getProperty("mail.host"); + if (user != null && host != null) { + address = user + '@' + host; + } + } + } + if (address == null) { + try { + String user = System.getProperty("user.name"); + String host = InetAddress.getLocalHost().getHostName(); + if (user != null && host != null) { + address = user + '@' + host; + } + } catch (UnknownHostException e) { + // ignore + } catch (SecurityException e) { + // ignore + } + } + if (address != null) { + try { + return new InternetAddress(address); + } catch (AddressException e) { + // ignore + } + } + return null; } - public void setPersonal(String name) throws UnsupportedEncodingException { - setPersonal(name, null); + /** + * Convert the supplied addresses into a single String of comma-separated text as + * produced by {@link InternetAddress#toString() toString()}. + * No line-break detection is performed. + * + * @param addresses the array of addresses to convert + * @return a one-line String of comma-separated addresses + */ + public static String toString(Address[] addresses) { + if (addresses == null || addresses.length == 0) { + return null; + } + if (addresses.length == 1) { + return addresses[0].toString(); + } else { + StringBuffer buf = new StringBuffer(addresses.length * 32); + buf.append(addresses[0].toString()); + for (int i = 1; i < addresses.length; i++) { + buf.append(", "); + buf.append(addresses[i].toString()); + } + return buf.toString(); + } } - public void setPersonal(String name, String encoding) - throws UnsupportedEncodingException { - encodedPersonal = - MimeUtility.encodeText(name, - MimeUtility.getDefaultJavaCharset(), - encoding); - personal = name; + /** + * Convert the supplies addresses into a String of comma-separated text, + * inserting line-breaks between addresses as needed to restrict the line + * length to 72 characters. Splits will only be introduced between addresses + * so an address longer than 71 characters will still be placed on a single + * line. + * + * @param addresses the array of addresses to convert + * @param used the starting column + * @return a String of comma-separated addresses with optional line breaks + */ + public static String toString(Address[] addresses, int used) { + if (addresses == null || addresses.length == 0) { + return null; + } + if (addresses.length == 1) { + String s = addresses[0].toString(); + if (used + s.length() > 72) { + s = "\r\n " + s; + } + return s; + } else { + StringBuffer buf = new StringBuffer(addresses.length * 32); + for (int i = 0; i < addresses.length; i++) { + String s = addresses[1].toString(); + if (i == 0) { + if (used + s.length() + 1 > 72) { + buf.append("\r\n "); + used = 2; + } + } else { + if (used + s.length() + 1 > 72) { + buf.append(",\r\n "); + used = 2; + } else { + buf.append(", "); + used += 2; + } + } + buf.append(s); + used += s.length(); + } + return buf.toString(); + } } - public String toString() { - return encodedPersonal + " <" + address + ">"; + /** + * Parse addresses out of the string with basic checking. + * + * @param addresses the addresses to parse + * @return an array of InternetAddresses parsed from the string + * @throws AddressException if addresses checking fails + */ + public static InternetAddress[] parse(String addresses) throws AddressException { + return parse(addresses, true, false); + } + + /** + * Parse addresses out of the string. + * + * @param addresses the addresses to parse + * @param strict if true perform detailed checking, if false just perform basic checking + * @return an array of InternetAddresses parsed from the string + * @throws AddressException if address checking fails + */ + public static InternetAddress[] parse(String addresses, boolean strict) throws AddressException { + return parse(addresses, strict, false); + } + + /** + * Parse addresses out of the string. + * + * @param addresses the addresses to parse + * @param strict if true perform detailed checking, if false perform little checking + * @return an array of InternetAddresses parsed from the string + * @throws AddressException if address checking fails + */ + public static InternetAddress[] parseHeader(String addresses, boolean strict) throws AddressException { + return parse(addresses, strict, true); + } + + /** + * Parse addresses with increasing degrees of RFC822 compliance checking. + * + * @param addresses the string to parse + * @param strict if true, performs basic address checking + * @param veryStrict if true performs detailed address checking + * @return an array of InternetAddresses parsed from the string + * @throws AddressException if address checking fails + */ + private static InternetAddress[] parse(String addresses, boolean strict, boolean veryStrict) throws AddressException { + List addrs = new ArrayList(); + + // todo we need to parse the addresses per the RFC822 spec with certain relaxations which are not documented by JavaMail + // for now, we ignore all flags and simply tokenize based on commas + + StringTokenizer tok = new StringTokenizer(addresses, ","); + while (tok.hasMoreTokens()) { + String text = tok.nextToken().trim(); + InternetAddress addr = new InternetAddress(); + init(addr, text); + if (strict || veryStrict) { + addr.validate(); + } + addrs.add(addr); + } + + return (InternetAddress[]) addrs.toArray(new InternetAddress[addrs.size()]); } - public String toUnicodeString() { - return personal + " <" + address + ">"; + private static void init(InternetAddress addr, String text) { + addr.address = text; + addr.personal = null; + addr.encodedPersonal = null; } public void validate() throws AddressException { // TODO Not implemented } - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof InternetAddress)) return false; + private int expectPhrase(String s, int index) { + int start = index; + index = expectWord(s, index); + while (index != start) { + start = skipSpace(s, index); + index = expectWord(s, start); + } + return index; + } - final InternetAddress internetAddress = (InternetAddress) o; + private int expectWord(String s, int index) { + if (index == s.length()) { + return index; + } + char c = s.charAt(index); + if (c == '"') { + index++; + while (index < s.length()) { + c = s.charAt(index); + if (c == '"') { + index++; + break; + } else if (c == '\\') { + if (index != s.length()) { + index++; + } + } else if (c == '\r') { + return index; + } + index++; + } + } else { + while (index < s.length() && isAtom(s.charAt(index))) { + index++; + } + } + return index; + } - if (!address.equals(internetAddress.address)) return false; - if (!personal.equals(internetAddress.personal)) return false; + private int skipSpace(String s, int index) { + while (index < s.length()) { + char c = s.charAt(index); + if (isSpace(c)) { + index++; + } else if (c == '(') { + index = skipComment(s, index); + } else { + return index; + } + } + return index; + } - return true; + private int skipComment(String s, int index) { + index++; + int nest = 1; + while (index < s.length() && nest > 0) { + char c = s.charAt(index++); + if (c == ')') { + nest -= 1; + } else if (c == '\\') { + if (index == s.length()) { + return index; + } + index++; + } else if (c == '(') { + nest += 1; + } else if (c == '\r') { + index -= 1; + return index; + } + } + return index; } - public int hashCode() { - int result; - result = address.hashCode(); - result = 29 * result + personal.hashCode(); - return result; + private static final byte[] CHARMAP = { + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06, 0x02, 0x06, 0x02, 0x02, 0x06, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, + + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + }; + + private static final byte FLG_SPECIAL = 1; + private static final byte FLG_CONTROL = 2; + private static final byte FLG_SPACE = 4; + + private static boolean isSpace(char c) { + if (c > '\u007f') { + return false; + } else { + return (CHARMAP[c] & FLG_SPACE) != 0; + } + } + + private static boolean isAtom(char c) { + if (c > '\u007f') { + return true; + } else if (c == ' ') { + return false; + } else { + return (CHARMAP[c] & (FLG_SPECIAL | FLG_CONTROL)) == 0; + } } } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/internet/MailDateFormat.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/internet/MailDateFormat.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/internet/MailDateFormat.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/internet/MailDateFormat.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/internet/MailDateFormat.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/internet/MailDateFormat.java Tue Jan 18 19:44:27 2005 @@ -17,39 +17,52 @@ package javax.mail.internet; +import java.text.FieldPosition; import java.text.NumberFormat; +import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Calendar; +import java.util.Date; import java.util.Locale; /** - * Parses dates of the form + * Formats ths date as specified by + * draft-ietf-drums-msg-fmt-08 dated January 26, 2000 + * which supercedes RFC822. *

- * Wed, 02 Jan 2003 23:59:59 -0100 (GMT) *

- * EEE, d MMM yyyy HH:mm:ss Z (z) + * The format used is EEE, d MMM yyyy HH:mm:ss Z and + * locale is always US-ASCII. * * @version $Rev$ $Date$ */ public class MailDateFormat extends SimpleDateFormat { - static final MailDateFormat INSTANCE = new MailDateFormat(); // @todo jboynes: this does not seem to be used - private static final String pattern = "EEE, d MMM yyyy HH:mm:ss Z (z)"; - public MailDateFormat() { - super(pattern, Locale.US); + super("EEE, d MMM yyyy HH:mm:ss Z", Locale.US); + } + + public StringBuffer format(Date date, StringBuffer buffer, FieldPosition position) { + return super.format(date, buffer, position); + } + + public Date parse(String string, ParsePosition position) { + return super.parse(string, position); } - // @todo jboynes: are these commented out for a reason? - // public StringBuffer format(Date date, StringBuffer buffer, FieldPosition position) { - // return super.format(date,buffer,position); - // } - // public Date parse(String string, ParsePosition position) { - // return parse(string,position); - // } + /** + * The calendar cannot be set + * @param calendar + * @throws UnsupportedOperationException + */ public void setCalendar(Calendar calendar) { throw new UnsupportedOperationException(); } + /** + * The format cannot be set + * @param format + * @throws UnsupportedOperationException + */ public void setNumberFormat(NumberFormat format) { throw new UnsupportedOperationException(); } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/internet/NewsAddress.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/internet/NewsAddress.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/internet/NewsAddress.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/internet/NewsAddress.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/internet/NewsAddress.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/internet/NewsAddress.java Tue Jan 18 19:44:27 2005 @@ -17,84 +17,65 @@ package javax.mail.internet; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import javax.mail.Address; /** + * A representation of an RFC1036 Internet newsgroup address. + * * @version $Rev$ $Date$ */ public class NewsAddress extends Address { - private static final String _separator = ","; - private static final NewsAddress[] NEWSADDRESS_ARRAY = new NewsAddress[0]; - - public static NewsAddress[] parse(String addresses) throws AddressException { - List result = new LinkedList(); - StringTokenizer tokenizer = new StringTokenizer(addresses, ","); - while (tokenizer.hasMoreTokens()) { - String address = tokenizer.nextToken(); - result.add(new NewsAddress(address)); - } - return (NewsAddress[]) result.toArray(NEWSADDRESS_ARRAY); - } - - public static String toString(Address[] addresses) { - // build up a comma separated list of addresses - StringBuffer result = new StringBuffer(); - for (int a = 0; a < addresses.length; a++) { - result.append(addresses[a].toString()); - if (a > 0) { - result.append(_separator); - } - } - return result.toString(); - } - + /** + * The host for this newsgroup + */ protected String host; + + /** + * The name of this newsgroup + */ protected String newsgroup; public NewsAddress() { } public NewsAddress(String newsgroup) { - setNewsgroup(newsgroup); + this.newsgroup = newsgroup; } public NewsAddress(String newsgroup, String host) { - setNewsgroup(newsgroup); - setHost(host); + this.newsgroup = newsgroup; + this.host = host; } - public String getHost() { - return host; + /** + * The type of this address; always "news". + * @return "news" + */ + public String getType() { + return "news"; } - public String getNewsgroup() { - return newsgroup; + public void setNewsgroup(String newsgroup) { + this.newsgroup = newsgroup; } - public String getType() { - return "news"; + public String getNewsgroup() { + return newsgroup; } - public void setHost(String string) { - host = string; + public void setHost(String host) { + this.host = host; } - public void setNewsgroup(String newsgroup) { - newsgroup = newsgroup.trim(); - int at; - if ((at = newsgroup.indexOf("@")) != -1) { - this.newsgroup = newsgroup.substring(0, at); - this.host = newsgroup.substring(at + 1); - } else { - this.newsgroup = newsgroup; - } + public String getHost() { + return host; } public String toString() { - return newsgroup + (host == null ? "" : "@" + host); + return host == null ? newsgroup : newsgroup + "@" + host; } public boolean equals(Object o) { @@ -103,16 +84,63 @@ final NewsAddress newsAddress = (NewsAddress) o; - if (!host.equals(newsAddress.host)) return false; - if (!newsgroup.equals(newsAddress.newsgroup)) return false; + if (host != null ? !host.equals(newsAddress.host) : newsAddress.host != null) return false; + if (newsgroup != null ? !newsgroup.equals(newsAddress.newsgroup) : newsAddress.newsgroup != null) return false; return true; } public int hashCode() { int result; - result = host.hashCode(); - result = 29 * result + newsgroup.hashCode(); + result = (host != null ? host.hashCode() : 0); + result = 29 * result + (newsgroup != null ? newsgroup.hashCode() : 0); return result; + } + + /** + * Parse a comma-spearated list of addresses. + * + * @param addresses the list to parse + * @return the array of extracted addresses + * @throws AddressException if one of the addresses is invalid + */ + public static NewsAddress[] parse(String addresses) throws AddressException { + List result = new ArrayList(); + StringTokenizer tokenizer = new StringTokenizer(addresses, ","); + while (tokenizer.hasMoreTokens()) { + String address = tokenizer.nextToken().trim(); + int index = address.indexOf('@'); + if (index == -1) { + result.add(new NewsAddress(address)); + } else { + String newsgroup = address.substring(0, index).trim(); + String host = address.substring(index+1).trim(); + result.add(new NewsAddress(newsgroup, host)); + } + } + return (NewsAddress[]) result.toArray(new NewsAddress[result.size()]); + } + + /** + * Convert the supplied addresses to a comma-separated String. + * If addresses is null, returns null; if empty, returns an empty string. + * + * @param addresses the addresses to convert + * @return a comma-separated list of addresses + */ + public static String toString(Address[] addresses) { + if (addresses == null) { + return null; + } + if (addresses.length == 0) { + return ""; + } + + StringBuffer result = new StringBuffer(addresses.length * 32); + result.append(addresses[0]); + for (int i = 1; i < addresses.length; i++) { + result.append(',').append(addresses[i].toString()); + } + return result.toString(); } } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/search/AddressStringTerm.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/search/AddressStringTerm.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/search/AddressStringTerm.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/search/AddressStringTerm.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/search/AddressStringTerm.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/search/AddressStringTerm.java Tue Jan 18 19:44:27 2005 @@ -20,13 +20,26 @@ import javax.mail.Address; /** + * A Term that compares two Addresses as Strings. + * * @version $Rev$ $Date$ */ public abstract class AddressStringTerm extends StringTerm { - protected AddressStringTerm(String addressString) { - super(addressString); + /** + * Constructor. + * @param pattern the pattern to be compared + */ + protected AddressStringTerm(String pattern) { + super(pattern); } + /** + * Tests if the patterm associated with this Term is a substring of + * the address in the supplied object. + * + * @param address + * @return + */ protected boolean match(Address address) { return match(address.toString()); } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/search/SearchTerm.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/search/SearchTerm.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/search/SearchTerm.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/search/SearchTerm.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/search/SearchTerm.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/search/SearchTerm.java Tue Jan 18 19:44:27 2005 @@ -21,18 +21,19 @@ import javax.mail.Message; /** + * Base class for Terms in a parse tree used to represent a search condition. + * + * This class is Serializable to allow for the short term persistence of + * searches between Sessions; this is not intended for long-term persistence. + * * @version $Rev$ $Date$ */ public abstract class SearchTerm implements Serializable { + /** + * Checks a matching criteria defined by the concrete subclass of this Term. + * + * @param message the message to apply the matching criteria to + * @return true if the matching criteria is met + */ public abstract boolean match(Message message); - - public boolean equals(Object other) { - return (other != null && other.getClass() == this.getClass()); - } - - public int hashCode() { - // need to provide a default, so that other terms - // doing 'super.hashCode' don't get an instance-specific hash. - return 1234; - } } Modified: geronimo/trunk/specs/javamail/src/java/javax/mail/search/StringTerm.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/java/javax/mail/search/StringTerm.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/java/javax/mail/search/StringTerm.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/java/javax/mail/search/StringTerm.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/java/javax/mail/search/StringTerm.java (original) +++ geronimo/trunk/specs/javamail/src/java/javax/mail/search/StringTerm.java Tue Jan 18 19:44:27 2005 @@ -18,46 +18,93 @@ package javax.mail.search; /** + * A Term that provides matching criteria for Strings. + * * @version $Rev$ $Date$ */ public abstract class StringTerm extends SearchTerm { + /** + * If true, case should be ignored during matching. + */ protected boolean ignoreCase; + + /** + * The pattern associated with this term. + */ protected String pattern; + /** + * Constructor specifying a pattern. + * Defaults to case insensitive matching. + * @param pattern the pattern for this term + */ protected StringTerm(String pattern) { this(pattern, true); } + /** + * Constructor specifying pattern and case sensitivity. + * @param pattern the pattern for this term + * @param ignoreCase if true, case should be ignored during matching + */ protected StringTerm(String pattern, boolean ignoreCase) { this.pattern = pattern; this.ignoreCase = ignoreCase; } - public boolean equals(Object other) { - return super.equals(other) - && ((StringTerm) other).pattern.equals(pattern) - && ((StringTerm) other).ignoreCase == ignoreCase; + /** + * Return the pattern associated with this term. + * @return the pattern associated with this term + */ + public String getPattern() { + return pattern; } + /** + * Indicate if case should be ignored when matching. + * @return if true, case should be ignored during matching + */ public boolean getIgnoreCase() { return ignoreCase; } - public String getPattern() { - return pattern; + /** + * Determine if the pattern associated with this term is a substring of the + * supplied String. If ignoreCase is true then case will be ignored. + * + * @param match the String to compare to + * @return true if this patter is a substring of the supplied String + */ + protected boolean match(String match) { + match: for (int length = match.length() - pattern.length(); length > 0; length--) { + for (int i = 0; i < pattern.length(); i++) { + char c1 = match.charAt(length + i); + char c2 = match.charAt(i); + if (c1 == c2) { + continue; + } + if (ignoreCase) { + if (Character.toLowerCase(c1) == Character.toLowerCase(c2)) { + continue; + } + if (Character.toUpperCase(c1) == Character.toUpperCase(c2)) { + continue; + } + } + continue match; + } + return true; + } + return false; } - public int hashCode() { - return super.hashCode() + pattern.hashCode() + (ignoreCase ? 32 : 79); + public boolean equals(Object other) { + return super.equals(other) + && ((StringTerm) other).pattern.equals(pattern) + && ((StringTerm) other).ignoreCase == ignoreCase; } - protected boolean match(String match) { - String a = match; - String b = pattern; - if (ignoreCase) { - a = a.toUpperCase(); - b = b.toUpperCase(); - } - return a.indexOf(b) != -1; + public int hashCode() { + return super.hashCode() + pattern.hashCode() + (ignoreCase ? 32 : 79); } } Modified: geronimo/trunk/specs/javamail/src/test/javax/mail/event/ConnectionEventTest.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/test/javax/mail/event/ConnectionEventTest.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/test/javax/mail/event/ConnectionEventTest.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/test/javax/mail/event/ConnectionEventTest.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/test/javax/mail/event/ConnectionEventTest.java (original) +++ geronimo/trunk/specs/javamail/src/test/javax/mail/event/ConnectionEventTest.java Tue Jan 18 19:44:27 2005 @@ -60,10 +60,5 @@ doEventTests(ConnectionEvent.CLOSED); doEventTests(ConnectionEvent.OPENED); doEventTests(ConnectionEvent.DISCONNECTED); - try { - ConnectionEvent event = new ConnectionEvent(this, -12345); - fail("Expected exception due to invalid type " + event.getType()); - } catch (IllegalArgumentException e) { - } } } Modified: geronimo/trunk/specs/javamail/src/test/javax/mail/event/FolderEventTest.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/test/javax/mail/event/FolderEventTest.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/test/javax/mail/event/FolderEventTest.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/test/javax/mail/event/FolderEventTest.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/test/javax/mail/event/FolderEventTest.java (original) +++ geronimo/trunk/specs/javamail/src/test/javax/mail/event/FolderEventTest.java Tue Jan 18 19:44:27 2005 @@ -28,11 +28,6 @@ doEventTests(FolderEvent.CREATED); doEventTests(FolderEvent.RENAMED); doEventTests(FolderEvent.DELETED); - try { - FolderEvent event = new FolderEvent(this, null, -12345); - fail("Expected exception due to invalid type " + event.getType()); - } catch (IllegalArgumentException e) { - } } private void doEventTests(int type) { FolderEvent event = new FolderEvent(this, null, type); Modified: geronimo/trunk/specs/javamail/src/test/javax/mail/event/MessageChangedEventTest.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/test/javax/mail/event/MessageChangedEventTest.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/test/javax/mail/event/MessageChangedEventTest.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/test/javax/mail/event/MessageChangedEventTest.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/test/javax/mail/event/MessageChangedEventTest.java (original) +++ geronimo/trunk/specs/javamail/src/test/javax/mail/event/MessageChangedEventTest.java Tue Jan 18 19:44:27 2005 @@ -27,14 +27,6 @@ public void testEvent() { doEventTests(MessageChangedEvent.ENVELOPE_CHANGED); doEventTests(MessageChangedEvent.FLAGS_CHANGED); - try { - MessageChangedEvent event = - new MessageChangedEvent(this, -12345, null); - fail( - "Expected exception due to invalid type " - + event.getMessageChangeType()); - } catch (IllegalArgumentException e) { - } } private void doEventTests(int type) { MessageChangedEvent event = new MessageChangedEvent(this, type, null); Modified: geronimo/trunk/specs/javamail/src/test/javax/mail/event/TransportEventTest.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/test/javax/mail/event/TransportEventTest.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/test/javax/mail/event/TransportEventTest.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/test/javax/mail/event/TransportEventTest.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/test/javax/mail/event/TransportEventTest.java (original) +++ geronimo/trunk/specs/javamail/src/test/javax/mail/event/TransportEventTest.java Tue Jan 18 19:44:27 2005 @@ -35,19 +35,6 @@ doEventTests(TransportEvent.MESSAGE_DELIVERED); doEventTests(TransportEvent.MESSAGE_PARTIALLY_DELIVERED); doEventTests(TransportEvent.MESSAGE_NOT_DELIVERED); - // TODO Should really instantiate some messages to test this - try { - TransportEvent event = - new TransportEvent( - TestData.getTestTransport(), - -12345, - null, - null, - null, - null); - fail("Expected exception due to invalid type " + event.getType()); - } catch (IllegalArgumentException e) { - } } private void doEventTests(int type) throws AddressException { Folder folder = TestData.getTestFolder(); Modified: geronimo/trunk/specs/javamail/src/test/javax/mail/internet/InternetAddressTest.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/specs/javamail/src/test/javax/mail/internet/InternetAddressTest.java?view=diff&rev=125583&p1=geronimo/trunk/specs/javamail/src/test/javax/mail/internet/InternetAddressTest.java&r1=125582&p2=geronimo/trunk/specs/javamail/src/test/javax/mail/internet/InternetAddressTest.java&r2=125583 ============================================================================== --- geronimo/trunk/specs/javamail/src/test/javax/mail/internet/InternetAddressTest.java (original) +++ geronimo/trunk/specs/javamail/src/test/javax/mail/internet/InternetAddressTest.java Tue Jan 18 19:44:27 2005 @@ -21,25 +21,26 @@ * @version $Rev$ $Date$ */ public class InternetAddressTest extends TestCase { - public InternetAddressTest(String arg0) { - super(arg0); + private InternetAddress address; + + public void testIsGroup() { + address.setAddress(":user@host;"); + assertTrue(address.isGroup()); + + address.setAddress(":user@host, user2@host;"); + assertTrue(address.isGroup()); + + address.setAddress("User Group :user@host;"); + assertTrue(address.isGroup()); + + address.setAddress("A \"User Group\" :user@host;"); + assertTrue(address.isGroup()); + + address.setAddress("\"Fake:Group\" user@host"); + assertFalse(address.isGroup()); } - public void testInternetAddress() throws AddressException { - InternetAddress ia = - new InternetAddress("Alex Blewitt "); - assertEquals("Alex Blewitt", ia.getPersonal()); - assertEquals("Alex.Blewitt@bigboy.com", ia.getAddress()); - } - public void testInternetAddresses() throws AddressException { - InternetAddress[] ia = - InternetAddress.parse( - "Mr B , Mrs B , Milly "); - assertEquals(3, ia.length); - assertEquals("Mr B", ia[0].getPersonal()); - assertEquals("Mr.B@bigboy.com", ia[0].getAddress()); - assertEquals("Mrs B", ia[1].getPersonal()); - assertEquals("Mrs.B@biggirl.com", ia[1].getAddress()); - assertEquals("Milly", ia[2].getPersonal()); - assertEquals("Milly@thedog.com", ia[2].getAddress()); + + protected void setUp() throws Exception { + address = new InternetAddress(); } }