Update 2.9.1

* Fix some problem with re-register
* Add directly mail.jar in AuthMe Builds
we also do not need the mail.jar in the lib folder
This commit is contained in:
Xephi
2013-08-07 21:21:58 +02:00
parent f585d1012a
commit d06a5f4e53
229 changed files with 66213 additions and 228 deletions
+88
View File
@@ -0,0 +1,88 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.io.Serializable;
/**
* This abstract class models the addresses in a message.
* Subclasses provide specific implementations. Subclasses
* will typically be serializable so that (for example) the
* use of Address objects in search terms can be serialized
* along with the search terms.
*
* @author John Mani
* @author Bill Shannon
*/
public abstract class Address implements Serializable {
private static final long serialVersionUID = -5822459626751992278L;
/**
* Return a type string that identifies this address type.
*
* @return address type
* @see javax.mail.internet.InternetAddress
*/
public abstract String getType();
/**
* Return a String representation of this address object.
*
* @return string representation of this address
*/
public abstract String toString();
/**
* The equality operator. Subclasses should provide an
* implementation of this method that supports value equality
* (do the two Address objects represent the same destination?),
* not object reference equality. A subclass must also provide
* a corresponding implementation of the <code>hashCode</code>
* method that preserves the general contract of
* <code>equals</code> and <code>hashCode</code> - objects that
* compare as equal must have the same hashCode.
*
* @param address Address object
*/
public abstract boolean equals(Object address);
}
@@ -0,0 +1,84 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* This exception is thrown when the connect method on a Store or
* Transport object fails due to an authentication failure (e.g.,
* bad user name or password).
*
* @author Bill Shannon
*/
public class AuthenticationFailedException extends MessagingException {
private static final long serialVersionUID = 492080754054436511L;
/**
* Constructs an AuthenticationFailedException.
*/
public AuthenticationFailedException() {
super();
}
/**
* Constructs an AuthenticationFailedException with the specified
* detail message.
*
* @param message The detailed error message
*/
public AuthenticationFailedException(String message) {
super(message);
}
/**
* Constructs an AuthenticationFailedException with the specified
* detail message and embedded exception. The exception is chained
* to this exception.
*
* @param message The detailed error message
* @param e The embedded exception
* @since JavaMail 1.5
*/
public AuthenticationFailedException(String message, Exception e) {
super(message, e);
}
}
+172
View File
@@ -0,0 +1,172 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.net.InetAddress;
/**
* The class Authenticator represents an object that knows how to obtain
* authentication for a network connection. Usually, it will do this
* by prompting the user for information.
* <p>
* Applications use this class by creating a subclass, and registering
* an instance of that subclass with the session when it is created.
* When authentication is required, the system will invoke a method
* on the subclass (like getPasswordAuthentication). The subclass's
* method can query about the authentication being requested with a
* number of inherited methods (getRequestingXXX()), and form an
* appropriate message for the user.
* <p>
* All methods that request authentication have a default implementation
* that fails.
*
* @see java.net.Authenticator
* @see javax.mail.Session#getInstance(java.util.Properties,
* javax.mail.Authenticator)
* @see javax.mail.Session#getDefaultInstance(java.util.Properties,
* javax.mail.Authenticator)
* @see javax.mail.Session#requestPasswordAuthentication
* @see javax.mail.PasswordAuthentication
*
* @author Bill Foote
* @author Bill Shannon
*/
// There are no abstract methods, but to be useful the user must
// subclass.
public abstract class Authenticator {
private InetAddress requestingSite;
private int requestingPort;
private String requestingProtocol;
private String requestingPrompt;
private String requestingUserName;
private void reset() {
requestingSite = null;
requestingPort = -1;
requestingProtocol = null;
requestingPrompt = null;
requestingUserName = null;
}
/**
* Ask the authenticator for a password.
* <p>
*
* @param addr The InetAddress of the site requesting authorization,
* or null if not known.
* @param port the port for the requested connection
* @param protocol The protocol that's requesting the connection
* (@see java.net.Authenticator.getProtocol())
* @param prompt A prompt string for the user
*
* @return The username/password, or null if one can't be gotten.
*/
final PasswordAuthentication requestPasswordAuthentication(
InetAddress addr, int port, String protocol,
String prompt, String defaultUserName) {
reset();
requestingSite = addr;
requestingPort = port;
requestingProtocol = protocol;
requestingPrompt = prompt;
requestingUserName = defaultUserName;
return getPasswordAuthentication();
}
/**
* @return the InetAddress of the site requesting authorization, or null
* if it's not available.
*/
protected final InetAddress getRequestingSite() {
return requestingSite;
}
/**
* @return the port for the requested connection
*/
protected final int getRequestingPort() {
return requestingPort;
}
/**
* Give the protocol that's requesting the connection. Often this
* will be based on a URLName.
*
* @return the protcol
*
* @see javax.mail.URLName#getProtocol
*/
protected final String getRequestingProtocol() {
return requestingProtocol;
}
/**
* @return the prompt string given by the requestor
*/
protected final String getRequestingPrompt() {
return requestingPrompt;
}
/**
* @return the default user name given by the requestor
*/
protected final String getDefaultUserName() {
return requestingUserName;
}
/**
* Called when password authentication is needed. Subclasses should
* override the default implementation, which returns null. <p>
*
* Note that if this method uses a dialog to prompt the user for this
* information, the dialog needs to block until the user supplies the
* information. This method can not simply return after showing the
* dialog.
* @return The PasswordAuthentication collected from the
* user, or null if none is provided.
*/
protected PasswordAuthentication getPasswordAuthentication() {
return null;
}
}
+82
View File
@@ -0,0 +1,82 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* This class models a Part that is contained within a Multipart.
* This is an abstract class. Subclasses provide actual implementations.<p>
*
* BodyPart implements the Part interface. Thus, it contains a set of
* attributes and a "content".
*
* @author John Mani
* @author Bill Shannon
*/
public abstract class BodyPart implements Part {
/**
* The <code>Multipart</code> object containing this <code>BodyPart</code>,
* if known.
* @since JavaMail 1.1
*/
protected Multipart parent;
/**
* Return the containing <code>Multipart</code> object,
* or <code>null</code> if not known.
*/
public Multipart getParent() {
return parent;
}
/**
* Set the parent of this <code>BodyPart</code> to be the specified
* <code>Multipart</code>. Normally called by <code>Multipart</code>'s
* <code>addBodyPart</code> method. <code>parent</code> may be
* <code>null</code> if the <code>BodyPart</code> is being removed
* from its containing <code>Multipart</code>.
* @since JavaMail 1.1
*/
void setParent(Multipart parent) {
this.parent = parent;
}
}
@@ -0,0 +1,79 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* A {@link javax.activation.DataSource DataSource} that also implements
* <code>EncodingAware</code> may specify the Content-Transfer-Encoding
* to use for its data. Valid Content-Transfer-Encoding values specified
* by RFC 2045 are "7bit", "8bit", "quoted-printable", "base64", and "binary".
* <p>
* For example, a {@link javax.activation.FileDataSource FileDataSource}
* could be created that forces all files to be base64 encoded: <p>
* <blockquote><pre>
* public class Base64FileDataSource extends FileDataSource
* implements EncodingAware {
* public Base64FileDataSource(File file) {
* super(file);
* }
*
* // implements EncodingAware.getEncoding()
* public String getEncoding() {
* return "base64";
* }
* }
* </pre></blockquote><p>
*
* @since JavaMail 1.5
* @author Bill Shannon
*/
public interface EncodingAware {
/**
* Return the MIME Content-Transfer-Encoding to use for this data,
* or null to indicate that an appropriate value should be chosen
* by the caller.
*
* @return the Content-Transfer-Encoding value, or null
*/
public String getEncoding();
}
+158
View File
@@ -0,0 +1,158 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.io.*;
import java.util.Vector;
import javax.mail.event.MailEvent;
/**
* Package private class used by Store & Folder to dispatch events.
* This class implements an event queue, and a dispatcher thread that
* dequeues and dispatches events from the queue.
*
* Pieces stolen from sun.misc.Queue.
*
* @author Bill Shannon
*/
class EventQueue implements Runnable {
static class QueueElement {
QueueElement next = null;
QueueElement prev = null;
MailEvent event = null;
Vector vector = null;
QueueElement(MailEvent event, Vector vector) {
this.event = event;
this.vector = vector;
}
}
private QueueElement head = null;
private QueueElement tail = null;
private Thread qThread;
public EventQueue() {
qThread = new Thread(this, "JavaMail-EventQueue");
qThread.setDaemon(true); // not a user thread
qThread.start();
}
/**
* Enqueue an event.
*/
public synchronized void enqueue(MailEvent event, Vector vector) {
QueueElement newElt = new QueueElement(event, vector);
if (head == null) {
head = newElt;
tail = newElt;
} else {
newElt.next = head;
head.prev = newElt;
head = newElt;
}
notifyAll();
}
/**
* Dequeue the oldest object on the queue.
* Used only by the run() method.
*
* @return the oldest object on the queue.
* @exception java.lang.InterruptedException if another thread has
* interrupted this thread.
*/
private synchronized QueueElement dequeue()
throws InterruptedException {
while (tail == null)
wait();
QueueElement elt = tail;
tail = elt.prev;
if (tail == null) {
head = null;
} else {
tail.next = null;
}
elt.prev = elt.next = null;
return elt;
}
/**
* Pull events off the queue and dispatch them.
*/
public void run() {
QueueElement qe;
try {
loop:
for (;;) {
qe = dequeue(); // blocks until an item is available
MailEvent e = qe.event;
Vector v = qe.vector;
for (int i = 0; i < v.size(); i++)
try {
e.dispatch(v.elementAt(i));
} catch (Throwable t) {
if (t instanceof InterruptedException)
break loop;
// ignore anything else thrown by the listener
}
qe = null; e = null; v = null;
}
} catch (InterruptedException e) {
// just die
}
}
/**
* Stop the dispatcher so we can be destroyed.
*/
void stop() {
if (qThread != null) {
qThread.interrupt(); // kill our thread
qThread = null;
}
}
}
+238
View File
@@ -0,0 +1,238 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.util.Vector;
/**
* Clients use a FetchProfile to list the Message attributes that
* it wishes to prefetch from the server for a range of messages.<p>
*
* Messages obtained from a Folder are light-weight objects that
* typically start off as empty references to the actual messages.
* Such a Message object is filled in "on-demand" when the appropriate
* get*() methods are invoked on that particular Message. Certain
* server-based message access protocols (Ex: IMAP) allow batch
* fetching of message attributes for a range of messages in a single
* request. Clients that want to use message attributes for a range of
* Messages (Example: to display the top-level headers in a headerlist)
* might want to use the optimization provided by such servers. The
* <code>FetchProfile</code> allows the client to indicate this desire
* to the server. <p>
*
* Note that implementations are not obligated to support
* FetchProfiles, since there might be cases where the backend service
* does not allow easy, efficient fetching of such profiles. <p>
*
* Sample code that illustrates the use of a FetchProfile is given
* below: <p>
* <blockquote>
* <pre>
*
* Message[] msgs = folder.getMessages();
*
* FetchProfile fp = new FetchProfile();
* fp.add(FetchProfile.Item.ENVELOPE);
* fp.add("X-mailer");
* folder.fetch(msgs, fp);
*
* </pre></blockquote><p>
*
* @see javax.mail.Folder#fetch
* @author John Mani
* @author Bill Shannon
*/
public class FetchProfile {
private Vector specials; // specials
private Vector headers; // vector of header names
/**
* This inner class is the base class of all items that
* can be requested in a FetchProfile. The items currently
* defined here are <code>ENVELOPE</code>, <code>CONTENT_INFO</code>
* and <code>FLAGS</code>. The <code>UIDFolder</code> interface
* defines the <code>UID</code> Item as well. <p>
*
* Note that this class only has a protected constructor, therby
* restricting new Item types to either this class or subclasses.
* This effectively implements a enumeration of allowed Item types.
*
* @see UIDFolder
*/
public static class Item {
/**
* This is the Envelope item. <p>
*
* The Envelope is an aggregration of the common attributes
* of a Message. Implementations should include the following
* attributes: From, To, Cc, Bcc, ReplyTo, Subject and Date.
* More items may be included as well. <p>
*
* For implementations of the IMAP4 protocol (RFC 2060), the
* Envelope should include the ENVELOPE data item. More items
* may be included too.
*/
public static final Item ENVELOPE = new Item("ENVELOPE");
/**
* This item is for fetching information about the
* content of the message. <p>
*
* This includes all the attributes that describe the content
* of the message. Implementations should include the following
* attributes: ContentType, ContentDisposition,
* ContentDescription, Size and LineCount. Other items may be
* included as well.
*/
public static final Item CONTENT_INFO = new Item("CONTENT_INFO");
/**
* SIZE is a fetch profile item that can be included in a
* <code>FetchProfile</code> during a fetch request to a Folder.
* This item indicates that the sizes of the messages in the specified
* range should be prefetched. <p>
*
* @since JavaMail 1.5
*/
public static final Item SIZE = new Item("SIZE");
/**
* This is the Flags item.
*/
public static final Item FLAGS = new Item("FLAGS");
private String name;
/**
* Constructor for an item. The name is used only for debugging.
*/
protected Item(String name) {
this.name = name;
}
/**
* Include the name in the toString return value for debugging.
*/
public String toString() {
return getClass().getName() + "[" + name + "]";
}
}
/**
* Create an empty FetchProfile.
*/
public FetchProfile() {
specials = null;
headers = null;
}
/**
* Add the given special item as one of the attributes to
* be prefetched.
*
* @param item the special item to be fetched
* @see FetchProfile.Item#ENVELOPE
* @see FetchProfile.Item#CONTENT_INFO
* @see FetchProfile.Item#FLAGS
*/
public void add(Item item) {
if (specials == null)
specials = new Vector();
specials.addElement(item);
}
/**
* Add the specified header-field to the list of attributes
* to be prefetched.
*
* @param headerName header to be prefetched
*/
public void add(String headerName) {
if (headers == null)
headers = new Vector();
headers.addElement(headerName);
}
/**
* Returns true if the fetch profile contains given special item.
*/
public boolean contains(Item item) {
return specials != null && specials.contains(item);
}
/**
* Returns true if the fetch profile contains given header name.
*/
public boolean contains(String headerName) {
return headers != null && headers.contains(headerName);
}
/**
* Get the items set in this profile.
*
* @return items set in this profile
*/
public Item[] getItems() {
if (specials == null)
return new Item[0];
Item[] s = new Item[specials.size()];
specials.copyInto(s);
return s;
}
/**
* Get the names of the header-fields set in this profile.
*
* @return headers set in this profile
*/
public String[] getHeaderNames() {
if (headers == null)
return new String[0];
String[] s = new String[headers.size()];
headers.copyInto(s);
return s;
}
}
+589
View File
@@ -0,0 +1,589 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.io.Serializable;
import java.util.*;
/**
* The Flags class represents the set of flags on a Message. Flags
* are composed of predefined system flags, and user defined flags. <p>
*
* A System flag is represented by the <code>Flags.Flag</code>
* inner class. A User defined flag is represented as a String.
* User flags are case-independent. <p>
*
* A set of standard system flags are predefined. Most folder
* implementations are expected to support these flags. Some
* implementations may also support arbitrary user-defined flags. The
* <code>getPermanentFlags</code> method on a Folder returns a Flags
* object that holds all the flags that are supported by that folder
* implementation. <p>
*
* A Flags object is serializable so that (for example) the
* use of Flags objects in search terms can be serialized
* along with the search terms. <p>
*
* <strong>Warning:</strong>
* Serialized objects of this class may not be compatible with future
* JavaMail API releases. The current serialization support is
* appropriate for short term storage. <p>
*
* The below code sample illustrates how to set, examine, and get the
* flags for a message. <p>
* <pre>
*
* Message m = folder.getMessage(1);
* m.setFlag(Flags.Flag.DELETED, true); // set the DELETED flag
*
* // Check if DELETED flag is set on this message
* if (m.isSet(Flags.Flag.DELETED))
* System.out.println("DELETED message");
*
* // Examine ALL system flags for this message
* Flags flags = m.getFlags();
* Flags.Flag[] sf = flags.getSystemFlags();
* for (int i = 0; i < sf.length; i++) {
* if (sf[i] == Flags.Flag.DELETED)
* System.out.println("DELETED message");
* else if (sf[i] == Flags.Flag.SEEN)
* System.out.println("SEEN message");
* ......
* ......
* }
* </pre>
* <p>
*
* @see Folder#getPermanentFlags
* @author John Mani
* @author Bill Shannon
*/
public class Flags implements Cloneable, Serializable {
private int system_flags = 0;
private Hashtable user_flags = null;
private final static int ANSWERED_BIT = 0x01;
private final static int DELETED_BIT = 0x02;
private final static int DRAFT_BIT = 0x04;
private final static int FLAGGED_BIT = 0x08;
private final static int RECENT_BIT = 0x10;
private final static int SEEN_BIT = 0x20;
private final static int USER_BIT = 0x80000000;
private static final long serialVersionUID = 6243590407214169028L;
/**
* This inner class represents an individual system flag. A set
* of standard system flag objects are predefined here.
*/
public static final class Flag {
/**
* This message has been answered. This flag is set by clients
* to indicate that this message has been answered to.
*/
public static final Flag ANSWERED = new Flag(ANSWERED_BIT);
/**
* This message is marked deleted. Clients set this flag to
* mark a message as deleted. The expunge operation on a folder
* removes all messages in that folder that are marked for deletion.
*/
public static final Flag DELETED = new Flag(DELETED_BIT);
/**
* This message is a draft. This flag is set by clients
* to indicate that the message is a draft message.
*/
public static final Flag DRAFT = new Flag(DRAFT_BIT);
/**
* This message is flagged. No semantic is defined for this flag.
* Clients alter this flag.
*/
public static final Flag FLAGGED = new Flag(FLAGGED_BIT);
/**
* This message is recent. Folder implementations set this flag
* to indicate that this message is new to this folder, that is,
* it has arrived since the last time this folder was opened. <p>
*
* Clients cannot alter this flag.
*/
public static final Flag RECENT = new Flag(RECENT_BIT);
/**
* This message is seen. This flag is implicitly set by the
* implementation when the this Message's content is returned
* to the client in some form. The <code>getInputStream</code>
* and <code>getContent</code> methods on Message cause this
* flag to be set. <p>
*
* Clients can alter this flag.
*/
public static final Flag SEEN = new Flag(SEEN_BIT);
/**
* A special flag that indicates that this folder supports
* user defined flags. <p>
*
* The implementation sets this flag. Clients cannot alter
* this flag but can use it to determine if a folder supports
* user defined flags by using
* <code>folder.getPermanentFlags().contains(Flags.Flag.USER)</code>.
*/
public static final Flag USER = new Flag(USER_BIT);
// flags are stored as bits for efficiency
private int bit;
private Flag(int bit) {
this.bit = bit;
}
}
/**
* Construct an empty Flags object.
*/
public Flags() { }
/**
* Construct a Flags object initialized with the given flags.
*
* @param flags the flags for initialization
*/
public Flags(Flags flags) {
this.system_flags = flags.system_flags;
if (flags.user_flags != null)
this.user_flags = (Hashtable)flags.user_flags.clone();
}
/**
* Construct a Flags object initialized with the given system flag.
*
* @param flag the flag for initialization
*/
public Flags(Flag flag) {
this.system_flags |= flag.bit;
}
/**
* Construct a Flags object initialized with the given user flag.
*
* @param flag the flag for initialization
*/
public Flags(String flag) {
user_flags = new Hashtable(1);
user_flags.put(flag.toLowerCase(Locale.ENGLISH), flag);
}
/**
* Add the specified system flag to this Flags object.
*
* @param flag the flag to add
*/
public void add(Flag flag) {
system_flags |= flag.bit;
}
/**
* Add the specified user flag to this Flags object.
*
* @param flag the flag to add
*/
public void add(String flag) {
if (user_flags == null)
user_flags = new Hashtable(1);
user_flags.put(flag.toLowerCase(Locale.ENGLISH), flag);
}
/**
* Add all the flags in the given Flags object to this
* Flags object.
*
* @param f Flags object
*/
public void add(Flags f) {
system_flags |= f.system_flags; // add system flags
if (f.user_flags != null) { // add user-defined flags
if (user_flags == null)
user_flags = new Hashtable(1);
Enumeration e = f.user_flags.keys();
while (e.hasMoreElements()) {
String s = (String)e.nextElement();
user_flags.put(s, f.user_flags.get(s));
}
}
}
/**
* Remove the specified system flag from this Flags object.
*
* @param flag the flag to be removed
*/
public void remove(Flag flag) {
system_flags &= ~flag.bit;
}
/**
* Remove the specified user flag from this Flags object.
*
* @param flag the flag to be removed
*/
public void remove(String flag) {
if (user_flags != null)
user_flags.remove(flag.toLowerCase(Locale.ENGLISH));
}
/**
* Remove all flags in the given Flags object from this
* Flags object.
*
* @param f the flag to be removed
*/
public void remove(Flags f) {
system_flags &= ~f.system_flags; // remove system flags
if (f.user_flags != null) {
if (user_flags == null)
return;
Enumeration e = f.user_flags.keys();
while (e.hasMoreElements())
user_flags.remove(e.nextElement());
}
}
/**
* Check whether the specified system flag is present in this Flags object.
*
* @return true of the given flag is present, otherwise false.
*/
public boolean contains(Flag flag) {
return (system_flags & flag.bit) != 0;
}
/**
* Check whether the specified user flag is present in this Flags object.
*
* @return true of the given flag is present, otherwise false.
*/
public boolean contains(String flag) {
if (user_flags == null)
return false;
else
return user_flags.containsKey(flag.toLowerCase(Locale.ENGLISH));
}
/**
* Check whether all the flags in the specified Flags object are
* present in this Flags object.
*
* @return true if all flags in the given Flags object are present,
* otherwise false.
*/
public boolean contains(Flags f) {
// Check system flags
if ((f.system_flags & system_flags) != f.system_flags)
return false;
// Check user flags
if (f.user_flags != null) {
if (user_flags == null)
return false;
Enumeration e = f.user_flags.keys();
while (e.hasMoreElements()) {
if (!user_flags.containsKey(e.nextElement()))
return false;
}
}
// If we've made it till here, return true
return true;
}
/**
* Check whether the two Flags objects are equal.
*
* @return true if they're equal
*/
public boolean equals(Object obj) {
if (!(obj instanceof Flags))
return false;
Flags f = (Flags)obj;
// Check system flags
if (f.system_flags != this.system_flags)
return false;
// Check user flags
if (f.user_flags == null && this.user_flags == null)
return true;
if (f.user_flags != null && this.user_flags != null &&
f.user_flags.size() == this.user_flags.size()) {
Enumeration e = f.user_flags.keys();
while (e.hasMoreElements()) {
if (!this.user_flags.containsKey(e.nextElement()))
return false;
}
return true;
}
return false;
}
/**
* Compute a hash code for this Flags object.
*
* @return the hash code
*/
public int hashCode() {
int hash = system_flags;
if (user_flags != null) {
Enumeration e = user_flags.keys();
while (e.hasMoreElements())
hash += ((String)e.nextElement()).hashCode();
}
return hash;
}
/**
* Return all the system flags in this Flags object. Returns
* an array of size zero if no flags are set.
*
* @return array of Flags.Flag objects representing system flags
*/
public Flag[] getSystemFlags() {
Vector v = new Vector();
if ((system_flags & ANSWERED_BIT) != 0)
v.addElement(Flag.ANSWERED);
if ((system_flags & DELETED_BIT) != 0)
v.addElement(Flag.DELETED);
if ((system_flags & DRAFT_BIT) != 0)
v.addElement(Flag.DRAFT);
if ((system_flags & FLAGGED_BIT) != 0)
v.addElement(Flag.FLAGGED);
if ((system_flags & RECENT_BIT) != 0)
v.addElement(Flag.RECENT);
if ((system_flags & SEEN_BIT) != 0)
v.addElement(Flag.SEEN);
if ((system_flags & USER_BIT) != 0)
v.addElement(Flag.USER);
Flag[] f = new Flag[v.size()];
v.copyInto(f);
return f;
}
/**
* Return all the user flags in this Flags object. Returns
* an array of size zero if no flags are set.
*
* @return array of Strings, each String represents a flag.
*/
public String[] getUserFlags() {
Vector v = new Vector();
if (user_flags != null) {
Enumeration e = user_flags.elements();
while (e.hasMoreElements())
v.addElement(e.nextElement());
}
String[] f = new String[v.size()];
v.copyInto(f);
return f;
}
/**
* Returns a clone of this Flags object.
*/
public Object clone() {
Flags f = null;
try {
f = (Flags)super.clone();
} catch (CloneNotSupportedException cex) {
// ignore, can't happen
}
if (this.user_flags != null)
f.user_flags = (Hashtable)this.user_flags.clone();
return f;
}
/*****
public static void main(String argv[]) throws Exception {
// a new flags object
Flags f1 = new Flags();
f1.add(Flags.Flag.DELETED);
f1.add(Flags.Flag.SEEN);
f1.add(Flags.Flag.RECENT);
f1.add(Flags.Flag.ANSWERED);
// check copy constructor with only system flags
Flags fc = new Flags(f1);
if (f1.equals(fc) && fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// check clone with only system flags
fc = (Flags)f1.clone();
if (f1.equals(fc) && fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// add a user flag and make sure it still works right
f1.add("MyFlag");
// shouldn't be equal here
if (!f1.equals(fc) && !fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// check clone
fc = (Flags)f1.clone();
if (f1.equals(fc) && fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// make sure user flag hash tables are separate
fc.add("AnotherFlag");
if (!f1.equals(fc) && !fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// check copy constructor
fc = new Flags(f1);
if (f1.equals(fc) && fc.equals(f1))
System.out.println("success");
else
System.out.println("fail");
// another new flags object
Flags f2 = new Flags(Flags.Flag.ANSWERED);
f2.add("MyFlag");
if (f1.contains(Flags.Flag.DELETED))
System.out.println("success");
else
System.out.println("fail");
if (f1.contains(Flags.Flag.SEEN))
System.out.println("success");
else
System.out.println("fail");
if (f1.contains(Flags.Flag.RECENT))
System.out.println("success");
else
System.out.println("fail");
if (f1.contains("MyFlag"))
System.out.println("success");
else
System.out.println("fail");
if (f2.contains(Flags.Flag.ANSWERED))
System.out.println("success");
else
System.out.println("fail");
System.out.println("----------------");
String[] s = f1.getUserFlags();
for (int i = 0; i < s.length; i++)
System.out.println(s[i]);
System.out.println("----------------");
s = f2.getUserFlags();
for (int i = 0; i < s.length; i++)
System.out.println(s[i]);
System.out.println("----------------");
if (f1.contains(f2)) // this should be true
System.out.println("success");
else
System.out.println("fail");
if (!f2.contains(f1)) // this should be false
System.out.println("success");
else
System.out.println("fail");
Flags f3 = new Flags();
f3.add(Flags.Flag.DELETED);
f3.add(Flags.Flag.SEEN);
f3.add(Flags.Flag.RECENT);
f3.add(Flags.Flag.ANSWERED);
f3.add("ANOTHERFLAG");
f3.add("MYFLAG");
f1.add("AnotherFlag");
if (f1.equals(f3))
System.out.println("equals success");
else
System.out.println("fail");
if (f3.equals(f1))
System.out.println("equals success");
else
System.out.println("fail");
System.out.println("f1 hash code " + f1.hashCode());
System.out.println("f3 hash code " + f3.hashCode());
if (f1.hashCode() == f3.hashCode())
System.out.println("success");
else
System.out.println("fail");
}
****/
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,105 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* This exception is thrown when a method is invoked on a Messaging object
* and the Folder that owns that object has died due to some reason. <p>
*
* Following the exception, the Folder is reset to the "closed" state.
* All messaging objects owned by the Folder should be considered invalid.
* The Folder can be reopened using the "open" method to reestablish the
* lost connection. <p>
*
* The getMessage() method returns more detailed information about the
* error that caused this exception. <p>
*
* @author John Mani
*/
public class FolderClosedException extends MessagingException {
transient private Folder folder;
private static final long serialVersionUID = 1687879213433302315L;
/**
* Constructs a FolderClosedException.
*
* @param folder The Folder
*/
public FolderClosedException(Folder folder) {
this(folder, null);
}
/**
* Constructs a FolderClosedException with the specified
* detail message.
*
* @param folder The Folder
* @param message The detailed error message
*/
public FolderClosedException(Folder folder, String message) {
super(message);
this.folder = folder;
}
/**
* Constructs a FolderClosedException with the specified
* detail message and embedded exception. The exception is chained
* to this exception.
*
* @param folder The Folder
* @param message The detailed error message
* @param e The embedded exception
* @since JavaMail 1.5
*/
public FolderClosedException(Folder folder, String message, Exception e) {
super(message, e);
this.folder = folder;
}
/**
* Returns the dead Folder object
*/
public Folder getFolder() {
return folder;
}
}
@@ -0,0 +1,124 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.lang.*;
/**
* This exception is thrown by Folder methods, when those
* methods are invoked on a non existent folder.
*
* @author John Mani
*/
public class FolderNotFoundException extends MessagingException {
transient private Folder folder;
private static final long serialVersionUID = 472612108891249403L;
/**
* Constructs a FolderNotFoundException with no detail message.
*/
public FolderNotFoundException() {
super();
}
/**
* Constructs a FolderNotFoundException.
*
* @param folder The Folder
* @since JavaMail 1.2
*/
public FolderNotFoundException(Folder folder) {
super();
this.folder = folder;
}
/**
* Constructs a FolderNotFoundException with the specified
* detail message.
*
* @param folder The Folder
* @param s The detailed error message
* @since JavaMail 1.2
*/
public FolderNotFoundException(Folder folder, String s) {
super(s);
this.folder = folder;
}
/**
* Constructs a FolderNotFoundException with the specified
* detail message and embedded exception. The exception is chained
* to this exception.
*
* @param folder The Folder
* @param s The detailed error message
* @param e The embedded exception
* @since JavaMail 1.5
*/
public FolderNotFoundException(Folder folder, String s, Exception e) {
super(s, e);
this.folder = folder;
}
/**
* Constructs a FolderNotFoundException with the specified detail message
* and the specified folder.
*
* @param s The detail message
* @param folder The Folder
*/
public FolderNotFoundException(String s, Folder folder) {
super(s);
this.folder = folder;
}
/**
* Returns the offending Folder object.
*
* @return the Folder object. Note that the returned value can be
* <code>null</code>.
*/
public Folder getFolder() {
return folder;
}
}
+94
View File
@@ -0,0 +1,94 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* The Header class stores a name/value pair to represent headers.
*
* @author John Mani
*/
public class Header {
/**
* The name of the header.
*
* @since JavaMail 1.4
*/
protected String name;
/**
* The value of the header.
*
* @since JavaMail 1.4
*/
protected String value;
/**
* Construct a Header object.
*
* @param name name of the header
* @param value value of the header
*/
public Header(String name, String value) {
this.name = name;
this.value = value;
}
/**
* Returns the name of this header.
*
* @return name of the header
*/
public String getName() {
return name;
}
/**
* Returns the value of this header.
*
* @return value of the header
*/
public String getValue() {
return value;
}
}
@@ -0,0 +1,84 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* The exception thrown when a write is attempted on a read-only attribute
* of any Messaging object.
*
* @author John Mani
*/
public class IllegalWriteException extends MessagingException {
private static final long serialVersionUID = 3974370223328268013L;
/**
* Constructs an IllegalWriteException with no detail message.
*/
public IllegalWriteException() {
super();
}
/**
* Constructs an IllegalWriteException with the specified
* detail message.
*
* @param s The detailed error message
*/
public IllegalWriteException(String s) {
super(s);
}
/**
* Constructs an IllegalWriteException with the specified
* detail message and embedded exception. The exception is chained
* to this exception.
*
* @param s The detailed error message
* @param e The embedded exception
* @since JavaMail 1.5
*/
public IllegalWriteException(String s, Exception e) {
super(s, e);
}
}
@@ -0,0 +1,112 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation used by Java EE applications to define a <code>MailSession</code>
* to be registered with JNDI. The <code>MailSession</code> may be configured
* by setting the annotation elements for commonly used <code>Session</code>
* properties. Additional standard and vendor-specific properties may be
* specified using the <code>properties</code> element.
* <p/>
* The session will be registered under the name specified in the
* <code>name</code> element. It may be defined to be in any valid
* <code>Java EE</code> namespace, and will determine the accessibility of
* the session from other components.
*
* @since JavaMail 1.5
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MailSessionDefinition {
/**
* Description of this mail session.
*/
String description() default "";
/**
* JNDI name by which the mail session will be registered.
*/
String name();
/**
* Store protocol name.
*/
String storeProtocol() default "";
/**
* Transport protocol name.
*/
String transportProtocol() default "";
/**
* Host name for the mail server.
*/
String host() default "";
/**
* User name to use for authentication.
*/
String user() default "";
/**
* Password to use for authentication.
*/
String password() default "";
/**
* From address for the user.
*/
String from() default "";
/**
* Properties to include in the Session.
* Properties are specified using the format:
* <i>propertyName=propertyValue</i> with one property per array element.
*/
String[] properties() default {};
}
@@ -0,0 +1,58 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
/**
* Declares one or more <code>MailSessionDefinition</code> annotations.
*
* @see MailSessionDefinition
* @since JavaMail 1.5
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MailSessionDefinitions {
MailSessionDefinition[] value();
}
+717
View File
@@ -0,0 +1,717 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.util.Vector;
import java.util.Date;
import java.util.Properties;
import java.io.*;
import javax.mail.search.SearchTerm;
/**
* This class models an email message. This is an abstract class.
* Subclasses provide actual implementations. <p>
*
* Message implements the Part interface. Message contains a set of
* attributes and a "content". Messages within a folder also have a
* set of flags that describe its state within the folder.<p>
*
* Message defines some new attributes in addition to those defined
* in the <code>Part</code> interface. These attributes specify meta-data
* for the message - i.e., addressing and descriptive information about
* the message. <p>
*
* Message objects are obtained either from a Folder or by constructing
* a new Message object of the appropriate subclass. Messages that have
* been received are normally retrieved from a folder named "INBOX". <p>
*
* A Message object obtained from a folder is just a lightweight
* reference to the actual message. The Message is 'lazily' filled
* up (on demand) when each item is requested from the message. Note
* that certain folder implementations may return Message objects that
* are pre-filled with certain user-specified items.
* To send a message, an appropriate subclass of Message (e.g.,
* MimeMessage) is instantiated, the attributes and content are
* filled in, and the message is sent using the <code>Transport.send</code>
* method. <p>
*
* @author John Mani
* @author Bill Shannon
* @author Max Spivak
* @see javax.mail.Part
*/
public abstract class Message implements Part {
/**
* The number of this message within its folder, or zero if
* the message was not retrieved from a folder.
*/
protected int msgnum = 0;
/**
* True if this message has been expunged.
*/
protected boolean expunged = false;
/**
* The containing folder, if this message is obtained from a folder
*/
protected Folder folder = null;
/**
* The Session object for this Message
*/
protected Session session = null;
/**
* No-arg version of the constructor.
*/
protected Message() { }
/**
* Constructor that takes a Folder and a message number.
* Used by Folder implementations.
*
* @param folder containing folder
* @param msgnum this message's sequence number within this folder
*/
protected Message(Folder folder, int msgnum) {
this.folder = folder;
this.msgnum = msgnum;
session = folder.store.session;
}
/**
* Constructor that takes a Session. Used for client created
* Message objects.
*
* @param session A Session object
*/
protected Message(Session session) {
this.session = session;
}
/**
* Return the Session used when this message was created.
*
* @return the message's Session
* @since JavaMail 1.5
*/
public Session getSession() {
return session;
}
/**
* Returns the "From" attribute. The "From" attribute contains
* the identity of the person(s) who wished this message to
* be sent. <p>
*
* In certain implementations, this may be different
* from the entity that actually sent the message. <p>
*
* This method returns <code>null</code> if this attribute
* is not present in this message. Returns an empty array if
* this attribute is present, but contains no addresses.
*
* @return array of Address objects
* @exception MessagingException
*/
public abstract Address[] getFrom() throws MessagingException;
/**
* Set the "From" attribute in this Message. The value of this
* attribute is obtained from the property "mail.user". If this
* property is absent, the system property "user.name" is used.
*
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public abstract void setFrom() throws MessagingException;
/**
* Set the "From" attribute in this Message.
*
* @param address the sender
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public abstract void setFrom(Address address)
throws MessagingException;
/**
* Add these addresses to the existing "From" attribute
*
* @param addresses the senders
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
* @exception MessagingException
*/
public abstract void addFrom(Address[] addresses)
throws MessagingException;
/**
* This inner class defines the types of recipients allowed by
* the Message class. The currently defined types are TO,
* CC and BCC.
*
* Note that this class only has a protected constructor, thereby
* restricting new Recipient types to either this class or subclasses.
* This effectively implements an enumeration of the allowed Recipient
* types.
*
* The following code sample shows how to use this class to obtain
* the "TO" recipients from a message.
* <blockquote><pre>
*
* Message msg = folder.getMessages(1);
* Address[] a = m.getRecipients(Message.RecipientType.TO);
*
* </pre></blockquote><p>
*
* @see javax.mail.Message#getRecipients
* @see javax.mail.Message#setRecipients
* @see javax.mail.Message#addRecipients
*/
public static class RecipientType implements Serializable {
/**
* The "To" (primary) recipients.
*/
public static final RecipientType TO = new RecipientType("To");
/**
* The "Cc" (carbon copy) recipients.
*/
public static final RecipientType CC = new RecipientType("Cc");
/**
* The "Bcc" (blind carbon copy) recipients.
*/
public static final RecipientType BCC = new RecipientType("Bcc");
/**
* The type of recipient, usually the name of a corresponding
* Internet standard header.
*
* @serial
*/
protected String type;
private static final long serialVersionUID = -7479791750606340008L;
/**
* Constructor for use by subclasses.
*/
protected RecipientType(String type) {
this.type = type;
}
/**
* When deserializing a RecipientType, we need to make sure to
* return only one of the known static final instances defined
* in this class. Subclasses must implement their own
* <code>readResolve</code> method that checks for their known
* instances before calling this super method.
*/
protected Object readResolve() throws ObjectStreamException {
if (type.equals("To"))
return TO;
else if (type.equals("Cc"))
return CC;
else if (type.equals("Bcc"))
return BCC;
else
throw new InvalidObjectException(
"Attempt to resolve unknown RecipientType: " + type);
}
public String toString() {
return type;
}
}
/**
* Get all the recipient addresses of the given type. <p>
*
* This method returns <code>null</code> if no recipients of
* the given type are present in this message. It may return an
* empty array if the header is present, but contains no addresses.
*
* @param type the recipient type
* @return array of Address objects
* @exception MessagingException
* @see Message.RecipientType#TO
* @see Message.RecipientType#CC
* @see Message.RecipientType#BCC
*/
public abstract Address[] getRecipients(RecipientType type)
throws MessagingException;
/**
* Get all the recipient addresses for the message.
* The default implementation extracts the TO, CC, and BCC
* recipients using the <code>getRecipients</code> method. <p>
*
* This method returns <code>null</code> if none of the recipient
* headers are present in this message. It may Return an empty array
* if any recipient header is present, but contains no addresses.
*
* @return array of Address objects
* @exception MessagingException
* @see Message.RecipientType#TO
* @see Message.RecipientType#CC
* @see Message.RecipientType#BCC
* @see #getRecipients
*/
public Address[] getAllRecipients() throws MessagingException {
Address[] to = getRecipients(RecipientType.TO);
Address[] cc = getRecipients(RecipientType.CC);
Address[] bcc = getRecipients(RecipientType.BCC);
if (cc == null && bcc == null)
return to; // a common case
int numRecip =
(to != null ? to.length : 0) +
(cc != null ? cc.length : 0) +
(bcc != null ? bcc.length : 0);
Address[] addresses = new Address[numRecip];
int pos = 0;
if (to != null) {
System.arraycopy(to, 0, addresses, pos, to.length);
pos += to.length;
}
if (cc != null) {
System.arraycopy(cc, 0, addresses, pos, cc.length);
pos += cc.length;
}
if (bcc != null) {
System.arraycopy(bcc, 0, addresses, pos, bcc.length);
pos += bcc.length;
}
return addresses;
}
/**
* Set the recipient addresses. All addresses of the specified
* type are replaced by the addresses parameter.
*
* @param type the recipient type
* @param addresses the addresses
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public abstract void setRecipients(RecipientType type, Address[] addresses)
throws MessagingException;
/**
* Set the recipient address. All addresses of the specified
* type are replaced by the address parameter. <p>
*
* The default implementation uses the <code>setRecipients</code> method.
*
* @param type the recipient type
* @param address the address
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
*/
public void setRecipient(RecipientType type, Address address)
throws MessagingException {
Address[] a = new Address[1];
a[0] = address;
setRecipients(type, a);
}
/**
* Add these recipient addresses to the existing ones of the given type.
*
* @param type the recipient type
* @param addresses the addresses
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public abstract void addRecipients(RecipientType type, Address[] addresses)
throws MessagingException;
/**
* Add this recipient address to the existing ones of the given type. <p>
*
* The default implementation uses the <code>addRecipients</code> method.
*
* @param type the recipient type
* @param address the address
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
*/
public void addRecipient(RecipientType type, Address address)
throws MessagingException {
Address[] a = new Address[1];
a[0] = address;
addRecipients(type, a);
}
/**
* Get the addresses to which replies should be directed.
* This will usually be the sender of the message, but
* some messages may direct replies to a different address. <p>
*
* The default implementation simply calls the <code>getFrom</code>
* method. <p>
*
* This method returns <code>null</code> if the corresponding
* header is not present. Returns an empty array if the header
* is present, but contains no addresses.
*
* @return addresses to which replies should be directed
* @exception MessagingException
* @see #getFrom
*/
public Address[] getReplyTo() throws MessagingException {
return getFrom();
}
/**
* Set the addresses to which replies should be directed.
* (Normally only a single address will be specified.)
* Not all message types allow this to be specified separately
* from the sender of the message. <p>
*
* The default implementation provided here just throws the
* MethodNotSupportedException.
*
* @param addresses addresses to which replies should be directed
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
* @exception MethodNotSupportedException if the underlying
* implementation does not support setting this
* attribute
*/
public void setReplyTo(Address[] addresses) throws MessagingException {
throw new MethodNotSupportedException("setReplyTo not supported");
}
/**
* Get the subject of this message.
*
* @return the subject
* @exception MessagingException
*/
public abstract String getSubject() throws MessagingException;
/**
* Set the subject of this message.
*
* @param subject the subject
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public abstract void setSubject(String subject)
throws MessagingException;
/**
* Get the date this message was sent.
*
* @return the date this message was sent
* @exception MessagingException
*/
public abstract Date getSentDate() throws MessagingException;
/**
* Set the sent date of this message.
*
* @param date the sent date of this message
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
*/
public abstract void setSentDate(Date date) throws MessagingException;
/**
* Get the date this message was received.
*
* @return the date this message was received
* @exception MessagingException
*/
public abstract Date getReceivedDate() throws MessagingException;
/**
* Returns a <code>Flags</code> object containing the flags for
* this message. <p>
*
* Modifying any of the flags in this returned Flags object will
* not affect the flags of this message. Use <code>setFlags()</code>
* to do that. <p>
*
* @return Flags object containing the flags for this message
* @see javax.mail.Flags
* @see #setFlags
* @exception MessagingException
*/
public abstract Flags getFlags() throws MessagingException;
/**
* Check whether the flag specified in the <code>flag</code>
* argument is set in this message. <p>
*
* The default implementation uses <code>getFlags</code>.
*
* @param flag the flag
* @return value of the specified flag for this message
* @see javax.mail.Flags.Flag
* @see javax.mail.Flags.Flag#ANSWERED
* @see javax.mail.Flags.Flag#DELETED
* @see javax.mail.Flags.Flag#DRAFT
* @see javax.mail.Flags.Flag#FLAGGED
* @see javax.mail.Flags.Flag#RECENT
* @see javax.mail.Flags.Flag#SEEN
* @exception MessagingException
*/
public boolean isSet(Flags.Flag flag) throws MessagingException {
return getFlags().contains(flag);
}
/**
* Set the specified flags on this message to the specified value.
* Note that any flags in this message that are not specified in
* the given <code>Flags</code> object are unaffected. <p>
*
* This will result in a <code>MessageChangedEvent</code> being
* delivered to any MessageChangedListener registered on this
* Message's containing folder.
*
* @param flag Flags object containing the flags to be set
* @param set the value to be set
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values.
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
* @see javax.mail.event.MessageChangedEvent
*/
public abstract void setFlags(Flags flag, boolean set)
throws MessagingException;
/**
* Set the specified flag on this message to the specified value.
*
* This will result in a <code>MessageChangedEvent</code> being
* delivered to any MessageChangedListener registered on this
* Message's containing folder. <p>
*
* The default implementation uses the <code>setFlags</code> method.
*
* @param flag Flags.Flag object containing the flag to be set
* @param set the value to be set
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values.
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
* @see javax.mail.event.MessageChangedEvent
*/
public void setFlag(Flags.Flag flag, boolean set)
throws MessagingException {
Flags f = new Flags(flag);
setFlags(f, set);
}
/**
* Get the Message number for this Message.
* A Message object's message number is the relative
* position of this Message in its Folder. Note that the message
* number for a particular Message can change during a session
* if other messages in the Folder are deleted and expunged. <p>
*
* Valid message numbers start at 1. Messages that do not belong
* to any folder (like newly composed or derived messages) have 0
* as their message number.
*
* @return the message number
*/
public int getMessageNumber() {
return msgnum;
}
/**
* Set the Message number for this Message. This method is
* invoked only by the implementation classes.
*/
protected void setMessageNumber(int msgnum) {
this.msgnum = msgnum;
}
/**
* Get the folder from which this message was obtained. If
* this is a new message or nested message, this method returns
* null.
*
* @return the containing folder
*/
public Folder getFolder() {
return folder;
}
/**
* Checks whether this message is expunged. All other methods except
* <code>getMessageNumber()</code> are invalid on an expunged
* Message object. <p>
*
* Messages that are expunged due to an explict <code>expunge()</code>
* request on the containing Folder are removed from the Folder
* immediately. Messages that are externally expunged by another source
* are marked "expunged" and return true for the isExpunged() method,
* but they are not removed from the Folder until an explicit
* <code>expunge()</code> is done on the Folder. <p>
*
* See the description of <code>expunge()</code> for more details on
* expunge handling.
*
* @see Folder#expunge
*/
public boolean isExpunged() {
return expunged;
}
/**
* Sets the expunged flag for this Message. This method is to
* be used only by the implementation classes.
*
* @param expunged the expunged flag
*/
protected void setExpunged(boolean expunged) {
this.expunged = expunged;
}
/**
* Get a new Message suitable for a reply to this message.
* The new Message will have its attributes and headers
* set up appropriately. Note that this new message object
* will be empty, that is, it will <strong>not</strong> have a "content".
* These will have to be suitably filled in by the client. <p>
*
* If <code>replyToAll</code> is set, the new Message will be addressed
* to all recipients of this message. Otherwise, the reply will be
* addressed to only the sender of this message (using the value
* of the <code>getReplyTo</code> method). <p>
*
* The "Subject" field is filled in with the original subject
* prefixed with "Re:" (unless it already starts with "Re:"). <p>
*
* The reply message will use the same session as this message.
*
* @param replyToAll reply should be sent to all recipients
* of this message
* @return the reply Message
* @exception MessagingException
*/
public abstract Message reply(boolean replyToAll) throws MessagingException;
/**
* Save any changes made to this message into the message-store
* when the containing folder is closed, if the message is contained
* in a folder. (Some implementations may save the changes
* immediately.) Update any header fields to be consistent with the
* changed message contents. If any part of a message's headers or
* contents are changed, saveChanges must be called to ensure that
* those changes are permanent. If saveChanges is not called, any
* such modifications may or may not be saved, depending on the
* message store and folder implementation. <p>
*
* Messages obtained from folders opened READ_ONLY should not be
* modified and saveChanges should not be called on such messages.
*
* @exception MessagingException
* @exception IllegalStateException if this message is
* obtained from a READ_ONLY folder.
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values.
*/
public abstract void saveChanges() throws MessagingException;
/**
* Apply the specified Search criterion to this message.
*
* @param term the Search criterion
* @return true if the Message matches this search
* criterion, false otherwise.
* @exception MessagingException
* @see javax.mail.search.SearchTerm
*/
public boolean match(SearchTerm term) throws MessagingException {
return term.match(this);
}
}
@@ -0,0 +1,58 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* 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
* @since JavaMail 1.1
*/
public interface MessageAware {
/**
* Return the message context.
*/
public MessageContext getMessageContext();
}
@@ -0,0 +1,122 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* 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
* @since JavaMail 1.1
*/
public class MessageContext {
private Part part;
/**
* Create a MessageContext object describing the context of the given Part.
*/
public MessageContext(Part part) {
this.part = part;
}
/**
* Return the Part that contains the content.
*
* @return the containing Part, or null if not known
*/
public Part getPart() {
return part;
}
/**
* 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() {
try {
return getMessage(part);
} catch (MessagingException ex) {
return null;
}
}
/**
* Return the Message containing an arbitrary Part.
* 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 none
* @see javax.mail.BodyPart#getParent
* @see javax.mail.Multipart#getParent
*/
private static Message getMessage(Part p) throws MessagingException {
while (p != null) {
if (p instanceof Message)
return (Message)p;
BodyPart bp = (BodyPart)p;
Multipart mp = bp.getParent();
if (mp == null) // MimeBodyPart might not be in a MimeMultipart
return null;
p = mp.getParent();
}
return null;
}
/**
* Return the Session we're operating in.
*
* @return the Session, or null if not known
*/
public Session getSession() {
Message msg = getMessage();
return msg != null ? msg.getSession() : null;
}
}
@@ -0,0 +1,86 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* The exception thrown when an invalid method is invoked on an expunged
* Message. The only valid methods on an expunged Message are
* <code>isExpunged()</code> and <code>getMessageNumber()</code>.
*
* @see javax.mail.Message#isExpunged()
* @see javax.mail.Message#getMessageNumber()
* @author John Mani
*/
public class MessageRemovedException extends MessagingException {
private static final long serialVersionUID = 1951292550679528690L;
/**
* Constructs a MessageRemovedException with no detail message.
*/
public MessageRemovedException() {
super();
}
/**
* Constructs a MessageRemovedException with the specified
* detail message.
*
* @param s The detailed error message
*/
public MessageRemovedException(String s) {
super(s);
}
/**
* Constructs a MessageRemovedException with the specified
* detail message and embedded exception. The exception is chained
* to this exception.
*
* @param s The detailed error message
* @param e The embedded exception
* @since JavaMail 1.5
*/
public MessageRemovedException(String s, Exception e) {
super(s, e);
}
}
@@ -0,0 +1,174 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.lang.*;
/**
* The base class for all exceptions thrown by the Messaging classes
*
* @author John Mani
* @author Bill Shannon
*/
public class MessagingException extends Exception {
/**
* The next exception in the chain.
*
* @serial
*/
private Exception next;
private static final long serialVersionUID = -7569192289819959253L;
/**
* Constructs a MessagingException with no detail message.
*/
public MessagingException() {
super();
initCause(null); // prevent anyone else from setting it
}
/**
* Constructs a MessagingException with the specified detail message.
*
* @param s the detail message
*/
public MessagingException(String s) {
super(s);
initCause(null); // prevent anyone else from setting it
}
/**
* Constructs a MessagingException with the specified
* Exception and detail message. The specified exception is chained
* to this exception.
*
* @param s the detail message
* @param e the embedded exception
* @see #getNextException
* @see #setNextException
* @see #getCause
*/
public MessagingException(String s, Exception e) {
super(s);
next = e;
initCause(null); // prevent anyone else from setting it
}
/**
* Get the next exception chained to this one. If the
* next exception is a MessagingException, the chain
* may extend further.
*
* @return next Exception, null if none.
*/
public synchronized Exception getNextException() {
return next;
}
/**
* Overrides the <code>getCause</code> method of <code>Throwable</code>
* to return the next exception in the chain of nested exceptions.
*
* @return next Exception, null if none.
*/
public synchronized Throwable getCause() {
return next;
}
/**
* Add an exception to the end of the chain. If the end
* is <strong>not</strong> a MessagingException, this
* exception cannot be added to the end.
*
* @param ex the new end of the Exception chain
* @return <code>true</code> if this Exception
* was added, <code>false</code> otherwise.
*/
public synchronized boolean setNextException(Exception ex) {
Exception theEnd = this;
while (theEnd instanceof MessagingException &&
((MessagingException)theEnd).next != null) {
theEnd = ((MessagingException)theEnd).next;
}
// If the end is a MessagingException, we can add this
// exception to the chain.
if (theEnd instanceof MessagingException) {
((MessagingException)theEnd).next = ex;
return true;
} else
return false;
}
/**
* Override toString method to provide information on
* nested exceptions.
*/
public synchronized String toString() {
String s = super.toString();
Exception n = next;
if (n == null)
return s;
StringBuffer sb = new StringBuffer(s == null ? "" : s);
while (n != null) {
sb.append(";\n nested exception is:\n\t");
if (n instanceof MessagingException) {
MessagingException mex = (MessagingException)n;
sb.append(mex.superToString());
n = mex.next;
} else {
sb.append(n.toString());
n = null;
}
}
return sb.toString();
}
/**
* Return the "toString" information for this exception,
* without any information on nested exceptions.
*/
private final String superToString() {
return super.toString();
}
}
@@ -0,0 +1,84 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* The exception thrown when a method is not supported by the
* implementation
*
* @author John Mani
*/
public class MethodNotSupportedException extends MessagingException {
private static final long serialVersionUID = -3757386618726131322L;
/**
* Constructs a MethodNotSupportedException with no detail message.
*/
public MethodNotSupportedException() {
super();
}
/**
* Constructs a MethodNotSupportedException with the specified
* detail message.
*
* @param s The detailed error message
*/
public MethodNotSupportedException(String s) {
super(s);
}
/**
* Constructs a MethodNotSupportedException with the specified
* detail message and embedded exception. The exception is chained
* to this exception.
*
* @param s The detailed error message
* @param e The embedded exception
* @since JavaMail 1.5
*/
public MethodNotSupportedException(String s, Exception e) {
super(s, e);
}
}
+277
View File
@@ -0,0 +1,277 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.util.Vector;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import javax.activation.DataSource;
/**
* Multipart is a container that holds multiple body parts. Multipart
* provides methods to retrieve and set its subparts. <p>
*
* Multipart also acts as the base class for the content object returned
* by most Multipart DataContentHandlers. For example, invoking getContent()
* on a DataHandler whose source is a "multipart/signed" data source may
* return an appropriate subclass of Multipart. <p>
*
* Some messaging systems provide different subtypes of Multiparts. For
* example, MIME specifies a set of subtypes that include "alternative",
* "mixed", "related", "parallel", "signed", etc. <p>
*
* Multipart is an abstract class. Subclasses provide actual implementations.
*
* @author John Mani
*/
public abstract class Multipart {
/**
* Vector of BodyPart objects.
*/
protected Vector parts = new Vector(); // Holds BodyParts
/**
* This field specifies the content-type of this multipart
* object. It defaults to "multipart/mixed".
*/
protected String contentType = "multipart/mixed"; // Content-Type
/**
* The <code>Part</code> containing this <code>Multipart</code>,
* if known.
* @since JavaMail 1.1
*/
protected Part parent;
/**
* Default constructor. An empty Multipart object is created.
*/
protected Multipart() { }
/**
* Setup this Multipart object from the given MultipartDataSource. <p>
*
* The method adds the MultipartDataSource's BodyPart
* objects into this Multipart. This Multipart's contentType is
* set to that of the MultipartDataSource. <p>
*
* This method is typically used in those cases where one
* has a multipart data source that has already been pre-parsed into
* the individual body parts (for example, an IMAP datasource), but
* needs to create an appropriate Multipart subclass that represents
* a specific multipart subtype.
*
* @param mp Multipart datasource
*/
protected synchronized void setMultipartDataSource(MultipartDataSource mp)
throws MessagingException {
contentType = mp.getContentType();
int count = mp.getCount();
for (int i = 0; i < count; i++)
addBodyPart(mp.getBodyPart(i));
}
/**
* Return the content-type of this Multipart. <p>
*
* This implementation just returns the value of the
* <code>contentType</code> field.
*
* @return content-type
* @see #contentType
*/
public synchronized String getContentType() {
return contentType;
}
/**
* Return the number of enclosed BodyPart objects. <p>
*
* @return number of parts
* @see #parts
*/
public synchronized int getCount() throws MessagingException {
if (parts == null)
return 0;
return parts.size();
}
/**
* Get the specified Part. Parts are numbered starting at 0.
*
* @param index the index of the desired Part
* @return the Part
* @exception IndexOutOfBoundsException if the given index
* is out of range.
* @exception MessagingException
*/
public synchronized BodyPart getBodyPart(int index)
throws MessagingException {
if (parts == null)
throw new IndexOutOfBoundsException("No such BodyPart");
return (BodyPart)parts.elementAt(index);
}
/**
* Remove the specified part from the multipart message.
* Shifts all the parts after the removed part down one.
*
* @param part The part to remove
* @return true if part removed, false otherwise
* @exception MessagingException if no such Part exists
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
*/
public synchronized boolean removeBodyPart(BodyPart part)
throws MessagingException {
if (parts == null)
throw new MessagingException("No such body part");
boolean ret = parts.removeElement(part);
part.setParent(null);
return ret;
}
/**
* Remove the part at specified location (starting from 0).
* Shifts all the parts after the removed part down one.
*
* @param index Index of the part to remove
* @exception MessagingException
* @exception IndexOutOfBoundsException if the given index
* is out of range.
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
*/
public synchronized void removeBodyPart(int index)
throws MessagingException {
if (parts == null)
throw new IndexOutOfBoundsException("No such BodyPart");
BodyPart part = (BodyPart)parts.elementAt(index);
parts.removeElementAt(index);
part.setParent(null);
}
/**
* Adds a Part to the multipart. The BodyPart is appended to
* the list of existing Parts.
*
* @param part The Part to be appended
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
*/
public synchronized void addBodyPart(BodyPart part)
throws MessagingException {
if (parts == null)
parts = new Vector();
parts.addElement(part);
part.setParent(this);
}
/**
* Adds a BodyPart at position <code>index</code>.
* If <code>index</code> is not the last one in the list,
* the subsequent parts are shifted up. If <code>index</code>
* is larger than the number of parts present, the
* BodyPart is appended to the end.
*
* @param part The BodyPart to be inserted
* @param index Location where to insert the part
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
*/
public synchronized void addBodyPart(BodyPart part, int index)
throws MessagingException {
if (parts == null)
parts = new Vector();
parts.insertElementAt(part, index);
part.setParent(this);
}
/**
* Output an appropriately encoded bytestream to the given
* OutputStream. The implementation subclass decides the
* appropriate encoding algorithm to be used. The bytestream
* is typically used for sending.
*
* @exception IOException if an IO related exception occurs
* @exception MessagingException
*/
public abstract void writeTo(OutputStream os)
throws IOException, MessagingException;
/**
* Return the <code>Part</code> that contains this <code>Multipart</code>
* object, or <code>null</code> if not known.
* @since JavaMail 1.1
*/
public synchronized Part getParent() {
return parent;
}
/**
* 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.
* <code>parent</code> may be <code>null</code> if the
* <code>Multipart</code> is being removed from its containing
* <code>Part</code>.
* @since JavaMail 1.1
*/
public synchronized void setParent(Part parent) {
this.parent = parent;
}
}
@@ -0,0 +1,86 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.util.Vector;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import javax.activation.DataSource;
/**
* MultipartDataSource is a <code>DataSource</code> that contains body
* parts. This allows "mail aware" <code>DataContentHandlers</code> to
* be implemented more efficiently by being aware of such
* <code>DataSources</code> and using the appropriate methods to access
* <code>BodyParts</code>. <p>
*
* Note that the data of a MultipartDataSource is also available as
* an input stream. <p>
*
* This interface will typically be implemented by providers that
* preparse multipart bodies, for example an IMAP provider.
*
* @author John Mani
* @see javax.activation.DataSource
*/
public interface MultipartDataSource extends DataSource {
/**
* Return the number of enclosed BodyPart objects.
*
* @return number of parts
*/
public int getCount();
/**
* Get the specified Part. Parts are numbered starting at 0.
*
* @param index the index of the desired Part
* @return the Part
* @exception IndexOutOfBoundsException if the given index
* is out of range.
* @exception MessagingException
*/
public BodyPart getBodyPart(int index) throws MessagingException;
}
@@ -0,0 +1,83 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* This exception is thrown when Session attempts to instantiate a
* Provider that doesn't exist.
*
* @author Max Spivak
*/
public class NoSuchProviderException extends MessagingException {
private static final long serialVersionUID = 8058319293154708827L;
/**
* Constructs a NoSuchProviderException with no detail message.
*/
public NoSuchProviderException() {
super();
}
/**
* Constructs a NoSuchProviderException with the specified
* detail message.
*
* @param message The detailed error message
*/
public NoSuchProviderException(String message) {
super(message);
}
/**
* Constructs a NoSuchProviderException with the specified
* detail message and embedded exception. The exception is chained
* to this exception.
*
* @param message The detailed error message
* @param e The embedded exception
* @since JavaMail 1.5
*/
public NoSuchProviderException(String message, Exception e) {
super(message, e);
}
}
+463
View File
@@ -0,0 +1,463 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.io.*;
import java.util.Enumeration;
import javax.activation.DataHandler;
/**
* The <code>Part</code> interface is the common base interface for
* Messages and BodyParts. <p>
*
* Part consists of a set of attributes and a "Content".<p>
*
* <strong> Attributes: </strong> <p>
*
* The JavaMail API defines a set of standard Part attributes that are
* considered to be common to most existing Mail systems. These
* attributes have their own settor and gettor methods. Mail systems
* may support other Part attributes as well, these are represented as
* name-value pairs where both the name and value are Strings.<p>
*
* <strong> Content: </strong> <p>
*
* The <strong>data type</strong> of the "content" is returned by
* the <code>getContentType()</code> method. The MIME typing system
* is used to name data types. <p>
*
* The "content" of a Part is available in various formats:
* <ul>
* <li> As a DataHandler - using the <code>getDataHandler()</code> method.
* The "content" of a Part is also available through a
* <code>javax.activation.DataHandler</code> object. The DataHandler
* object allows clients to discover the operations available on the
* content, and to instantiate the appropriate component to perform
* those operations.
*
* <li> As an input stream - using the <code>getInputStream()</code> method.
* Any mail-specific encodings are decoded before this stream is returned.
*
* <li> As a Java object - using the <code>getContent()</code> method.
* This method returns the "content" as a Java object.
* The returned object is of course dependent on the content
* itself. In particular, a "multipart" Part's content is always a
* Multipart or subclass thereof. That is, <code>getContent()</code> on a
* "multipart" type Part will always return a Multipart (or subclass) object.
* </ul>
*
* Part provides the <code>writeTo()</code> method that streams
* out its bytestream in mail-safe form suitable for transmission.
* This bytestream is typically an aggregation of the Part attributes
* and its content's bytestream. <p>
*
* Message and BodyPart implement the Part interface. Note that in
* MIME parlance, Part models an Entity (RFC 2045, Section 2.4).
*
* @author John Mani
*/
public interface Part {
/**
* Return the size of the content of this part in bytes.
* Return -1 if the size cannot be determined. <p>
*
* Note that the size may not be an exact measure of the content
* size and may or may not account for any transfer encoding
* of the content. The size is appropriate for display in a
* user interface to give the user a rough idea of the size
* of this part.
*
* @return size of content in bytes
* @exception MessagingException
*/
public int getSize() throws MessagingException;
/**
* Return the number of lines in the content of this part.
* Return -1 if the number cannot be determined.
*
* Note that this number may not be an exact measure of the
* content length and may or may not account for any transfer
* encoding of the content.
*
* @return number of lines in the content.
* @exception MessagingException
*/
public int getLineCount() throws MessagingException;
/**
* Returns the Content-Type of the content of this part.
* Returns null if the Content-Type could not be determined. <p>
*
* The MIME typing system is used to name Content-types.
*
* @return The ContentType of this part
* @exception MessagingException
* @see javax.activation.DataHandler
*/
public String getContentType() throws MessagingException;
/**
* Is this Part of the specified MIME type? This method
* compares <strong>only the <code>primaryType</code> and
* <code>subType</code></strong>.
* The parameters of the content types are ignored. <p>
*
* For example, this method will return <code>true</code> when
* comparing a Part of content type <strong>"text/plain"</strong>
* with <strong>"text/plain; charset=foobar"</strong>. <p>
*
* If the <code>subType</code> of <code>mimeType</code> is the
* special character '*', then the subtype is ignored during the
* comparison.
*/
public boolean isMimeType(String mimeType) throws MessagingException;
/**
* This part should be presented as an attachment.
* @see #getDisposition
* @see #setDisposition
*/
public static final String ATTACHMENT = "attachment";
/**
* This part should be presented inline.
* @see #getDisposition
* @see #setDisposition
*/
public static final String INLINE = "inline";
/**
* Return the disposition of this part. The disposition
* describes how the part should be presented to the user.
* (See RFC 2183.) The return value should be considered
* without regard to case. For example: <p>
* <blockquote><pre>
* String disp = part.getDisposition();
* if (disp == null || disp.equalsIgnoreCase(Part.ATTACHMENT))
* // treat as attachment if not first part
* </pre></blockquote>
*
* @return disposition of this part, or null if unknown
* @exception MessagingException
* @see #ATTACHMENT
* @see #INLINE
* @see #getFileName
*/
public String getDisposition() throws MessagingException;
/**
* Set the disposition of this part.
*
* @param disposition disposition of this part
* @exception MessagingException
* @exception IllegalWriteException if the underlying implementation
* does not support modification of this header
* @exception IllegalStateException if this Part is obtained
* from a READ_ONLY folder
* @see #ATTACHMENT
* @see #INLINE
* @see #setFileName
*/
public void setDisposition(String disposition) throws MessagingException;
/**
* Return a description String for this part. This typically
* associates some descriptive information with this part.
* Returns null if none is available.
*
* @return description of this part
* @exception MessagingException
*/
public String getDescription() throws MessagingException;
/**
* Set a description String for this part. This typically
* associates some descriptive information with this part.
*
* @param description description of this part
* @exception MessagingException
* @exception IllegalWriteException if the underlying implementation
* does not support modification of this header
* @exception IllegalStateException if this Part is obtained
* from a READ_ONLY folder
*/
public void setDescription(String description) throws MessagingException;
/**
* Get the filename associated with this part, if possible.
* Useful if this part represents an "attachment" that was
* loaded from a file. The filename will usually be a simple
* name, not including directory components.
*
* @return Filename to associate with this part
*/
public String getFileName() throws MessagingException;
/**
* Set the filename associated with this part, if possible.
* Useful if this part represents an "attachment" that was
* loaded from a file. The filename will usually be a simple
* name, not including directory components.
*
* @param filename Filename to associate with this part
* @exception IllegalWriteException if the underlying implementation
* does not support modification of this header
* @exception IllegalStateException if this Part is obtained
* from a READ_ONLY folder
*/
public void setFileName(String filename) throws MessagingException;
/**
* Return an input stream for this part's "content". Any
* mail-specific transfer encodings will be decoded before the
* input stream is provided. <p>
*
* This is typically a convenience method that just invokes
* the DataHandler's <code>getInputStream()</code> method.
*
* @return an InputStream
* @exception IOException this is typically thrown by the
* DataHandler. Refer to the documentation for
* javax.activation.DataHandler for more details.
* @exception MessagingException
* @see #getDataHandler
* @see javax.activation.DataHandler#getInputStream
*/
public InputStream getInputStream()
throws IOException, MessagingException;
/**
* Return a DataHandler for the content within this part. The
* DataHandler allows clients to operate on as well as retrieve
* the content.
*
* @return DataHandler for the content
* @exception MessagingException
*/
public DataHandler getDataHandler() throws MessagingException;
/**
* Return the content as a Java object. The type of the returned
* object is of course dependent on the content itself. For example,
* the object returned for "text/plain" content is usually a String
* object. The object returned for a "multipart" content is always a
* Multipart subclass. For content-types that are unknown to the
* DataHandler system, an input stream is returned as the content <p>
*
* This is a convenience method that just invokes the DataHandler's
* getContent() method
*
* @return Object
* @exception MessagingException
* @exception IOException this is typically thrown by the
* DataHandler. Refer to the documentation for
* javax.activation.DataHandler for more details.
*
* @see javax.activation.DataHandler#getContent
*/
public Object getContent() throws IOException, MessagingException;
/**
* This method provides the mechanism to set this part's content.
* The DataHandler wraps around the actual content.
*
* @param dh The DataHandler for the content.
* @exception MessagingException
* @exception IllegalWriteException if the underlying implementation
* does not support modification of existing values
* @exception IllegalStateException if this Part is obtained
* from a READ_ONLY folder
*/
public void setDataHandler(DataHandler dh) throws MessagingException;
/**
* A convenience method for setting this part's content. The part
* internally wraps the content in a DataHandler. <p>
*
* Note that a DataContentHandler class for the specified type should
* be available to the JavaMail implementation for this to work right.
* i.e., to do <code>setContent(foobar, "application/x-foobar")</code>,
* a DataContentHandler for "application/x-foobar" should be installed.
* Refer to the Java Activation Framework for more information.
*
* @param obj A java object.
* @param type MIME type of this object.
* @exception IllegalWriteException if the underlying implementation
* does not support modification of existing values
* @exception IllegalStateException if this Part is obtained
* from a READ_ONLY folder
*/
public void setContent(Object obj, String type)
throws MessagingException;
/**
* A convenience method that sets the given String as this
* part's content with a MIME type of "text/plain".
*
* @param text The text that is the Message's content.
* @exception IllegalWriteException if the underlying
* implementation does not support modification of
* existing values
* @exception IllegalStateException if this Part is obtained
* from a READ_ONLY folder
*/
public void setText(String text) throws MessagingException;
/**
* This method sets the given Multipart object as this message's
* content.
*
* @param mp The multipart object that is the Message's content
* @exception IllegalWriteException if the underlying
* implementation does not support modification of
* existing values
* @exception IllegalStateException if this Part is obtained
* from a READ_ONLY folder
*/
public void setContent(Multipart mp) throws MessagingException;
/**
* Output a bytestream for this Part. This bytestream is
* typically an aggregration of the Part attributes and
* an appropriately encoded bytestream from its 'content'. <p>
*
* Classes that implement the Part interface decide on
* the appropriate encoding algorithm to be used. <p>
*
* The bytestream is typically used for sending.
*
* @exception IOException if an error occurs writing to the
* stream or if an error is generated
* by the javax.activation layer.
* @exception MessagingException if an error occurs fetching the
* data to be written
*
* @see javax.activation.DataHandler#writeTo
*/
public void writeTo(OutputStream os) throws IOException, MessagingException;
/**
* Get all the headers for this header name. Returns <code>null</code>
* if no headers for this header name are available.
*
* @param header_name the name of this header
* @return the value fields for all headers with
* this name
* @exception MessagingException
*/
public String[] getHeader(String header_name)
throws MessagingException;
/**
* Set the value for this header_name. Replaces all existing
* header values with this new value.
*
* @param header_name the name of this header
* @param header_value the value for this header
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this Part is
* obtained from a READ_ONLY folder
*/
public void setHeader(String header_name, String header_value)
throws MessagingException;
/**
* Add this value to the existing values for this header_name.
*
* @param header_name the name of this header
* @param header_value the value for this header
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this Part is
* obtained from a READ_ONLY folder
*/
public void addHeader(String header_name, String header_value)
throws MessagingException;
/**
* Remove all headers with this name.
*
* @param header_name the name of this header
* @exception MessagingException
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* of existing values
* @exception IllegalStateException if this Part is
* obtained from a READ_ONLY folder
*/
public void removeHeader(String header_name)
throws MessagingException;
/**
* Return all the headers from this part as an Enumeration of
* Header objects.
*
* @return enumeration of Header objects
* @exception MessagingException
*/
public Enumeration getAllHeaders() throws MessagingException;
/**
* Return matching headers from this part as an Enumeration of
* Header objects.
*
* @return enumeration of Header objects
* @exception MessagingException
*/
public Enumeration getMatchingHeaders(String[] header_names)
throws MessagingException;
/**
* Return non-matching headers from this envelope as an Enumeration
* of Header objects.
*
* @return enumeration of Header objects
* @exception MessagingException
*/
public Enumeration getNonMatchingHeaders(String[] header_names)
throws MessagingException;
}
@@ -0,0 +1,83 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* The class PasswordAuthentication is a data holder that is used by
* Authenticator. It is simply a repository for a user name and a password.
*
* @see java.net.PasswordAuthentication
* @see javax.mail.Authenticator
* @see javax.mail.Authenticator#getPasswordAuthentication()
*
* @author Bill Foote
*/
public final class PasswordAuthentication {
private final String userName;
private final String password;
/**
* Initialize a new PasswordAuthentication
* @param userName the user name
* @param password The user's password
*/
public PasswordAuthentication(String userName, String password) {
this.userName = userName;
this.password = password;
}
/**
* @return the user name
*/
public String getUserName() {
return userName;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
}
+139
View File
@@ -0,0 +1,139 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* The Provider is a class that describes a protocol
* implementation. The values typically come from the
* javamail.providers and javamail.default.providers
* resource files. An application may also create and
* register a Provider object to dynamically add support
* for a new provider.
*
* @author Max Spivak
* @author Bill Shannon
*/
public class Provider {
/**
* This inner class defines the Provider type.
* Currently, STORE and TRANSPORT are the only two provider types
* supported.
*/
public static class Type {
public static final Type STORE = new Type("STORE");
public static final Type TRANSPORT = new Type("TRANSPORT");
private String type;
private Type(String type) {
this.type = type;
}
public String toString() {
return type;
}
}
private Type type;
private String protocol, className, vendor, version;
/**
* Create a new provider of the specified type for the specified
* protocol. The specified class implements the provider.
*
* @param type Type.STORE or Type.TRANSPORT
* @param protocol valid protocol for the type
* @param classname class name that implements this protocol
* @param vendor optional string identifying the vendor (may be null)
* @param version optional implementation version string (may be null)
* @since JavaMail 1.4
*/
public Provider(Type type, String protocol, String classname,
String vendor, String version) {
this.type = type;
this.protocol = protocol;
this.className = classname;
this.vendor = vendor;
this.version = version;
}
/** Returns the type of this Provider */
public Type getType() {
return type;
}
/** Returns the protocol supported by this Provider */
public String getProtocol() {
return protocol;
}
/** Returns name of the class that implements the protocol */
public String getClassName() {
return className;
}
/** Returns name of vendor associated with this implementation or null */
public String getVendor() {
return vendor;
}
/** Returns version of this implementation or null if no version */
public String getVersion() {
return version;
}
/** Overrides Object.toString() */
public String toString() {
String s = "javax.mail.Provider[" + type + "," +
protocol + "," + className;
if (vendor != null)
s += "," + vendor;
if (version != null)
s += "," + version;
s += "]";
return s;
}
}
+129
View File
@@ -0,0 +1,129 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.util.Vector;
/**
* This class represents a set of quotas for a given quota root.
* Each quota root has a set of resources, represented by the
* <code>Quota.Resource</code> class. Each resource has a name
* (for example, "STORAGE"), a current usage, and a usage limit.
* See RFC 2087.
*
* @since JavaMail 1.4
* @author Bill Shannon
*/
public class Quota {
/**
* An individual resource in a quota root.
*
* @since JavaMail 1.4
*/
public static class Resource {
/** The name of the resource. */
public String name;
/** The current usage of the resource. */
public long usage;
/** The usage limit for the resource. */
public long limit;
/**
* Construct a Resource object with the given name,
* usage, and limit.
*
* @param name the resource name
* @param usage the current usage of the resource
* @param limit the usage limit for the resource
*/
public Resource(String name, long usage, long limit) {
this.name = name;
this.usage = usage;
this.limit = limit;
}
}
/**
* The name of the quota root.
*/
public String quotaRoot;
/**
* The set of resources associated with this quota root.
*/
public Quota.Resource[] resources;
/**
* Create a Quota object for the named quotaroot with no associated
* resources.
*
* @param quotaRoot the name of the quota root
*/
public Quota(String quotaRoot) {
this.quotaRoot = quotaRoot;
}
/**
* Set a resource limit for this quota root.
*
* @param name the name of the resource
* @param limit the resource limit
*/
public void setResourceLimit(String name, long limit) {
if (resources == null) {
resources = new Quota.Resource[1];
resources[0] = new Quota.Resource(name, 0, limit);
return;
}
for (int i = 0; i < resources.length; i++) {
if (resources[i].name.equalsIgnoreCase(name)) {
resources[i].limit = limit;
return;
}
}
Quota.Resource[] ra = new Quota.Resource[resources.length + 1];
System.arraycopy(resources, 0, ra, 0, resources.length);
ra[ra.length - 1] = new Quota.Resource(name, 0, limit);
resources = ra;
}
}
@@ -0,0 +1,81 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* An interface implemented by Stores that support quotas.
* The {@link #getQuota getQuota} and {@link #setQuota setQuota} methods
* support the quota model defined by the IMAP QUOTA extension.
* Refer to <A HREF="http://www.ietf.org/rfc/rfc2087.txt">RFC 2087</A>
* for more information. <p>
*
* @since JavaMail 1.4
*/
public interface QuotaAwareStore {
/**
* Get the quotas for the named folder.
* Quotas are controlled on the basis of a quota root, not
* (necessarily) a folder. The relationship between folders
* and quota roots depends on the server. Some servers
* might implement a single quota root for all folders owned by
* a user. Other servers might implement a separate quota root
* for each folder. A single folder can even have multiple
* quota roots, perhaps controlling quotas for different
* resources.
*
* @param folder the name of the folder
* @return array of Quota objects
* @exception MessagingException if the server doesn't support the
* QUOTA extension
*/
Quota[] getQuota(String folder) throws MessagingException;
/**
* Set the quotas for the quota root specified in the quota argument.
* Typically this will be one of the quota roots obtained from the
* <code>getQuota</code> method, but it need not be.
*
* @param quota the quota to set
* @exception MessagingException if the server doesn't support the
* QUOTA extension
*/
void setQuota(Quota quota) throws MessagingException;
}
@@ -0,0 +1,104 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* This exception is thrown when an attempt is made to open a folder
* read-write access when the folder is marked read-only. <p>
*
* The getMessage() method returns more detailed information about the
* error that caused this exception. <p>
*
* @author Jim Glennon
*/
public class ReadOnlyFolderException extends MessagingException {
transient private Folder folder;
private static final long serialVersionUID = 5711829372799039325L;
/**
* Constructs a ReadOnlyFolderException with the specified
* folder and no detail message.
*
* @param folder the Folder
* @since JavaMail 1.2
*/
public ReadOnlyFolderException(Folder folder) {
this(folder, null);
}
/**
* Constructs a ReadOnlyFolderException with the specified
* detail message.
*
* @param folder The Folder
* @param message The detailed error message
* @since JavaMail 1.2
*/
public ReadOnlyFolderException(Folder folder, String message) {
super(message);
this.folder = folder;
}
/**
* Constructs a ReadOnlyFolderException with the specified
* detail message and embedded exception. The exception is chained
* to this exception.
*
* @param folder The Folder
* @param message The detailed error message
* @param e The embedded exception
* @since JavaMail 1.5
*/
public ReadOnlyFolderException(Folder folder, String message, Exception e) {
super(message, e);
this.folder = folder;
}
/**
* Returns the dead Folder object.
* @since JavaMail 1.2
*/
public Folder getFolder() {
return folder;
}
}
@@ -0,0 +1,140 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* This exception is thrown when the message cannot be sent.<p>
*
* The exception includes those addresses to which the message could not be
* sent as well as the valid addresses to which the message was sent and
* valid addresses to which the message was not sent.
*
* @see javax.mail.Transport#send
* @see javax.mail.Transport#sendMessage
* @see javax.mail.event.TransportEvent
*
* @author John Mani
* @author Max Spivak
*/
public class SendFailedException extends MessagingException {
transient protected Address[] invalid;
transient protected Address[] validSent;
transient protected Address[] validUnsent;
private static final long serialVersionUID = -6457531621682372913L;
/**
* Constructs a SendFailedException with no detail message.
*/
public SendFailedException() {
super();
}
/**
* Constructs a SendFailedException with the specified detail message.
* @param s the detail message
*/
public SendFailedException(String s) {
super(s);
}
/**
* Constructs a SendFailedException with the specified
* Exception and detail message. The specified exception is chained
* to this exception.
* @param s the detail message
* @param e the embedded exception
* @see #getNextException
* @see #setNextException
*/
public SendFailedException(String s, Exception e) {
super(s, e);
}
/**
* Constructs a SendFailedException with the specified string
* and the specified address objects.
*
* @param msg the detail message
* @param ex the embedded exception
* @param validSent valid addresses to which message was sent
* @param validUnsent valid addresses to which message was not sent
* @param invalid the invalid addresses
* @see #getNextException
* @see #setNextException
*/
public SendFailedException(String msg, Exception ex, Address[] validSent,
Address[] validUnsent, Address[] invalid) {
super(msg, ex);
this.validSent = validSent;
this.validUnsent = validUnsent;
this.invalid = invalid;
}
/**
* Return the addresses to which this message was sent succesfully.
* @return Addresses to which the message was sent successfully or null
*/
public Address[] getValidSentAddresses() {
return validSent;
}
/**
* Return the addresses that are valid but to which this message
* was not sent.
* @return Addresses that are valid but to which the message was
* not sent successfully or null
*/
public Address[] getValidUnsentAddresses() {
return validUnsent;
}
/**
* Return the addresses to which this message could not be sent.
*
* @return Addresses to which the message sending failed or null;
*/
public Address[] getInvalidAddresses() {
return invalid;
}
}
+676
View File
@@ -0,0 +1,676 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.mail.event.*;
/**
* An abstract class that contains the functionality
* common to messaging services, such as stores and transports. <p>
* A messaging service is created from a <code>Session</code> and is
* named using a <code>URLName</code>. A service must be connected
* before it can be used. Connection events are sent to reflect
* its connection status.
*
* @author Christopher Cotton
* @author Bill Shannon
* @author Kanwar Oberoi
*/
public abstract class Service {
/**
* The session from which this service was created.
*/
protected Session session;
/**
* The <code>URLName</code> of this service.
*/
protected URLName url = null;
/**
* Debug flag for this service. Set from the session's debug
* flag when this service is created.
*/
protected boolean debug = false;
private boolean connected = false;
/*
* connectionListeners is a Vector, initialized here,
* because we depend on it always existing and depend
* on the synchronization that Vector provides.
* (Sychronizing on the Service object itself can cause
* deadlocks when notifying listeners.)
*/
private final Vector connectionListeners = new Vector();
/**
* Constructor.
*
* @param session Session object for this service
* @param urlname URLName object to be used for this service
*/
protected Service(Session session, URLName urlname) {
this.session = session;
debug = session.getDebug();
url = urlname;
/*
* Initialize the URLName with default values.
* The URLName will be updated when connect is called.
*/
String protocol = null;
String host = null;
int port = -1;
String user = null;
String password = null;
String file = null;
// get whatever information we can from the URL
// XXX - url should always be non-null here, Session
// passes it into the constructor
if (url != null) {
protocol = url.getProtocol();
host = url.getHost();
port = url.getPort();
user = url.getUsername();
password = url.getPassword();
file = url.getFile();
}
// try to get protocol-specific default properties
if (protocol != null) {
if (host == null)
host = session.getProperty("mail." + protocol + ".host");
if (user == null)
user = session.getProperty("mail." + protocol + ".user");
}
// try to get mail-wide default properties
if (host == null)
host = session.getProperty("mail.host");
if (user == null)
user = session.getProperty("mail.user");
// try using the system username
if (user == null) {
try {
user = System.getProperty("user.name");
} catch (SecurityException sex) {
// XXX - it's not worth creating a MailLogger just for this
//logger.log(Level.CONFIG, "Can't get user.name property", sex);
}
}
url = new URLName(protocol, host, port, file, user, password);
}
/**
* A generic connect method that takes no parameters. Subclasses
* can implement the appropriate authentication schemes. Subclasses
* that need additional information might want to use some properties
* or might get it interactively using a popup window. <p>
*
* If the connection is successful, an "open" <code>ConnectionEvent</code>
* is delivered to any <code>ConnectionListeners</code> on this service. <p>
*
* Most clients should just call this method to connect to the service.<p>
*
* It is an error to connect to an already connected service. <p>
*
* The implementation provided here simply calls the following
* <code>connect(String, String, String)</code> method with nulls.
*
* @exception AuthenticationFailedException for authentication failures
* @exception MessagingException for other failures
* @exception IllegalStateException if the service is already connected
*
* @see javax.mail.event.ConnectionEvent
*/
public void connect() throws MessagingException {
connect(null, null, null);
}
/**
* 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" <code>ConnectionEvent</code>
* is delivered to any <code>ConnectionListeners</code> on this service. <p>
*
* It is an error to connect to an already connected service. <p>
*
* The implementation in the Service class will collect defaults
* for the host, user, and password from the session, from the
* <code>URLName</code> for this service, and from the supplied
* parameters and then call the <code>protocolConnect</code> method.
* If the <code>protocolConnect</code> method returns <code>false</code>,
* the user will be prompted for any missing information and the
* <code>protocolConnect</code> method will be called again. The
* subclass should override the <code>protocolConnect</code> method.
* 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 username passed in is null, a default value will be chosen
* as described above.
*
* If the password passed in is null and this is the first successful
* connection to this service, the user name and the password
* collected from the user will be saved as defaults for subsequent
* connection attempts to this same service when using other Service object
* instances (the connection information is typically always saved within
* a particular Service object instance). The password is saved using the
* Session method <code>setPasswordAuthentication</code>. 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 service is already connected
* @see javax.mail.event.ConnectionEvent
* @see javax.mail.Session#setPasswordAuthentication
*/
public void connect(String host, String user, String password)
throws MessagingException {
connect(host, -1, user, password);
}
/**
* Connect to the current host using the specified username
* and password. This method is equivalent to calling the
* <code>connect(host, user, password)</code> method with null
* for the host name.
*
* @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 service is already connected
* @see javax.mail.event.ConnectionEvent
* @see javax.mail.Session#setPasswordAuthentication
* @see #connect(java.lang.String, java.lang.String, java.lang.String)
* @since JavaMail 1.4
*/
public void connect(String user, String password) throws MessagingException {
connect(null, user, password);
}
/**
* Similar to connect(host, user, password) except a specific port
* can be specified.
*
* @param host the host to connect to
* @param port the port to connect to (-1 means the default port)
* @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 service is already connected
* @see #connect(java.lang.String, java.lang.String, java.lang.String)
* @see javax.mail.event.ConnectionEvent
*/
public synchronized void connect(String host, int port,
String user, String password) throws MessagingException {
// see if the service is already connected
if (isConnected())
throw new IllegalStateException("already connected");
PasswordAuthentication pw;
boolean connected = false;
boolean save = false;
String protocol = null;
String file = null;
// get whatever information we can from the URL
// XXX - url should always be non-null here, Session
// passes it into the constructor
if (url != null) {
protocol = url.getProtocol();
if (host == null)
host = url.getHost();
if (port == -1)
port = url.getPort();
if (user == null) {
user = url.getUsername();
if (password == null) // get password too if we need it
password = url.getPassword();
} else {
if (password == null && user.equals(url.getUsername()))
// only get the password if it matches the username
password = url.getPassword();
}
file = url.getFile();
}
// try to get protocol-specific default properties
if (protocol != null) {
if (host == null)
host = session.getProperty("mail." + protocol + ".host");
if (user == null)
user = session.getProperty("mail." + protocol + ".user");
}
// try to get mail-wide default properties
if (host == null)
host = session.getProperty("mail.host");
if (user == null)
user = session.getProperty("mail.user");
// try using the system username
if (user == null) {
try {
user = System.getProperty("user.name");
} catch (SecurityException sex) {
// XXX - it's not worth creating a MailLogger just for this
//logger.log(Level.CONFIG, "Can't get user.name property", sex);
}
}
// if we don't have a password, look for saved authentication info
if (password == null && url != null) {
// canonicalize the URLName
setURLName(new URLName(protocol, host, port, file, user, null));
pw = session.getPasswordAuthentication(getURLName());
if (pw != null) {
if (user == null) {
user = pw.getUserName();
password = pw.getPassword();
} else if (user.equals(pw.getUserName())) {
password = pw.getPassword();
}
} else
save = true;
}
// try connecting, if the protocol needs some missing
// information (user, password) it will not connect.
// if it tries to connect and fails, remember why for later.
AuthenticationFailedException authEx = null;
try {
connected = protocolConnect(host, port, user, password);
} catch (AuthenticationFailedException ex) {
authEx = ex;
}
// if not connected, ask the user and try again
if (!connected) {
InetAddress addr;
try {
addr = InetAddress.getByName(host);
} catch (UnknownHostException e) {
addr = null;
}
pw = session.requestPasswordAuthentication(
addr, port,
protocol,
null, user);
if (pw != null) {
user = pw.getUserName();
password = pw.getPassword();
// have the service connect again
connected = protocolConnect(host, port, user, password);
}
}
// if we're not connected by now, we give up
if (!connected) {
if (authEx != null)
throw authEx;
else if (user == null)
throw new AuthenticationFailedException(
"failed to connect, no user name specified?");
else if (password == null)
throw new AuthenticationFailedException(
"failed to connect, no password specified?");
else
throw new AuthenticationFailedException("failed to connect");
}
setURLName(new URLName(protocol, host, port, file, user, password));
if (save)
session.setPasswordAuthentication(getURLName(),
new PasswordAuthentication(user, password));
// set our connected state
setConnected(true);
// finally, deliver the connection event
notifyConnectionListeners(ConnectionEvent.OPENED);
}
/**
* The service implementation should override this method to
* perform the actual protocol-specific connection attempt.
* The default implementation of the <code>connect</code> method
* calls this method as needed. <p>
*
* The <code>protocolConnect</code> method should return
* <code>false</code> if a user name or password is required
* for authentication but the corresponding parameter is null;
* the <code>connect</code> method will prompt the user when
* needed to supply missing information. This method may
* also return <code>false</code> if authentication fails for
* the supplied user name or password. Alternatively, this method
* may throw an AuthenticationFailedException when authentication
* fails. This exception may include a String message with more
* detail about the failure. <p>
*
* The <code>protocolConnect</code> method should throw an
* exception to report failures not related to authentication,
* such as an invalid host name or port number, loss of a
* connection during the authentication process, unavailability
* of the server, etc.
*
* @param host the name of the host to connect to
* @param port the port to use (-1 means use default port)
* @param user the name of the user to login as
* @param password the user's password
* @return true if connection successful, false if authentication failed
* @exception AuthenticationFailedException for authentication failures
* @exception MessagingException for non-authentication failures
*/
protected boolean protocolConnect(String host, int port, String user,
String password) throws MessagingException {
return false;
}
/**
* Is this service currently connected? <p>
*
* This implementation uses a private boolean field to
* store the connection state. This method returns the value
* of that field. <p>
*
* Subclasses may want to override this method to verify that any
* connection to the message store is still alive.
*
* @return true if the service is connected, false if it is not connected
*/
public synchronized boolean isConnected() {
return connected;
}
/**
* Set the connection state of this service. The connection state
* will automatically be set by the service implementation during the
* <code>connect</code> and <code>close</code> methods.
* Subclasses will need to call this method to set the state
* if the service was automatically disconnected. <p>
*
* The implementation in this class merely sets the private field
* returned by the <code>isConnected</code> method.
*
* @param connected true if the service is connected,
* false if it is not connected
*/
protected synchronized void setConnected(boolean connected) {
this.connected = connected;
}
/**
* Close this service and terminate its connection. A close
* ConnectionEvent is delivered to any ConnectionListeners. Any
* Messaging components (Folders, Messages, etc.) belonging to this
* service are invalid after this service is closed. Note that the service
* is closed even if this method terminates abnormally by throwing
* a MessagingException. <p>
*
* This implementation uses <code>setConnected(false)</code> to set
* this service's connected state to <code>false</code>. It will then
* send a close ConnectionEvent to any registered ConnectionListeners.
* Subclasses overriding this method to do implementation specific
* cleanup should call this method as a last step to insure event
* notification, probably by including a call to <code>super.close()</code>
* in a <code>finally</code> clause.
*
* @see javax.mail.event.ConnectionEvent
* @throws MessagingException for errors while closing
*/
public synchronized void close() throws MessagingException {
setConnected(false);
notifyConnectionListeners(ConnectionEvent.CLOSED);
}
/**
* Return a URLName representing this service. 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. <p>
*
* The implementation in the Service class returns (usually a copy of)
* the <code>url</code> field with the password and file information
* stripped out.
*
* @return the URLName representing this service
* @see URLName
*/
public synchronized URLName getURLName() {
if (url != null && (url.getPassword() != null || url.getFile() != null))
return new URLName(url.getProtocol(), url.getHost(),
url.getPort(), null /* no file */,
url.getUsername(), null /* no password */);
else
return url;
}
/**
* Set the URLName representing this service.
* Normally used to update the <code>url</code> field
* after a service has successfully connected. <p>
*
* Subclasses should only override this method if their
* URL does not follow the standard format. In particular,
* subclasses should override this method if their URL
* does not require all the possible fields supported by
* <code>URLName</code>; a new <code>URLName</code> should
* be constructed with any unneeded fields removed. <p>
*
* The implementation in the Service class simply sets the
* <code>url</code> field.
*
* @see URLName
*/
protected synchronized void setURLName(URLName url) {
this.url = url;
}
/**
* Add a listener for Connection events on this service. <p>
*
* The default implementation provided here adds this listener
* to an internal list of ConnectionListeners.
*
* @param l the Listener for Connection events
* @see javax.mail.event.ConnectionEvent
*/
public void addConnectionListener(ConnectionListener l) {
connectionListeners.addElement(l);
}
/**
* Remove a Connection event listener. <p>
*
* The default implementation provided here removes this listener
* from the internal list of ConnectionListeners.
*
* @param l the listener
* @see #addConnectionListener
*/
public void removeConnectionListener(ConnectionListener l) {
connectionListeners.removeElement(l);
}
/**
* Notify all ConnectionListeners. Service implementations are
* expected to use this method to broadcast connection events. <p>
*
* The provided default implementation queues the event into
* an internal event queue. An event dispatcher thread dequeues
* events from the queue and dispatches them to the registered
* ConnectionListeners. Note that the event dispatching occurs
* in a separate thread, thus avoiding potential deadlock problems.
*/
protected void notifyConnectionListeners(int type) {
/*
* Don't bother queuing an event if there's no listeners.
* Yes, listeners could be removed after checking, which
* just makes this an expensive no-op.
*/
if (connectionListeners.size() > 0) {
ConnectionEvent e = new ConnectionEvent(this, type);
queueEvent(e, connectionListeners);
}
/* Fix for broken JDK1.1.x Garbage collector :
* The 'conservative' GC in JDK1.1.x occasionally fails to
* garbage-collect Threads which are in the wait state.
* This would result in thread (and consequently memory) leaks.
*
* We attempt to fix this by sending a 'terminator' event
* to the queue, after we've sent the CLOSED event. The
* terminator event causes the event-dispatching thread to
* self destruct.
*/
if (type == ConnectionEvent.CLOSED)
terminateQueue();
}
/**
* Return <code>getURLName.toString()</code> if this service has a URLName,
* otherwise it will return the default <code>toString</code>.
*/
public String toString() {
URLName url = getURLName();
if (url != null)
return url.toString();
else
return super.toString();
}
/*
* The queue of events to be delivered.
*/
private EventQueue q;
/*
* A lock for creating the EventQueue object. Only one thread should
* create an EventQueue for this service. We can't synchronize on the
* service's lock because that might violate the locking hierarchy in
* some cases.
*/
private Object qLock = new Object();
/**
* Add the event and vector of listeners to the queue to be delivered.
*/
protected void queueEvent(MailEvent event, Vector vector) {
// synchronize creation of the event queue
synchronized (qLock) {
if (q == null)
q = new EventQueue();
}
/*
* Copy the vector in order to freeze the state of the set
* of EventListeners the event should be delivered to prior
* to delivery. This ensures that any changes made to the
* Vector from a target listener's method during the delivery
* of this event will not take effect until after the event is
* delivered.
*/
Vector v = (Vector)vector.clone();
q.enqueue(event, v);
}
static class TerminatorEvent extends MailEvent {
private static final long serialVersionUID = 5542172141759168416L;
TerminatorEvent() {
super(new Object());
}
public void dispatch(Object listener) {
// Kill the event dispatching thread.
Thread.currentThread().interrupt();
}
}
// Dispatch the terminator
private void terminateQueue() {
synchronized (qLock) {
if (q != null) {
Vector dummyListeners = new Vector();
dummyListeners.setSize(1); // need atleast one listener
q.enqueue(new TerminatorEvent(), dummyListeners);
q = null;
}
}
}
/**
* Stop the event dispatcher thread so the queue can be garbage collected.
*/
protected void finalize() throws Throwable {
super.finalize();
terminateQueue();
}
}
File diff suppressed because it is too large Load Diff
+315
View File
@@ -0,0 +1,315 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.mail.event.*;
/**
* An abstract class that models a message store and its
* access protocol, for storing and retrieving messages.
* Subclasses provide actual implementations. <p>
*
* Note that <code>Store</code> extends the <code>Service</code>
* class, which provides many common methods for naming stores,
* connecting to stores, and listening to connection events.
*
* @author John Mani
* @author Bill Shannon
*
* @see javax.mail.Service
* @see javax.mail.event.ConnectionEvent
* @see javax.mail.event.StoreEvent
*/
public abstract class Store extends Service {
/**
* Constructor.
*
* @param session Session object for this Store.
* @param urlname URLName object to be used for this Store
*/
protected Store(Session session, URLName urlname) {
super(session, urlname);
}
/**
* Returns a Folder object that represents the 'root' of
* the default namespace presented to the user by the Store.
*
* @return the root Folder
* @exception IllegalStateException if this Store is not connected.
*/
public abstract Folder getDefaultFolder() throws MessagingException;
/**
* Return the Folder object corresponding to the given name. Note
* that a Folder object is returned even if the named folder does
* not physically exist on the Store. The <code>exists()</code>
* method on the folder object indicates whether this folder really
* exists. <p>
*
* Folder objects are not cached by the Store, so invoking this
* method on the same name multiple times will return that many
* distinct Folder objects.
*
* @param name The name of the Folder. In some Stores, name can
* be an absolute path if it starts with the
* hierarchy delimiter. Else it is interpreted
* relative to the 'root' of this namespace.
* @return Folder object
* @exception IllegalStateException if this Store is not connected.
* @see Folder#exists
* @see Folder#create
*/
public abstract Folder getFolder(String name)
throws MessagingException;
/**
* Return a closed Folder object, corresponding to the given
* URLName. The store specified in the given URLName should
* refer to this Store object. <p>
*
* Implementations of this method may obtain the name of the
* actual folder using the <code>getFile()</code> method on
* URLName, and use that name to create the folder.
*
* @param url URLName that denotes a folder
* @see URLName
* @exception IllegalStateException if this Store is not connected.
* @return Folder object
*/
public abstract Folder getFolder(URLName url)
throws MessagingException;
/**
* Return a set of folders representing the <i>personal</i> namespaces
* for the current user. A personal namespace is a set of names that
* is considered within the personal scope of the authenticated user.
* Typically, only the authenticated user has access to mail folders
* in their personal namespace. If an INBOX exists for a user, it
* must appear within the user's personal namespace. In the
* typical case, there should be only one personal namespace for each
* user in each Store. <p>
*
* This implementation returns an array with a single entry containing
* the return value of the <code>getDefaultFolder</code> method.
* Subclasses should override this method to return appropriate information.
*
* @exception IllegalStateException if this Store is not connected.
* @return array of Folder objects
* @since JavaMail 1.2
*/
public Folder[] getPersonalNamespaces() throws MessagingException {
return new Folder[] { getDefaultFolder() };
}
/**
* Return a set of folders representing the namespaces for
* <code>user</code>. The namespaces returned represent the
* personal namespaces for the user. To access mail folders in the
* other user's namespace, the currently authenticated user must be
* explicitly granted access rights. For example, it is common for
* a manager to grant to their secretary access rights to their
* mail folders. <p>
*
* This implementation returns an empty array. Subclasses should
* override this method to return appropriate information.
*
* @exception IllegalStateException if this Store is not connected.
* @return array of Folder objects
* @since JavaMail 1.2
*/
public Folder[] getUserNamespaces(String user)
throws MessagingException {
return new Folder[0];
}
/**
* Return a set of folders representing the <i>shared</i> namespaces.
* A shared namespace is a namespace that consists of mail folders
* that are intended to be shared amongst users and do not exist
* within a user's personal namespace. <p>
*
* This implementation returns an empty array. Subclasses should
* override this method to return appropriate information.
*
* @exception IllegalStateException if this Store is not connected.
* @return array of Folder objects
* @since JavaMail 1.2
*/
public Folder[] getSharedNamespaces() throws MessagingException {
return new Folder[0];
}
// Vector of Store listeners
private volatile Vector storeListeners = null;
/**
* Add a listener for StoreEvents on this Store. <p>
*
* The default implementation provided here adds this listener
* to an internal list of StoreListeners.
*
* @param l the Listener for Store events
* @see javax.mail.event.StoreEvent
*/
public synchronized void addStoreListener(StoreListener l) {
if (storeListeners == null)
storeListeners = new Vector();
storeListeners.addElement(l);
}
/**
* Remove a listener for Store events. <p>
*
* The default implementation provided here removes this listener
* from the internal list of StoreListeners.
*
* @param l the listener
* @see #addStoreListener
*/
public synchronized void removeStoreListener(StoreListener l) {
if (storeListeners != null)
storeListeners.removeElement(l);
}
/**
* Notify all StoreListeners. Store implementations are
* expected to use this method to broadcast StoreEvents. <p>
*
* The provided default implementation queues the event into
* an internal event queue. An event dispatcher thread dequeues
* events from the queue and dispatches them to the registered
* StoreListeners. Note that the event dispatching occurs
* in a separate thread, thus avoiding potential deadlock problems.
*/
protected void notifyStoreListeners(int type, String message) {
if (storeListeners == null)
return;
StoreEvent e = new StoreEvent(this, type, message);
queueEvent(e, storeListeners);
}
// Vector of folder listeners
private volatile Vector folderListeners = null;
/**
* Add a listener for Folder events on any Folder object
* obtained from this Store. FolderEvents are delivered to
* FolderListeners on the affected Folder as well as to
* FolderListeners on the containing Store. <p>
*
* The default implementation provided here adds this listener
* to an internal list of FolderListeners.
*
* @param l the Listener for Folder events
* @see javax.mail.event.FolderEvent
*/
public synchronized void addFolderListener(FolderListener l) {
if (folderListeners == null)
folderListeners = new Vector();
folderListeners.addElement(l);
}
/**
* Remove a listener for Folder events. <p>
*
* The default implementation provided here removes this listener
* from the internal list of FolderListeners.
*
* @param l the listener
* @see #addFolderListener
*/
public synchronized void removeFolderListener(FolderListener l) {
if (folderListeners != null)
folderListeners.removeElement(l);
}
/**
* Notify all FolderListeners. Store implementations are
* expected to use this method to broadcast Folder events. <p>
*
* The provided default implementation queues the event into
* an internal event queue. An event dispatcher thread dequeues
* events from the queue and dispatches them to the registered
* FolderListeners. Note that the event dispatching occurs
* in a separate thread, thus avoiding potential deadlock problems.
*
* @param type type of FolderEvent
* @param folder affected Folder
* @see #notifyFolderRenamedListeners
*/
protected void notifyFolderListeners(int type, Folder folder) {
if (folderListeners == null)
return;
FolderEvent e = new FolderEvent(this, folder, type);
queueEvent(e, folderListeners);
}
/**
* Notify all FolderListeners about the renaming of a folder.
* Store implementations are expected to use this method to broadcast
* Folder events indicating the renaming of folders. <p>
*
* The provided default implementation queues the event into
* an internal event queue. An event dispatcher thread dequeues
* events from the queue and dispatches them to the registered
* FolderListeners. Note that the event dispatching occurs
* in a separate thread, thus avoiding potential deadlock problems.
*
* @param oldF the folder being renamed
* @param newF the folder representing the new name.
* @since JavaMail 1.1
*/
protected void notifyFolderRenamedListeners(Folder oldF, Folder newF) {
if (folderListeners == null)
return;
FolderEvent e = new FolderEvent(this, oldF, newF,FolderEvent.RENAMED);
queueEvent(e, folderListeners);
}
}
@@ -0,0 +1,105 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
/**
* This exception is thrown when a method is invoked on a Messaging object
* and the Store that owns that object has died due to some reason.
* This exception should be treated as a fatal error; in particular any
* messaging object belonging to that Store must be considered invalid. <p>
*
* The connect method may be invoked on the dead Store object to
* revive it. <p>
*
* The getMessage() method returns more detailed information about the
* error that caused this exception. <p>
*
* @author John Mani
*/
public class StoreClosedException extends MessagingException {
transient private Store store;
private static final long serialVersionUID = -3145392336120082655L;
/**
* Constructs a StoreClosedException with no detail message.
*
* @param store The dead Store object
*/
public StoreClosedException(Store store) {
this(store, null);
}
/**
* Constructs a StoreClosedException with the specified
* detail message.
*
* @param store The dead Store object
* @param message The detailed error message
*/
public StoreClosedException(Store store, String message) {
super(message);
this.store = store;
}
/**
* Constructs a StoreClosedException with the specified
* detail message and embedded exception. The exception is chained
* to this exception.
*
* @param store The dead Store object
* @param message The detailed error message
* @param e The embedded exception
* @since JavaMail 1.5
*/
public StoreClosedException(Store store, String message, Exception e) {
super(message, e);
this.store = store;
}
/**
* Returns the dead Store object
*/
public Store getStore() {
return store;
}
}
+419
View File
@@ -0,0 +1,419 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.io.IOException;
import java.net.*;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import javax.mail.event.*;
/**
* An abstract class that models a message transport.
* Subclasses provide actual implementations. <p>
*
* Note that <code>Transport</code> extends the <code>Service</code>
* class, which provides many common methods for naming transports,
* connecting to transports, and listening to connection events.
*
* @author John Mani
* @author Max Spivak
* @author Bill Shannon
*
* @see javax.mail.Service
* @see javax.mail.event.ConnectionEvent
* @see javax.mail.event.TransportEvent
*/
public abstract class Transport extends Service {
/**
* Constructor.
*
* @param session Session object for this Transport.
* @param urlname URLName object to be used for this Transport
*/
public Transport(Session session, URLName urlname) {
super(session, urlname);
}
/**
* Send a message. The message will be sent to all recipient
* addresses specified in the message (as returned from the
* <code>Message</code> method <code>getAllRecipients</code>),
* using message transports appropriate to each address. The
* <code>send</code> method calls the <code>saveChanges</code>
* method on the message before sending it. <p>
*
* If any of the recipient addresses is detected to be invalid by
* the Transport during message submission, a SendFailedException
* is thrown. Clients can get more detail about the failure by examining
* the exception. Whether or not the message is still sent successfully
* to any valid addresses depends on the Transport implementation. See
* SendFailedException for more details. Note also that success does
* not imply that the message was delivered to the ultimate recipient,
* as failures may occur in later stages of delivery. Once a Transport
* accepts a message for delivery to a recipient, failures that occur later
* should be reported to the user via another mechanism, such as
* returning the undeliverable message. <p>
*
* In typical usage, a SendFailedException reflects an error detected
* by the server. The details of the SendFailedException will usually
* contain the error message from the server (such as an SMTP error
* message). An address may be detected as invalid for a variety of
* reasons - the address may not exist, the address may have invalid
* syntax, the address may have exceeded its quota, etc. <p>
*
* Note that <code>send</code> is a static method that creates and
* manages its own connection. Any connection associated with any
* Transport instance used to invoke this method is ignored and not
* used. This method should only be invoked using the form
* <code>Transport.send(msg);</code>, and should never be invoked
* using an instance variable.
*
* @param msg the message to send
* @exception SendFailedException if the message could not
* be sent to some or any of the recipients.
* @exception MessagingException
* @see Message#saveChanges
* @see Message#getAllRecipients
* @see #send(Message, Address[])
* @see javax.mail.SendFailedException
*/
public static void send(Message msg) throws MessagingException {
msg.saveChanges(); // do this first
send0(msg, msg.getAllRecipients(), null, null);
}
/**
* Send the message to the specified addresses, ignoring any
* recipients specified in the message itself. The
* <code>send</code> method calls the <code>saveChanges</code>
* method on the message before sending it. <p>
*
* @param msg the message to send
* @param addresses the addresses to which to send the message
* @exception SendFailedException if the message could not
* be sent to some or any of the recipients.
* @exception MessagingException
* @see Message#saveChanges
* @see #send(Message)
* @see javax.mail.SendFailedException
*/
public static void send(Message msg, Address[] addresses)
throws MessagingException {
msg.saveChanges();
send0(msg, addresses, null, null);
}
/**
* Send a message. The message will be sent to all recipient
* addresses specified in the message (as returned from the
* <code>Message</code> method <code>getAllRecipients</code>).
* The <code>send</code> method calls the <code>saveChanges</code>
* method on the message before sending it. <p>
*
* Use the specified user name and password to authenticate to
* the mail server.
*
* @param msg the message to send
* @param user the user name
* @param password this user's password
* @exception SendFailedException if the message could not
* be sent to some or any of the recipients.
* @exception MessagingException
* @see Message#saveChanges
* @see #send(Message)
* @see javax.mail.SendFailedException
* @since JavaMail 1.5
*/
public static void send(Message msg,
String user, String password) throws MessagingException {
msg.saveChanges();
send0(msg, msg.getAllRecipients(), user, password);
}
/**
* Send the message to the specified addresses, ignoring any
* recipients specified in the message itself. The
* <code>send</code> method calls the <code>saveChanges</code>
* method on the message before sending it. <p>
*
* Use the specified user name and password to authenticate to
* the mail server.
*
* @param msg the message to send
* @param addresses the addresses to which to send the message
* @param user the user name
* @param password this user's password
* @exception SendFailedException if the message could not
* be sent to some or any of the recipients.
* @exception MessagingException
* @see Message#saveChanges
* @see #send(Message)
* @see javax.mail.SendFailedException
* @since JavaMail 1.5
*/
public static void send(Message msg, Address[] addresses,
String user, String password) throws MessagingException {
msg.saveChanges();
send0(msg, addresses, user, password);
}
// send, but without the saveChanges
private static void send0(Message msg, Address[] addresses,
String user, String password) throws MessagingException {
if (addresses == null || addresses.length == 0)
throw new SendFailedException("No recipient addresses");
/*
* protocols is a hashtable containing the addresses
* indexed by address type
*/
Hashtable protocols = new Hashtable();
// Vectors of addresses
Vector invalid = new Vector();
Vector validSent = new Vector();
Vector validUnsent = new Vector();
for (int i = 0; i < addresses.length; i++) {
// is this address type already in the hashtable?
if (protocols.containsKey(addresses[i].getType())) {
Vector v = (Vector)protocols.get(addresses[i].getType());
v.addElement(addresses[i]);
} else {
// need to add a new protocol
Vector w = new Vector();
w.addElement(addresses[i]);
protocols.put(addresses[i].getType(), w);
}
}
int dsize = protocols.size();
if (dsize == 0)
throw new SendFailedException("No recipient addresses");
Session s = (msg.session != null) ? msg.session :
Session.getDefaultInstance(System.getProperties(), null);
Transport transport;
/*
* Optimize the case of a single protocol.
*/
if (dsize == 1) {
transport = s.getTransport(addresses[0]);
try {
if (user != null)
transport.connect(user, password);
else
transport.connect();
transport.sendMessage(msg, addresses);
} finally {
transport.close();
}
return;
}
/*
* More than one protocol. Have to do them one at a time
* and collect addresses and chain exceptions.
*/
MessagingException chainedEx = null;
boolean sendFailed = false;
Enumeration e = protocols.elements();
while (e.hasMoreElements()) {
Vector v = (Vector)e.nextElement();
Address[] protaddresses = new Address[v.size()];
v.copyInto(protaddresses);
// Get a Transport that can handle this address type.
if ((transport = s.getTransport(protaddresses[0])) == null) {
// Could not find an appropriate Transport ..
// Mark these addresses invalid.
for (int j = 0; j < protaddresses.length; j++)
invalid.addElement(protaddresses[j]);
continue;
}
try {
transport.connect();
transport.sendMessage(msg, protaddresses);
} catch (SendFailedException sex) {
sendFailed = true;
// chain the exception we're catching to any previous ones
if (chainedEx == null)
chainedEx = sex;
else
chainedEx.setNextException(sex);
// retrieve invalid addresses
Address[] a = sex.getInvalidAddresses();
if (a != null)
for (int j = 0; j < a.length; j++)
invalid.addElement(a[j]);
// retrieve validSent addresses
a = sex.getValidSentAddresses();
if (a != null)
for (int k = 0; k < a.length; k++)
validSent.addElement(a[k]);
// retrieve validUnsent addresses
Address[] c = sex.getValidUnsentAddresses();
if (c != null)
for (int l = 0; l < c.length; l++)
validUnsent.addElement(c[l]);
} catch (MessagingException mex) {
sendFailed = true;
// chain the exception we're catching to any previous ones
if (chainedEx == null)
chainedEx = mex;
else
chainedEx.setNextException(mex);
} finally {
transport.close();
}
}
// done with all protocols. throw exception if something failed
if (sendFailed || invalid.size() != 0 || validUnsent.size() != 0) {
Address[] a = null, b = null, c = null;
// copy address vectors into arrays
if (validSent.size() > 0) {
a = new Address[validSent.size()];
validSent.copyInto(a);
}
if (validUnsent.size() > 0) {
b = new Address[validUnsent.size()];
validUnsent.copyInto(b);
}
if (invalid.size() > 0) {
c = new Address[invalid.size()];
invalid.copyInto(c);
}
throw new SendFailedException("Sending failed", chainedEx,
a, b, c);
}
}
/**
* Send the Message to the specified list of addresses. An appropriate
* TransportEvent indicating the delivery status is delivered to any
* TransportListener registered on this Transport. Also, if any of
* the addresses is invalid, a SendFailedException is thrown.
* Whether or not the message is still sent succesfully to
* any valid addresses depends on the Transport implementation. <p>
*
* Unlike the static <code>send</code> method, the <code>sendMessage</code>
* method does <em>not</em> call the <code>saveChanges</code> method on
* the message; the caller should do so.
*
* @param msg The Message to be sent
* @param addresses array of addresses to send this message to
* @see javax.mail.event.TransportEvent
* @exception SendFailedException if the send failed because of
* invalid addresses.
* @exception MessagingException if the connection is dead or not in the
* connected state
*/
public abstract void sendMessage(Message msg, Address[] addresses)
throws MessagingException;
// Vector of Transport listeners
private volatile Vector transportListeners = null;
/**
* Add a listener for Transport events. <p>
*
* The default implementation provided here adds this listener
* to an internal list of TransportListeners.
*
* @param l the Listener for Transport events
* @see javax.mail.event.TransportEvent
*/
public synchronized void addTransportListener(TransportListener l) {
if (transportListeners == null)
transportListeners = new Vector();
transportListeners.addElement(l);
}
/**
* Remove a listener for Transport events. <p>
*
* The default implementation provided here removes this listener
* from the internal list of TransportListeners.
*
* @param l the listener
* @see #addTransportListener
*/
public synchronized void removeTransportListener(TransportListener l) {
if (transportListeners != null)
transportListeners.removeElement(l);
}
/**
* Notify all TransportListeners. Transport implementations are
* expected to use this method to broadcast TransportEvents.<p>
*
* The provided default implementation queues the event into
* an internal event queue. An event dispatcher thread dequeues
* events from the queue and dispatches them to the registered
* TransportListeners. Note that the event dispatching occurs
* in a separate thread, thus avoiding potential deadlock problems.
*/
protected void notifyTransportListeners(int type, Address[] validSent,
Address[] validUnsent,
Address[] invalid, Message msg) {
if (transportListeners == null)
return;
TransportEvent e = new TransportEvent(this, type, validSent,
validUnsent, invalid, msg);
queueEvent(e, transportListeners);
}
}
+192
View File
@@ -0,0 +1,192 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.util.NoSuchElementException;
/**
* The <code>UIDFolder</code> interface is implemented by Folders
* that can support the "disconnected" mode of operation, by providing
* unique-ids for messages in the folder. This interface is based on
* the IMAP model for supporting disconnected operation. <p>
*
* A Unique identifier (UID) is a positive long value, assigned to
* each message in a specific folder. Unique identifiers are assigned
* in a strictly <strong>ascending</strong> fashion in the mailbox.
* That is, as each message is added to the mailbox it is assigned a
* higher UID than the message(s) which were added previously. Unique
* identifiers persist across sessions. This permits a client to
* resynchronize its state from a previous session with the server. <p>
*
* Associated with every mailbox is a unique identifier validity value.
* If unique identifiers from an earlier session fail to persist to
* this session, the unique identifier validity value
* <strong>must</strong> be greater than the one used in the earlier
* session. <p>
*
* Refer to <A HREF="http://www.ietf.org/rfc/rfc2060.txt">RFC 2060</A>
* for more information.
*
* All the Folder objects returned by the default IMAP provider implement
* the UIDFolder interface. Use it as follows: <p>
* <blockquote><pre>
*
* Folder f = store.getFolder("whatever");
* UIDFolder uf = (UIDFolder)f;
* long uid = uf.getUID(msg);
*
* </pre></blockquote><p>
*
* @author John Mani
*/
public interface UIDFolder {
/**
* A fetch profile item for fetching UIDs.
* This inner class extends the <code>FetchProfile.Item</code>
* class to add new FetchProfile item types, specific to UIDFolders.
* The only item currently defined here is the <code>UID</code> item.
*
* @see FetchProfile
*/
public static class FetchProfileItem extends FetchProfile.Item {
protected FetchProfileItem(String name) {
super(name);
}
/**
* UID is a fetch profile item that can be included in a
* <code>FetchProfile</code> during a fetch request to a Folder.
* This item indicates that the UIDs for messages in the specified
* range are desired to be prefetched. <p>
*
* An example of how a client uses this is below: <p>
* <blockquote><pre>
*
* FetchProfile fp = new FetchProfile();
* fp.add(UIDFolder.FetchProfileItem.UID);
* folder.fetch(msgs, fp);
*
* </pre></blockquote><p>
*/
public static final FetchProfileItem UID =
new FetchProfileItem("UID");
}
/**
* This is a special value that can be used as the <code>end</code>
* parameter in <code>getMessagesByUID(start, end)</code>, to denote the
* UID of the last message in the folder.
*
* @see #getMessagesByUID
*/
public final static long LASTUID = -1;
/**
* Returns the UIDValidity value associated with this folder. <p>
*
* Clients typically compare this value against a UIDValidity
* value saved from a previous session to insure that any cached
* UIDs are not stale.
*
* @return UIDValidity
*/
public long getUIDValidity() throws MessagingException;
/**
* Get the Message corresponding to the given UID. If no such
* message exists, <code>null</code> is returned.
*
* @param uid UID for the desired message
* @return the Message object. <code>null</code> is returned
* if no message corresponding to this UID is obtained.
* @exception MessagingException
*/
public Message getMessageByUID(long uid) throws MessagingException;
/**
* Get the Messages specified by the given range. The special
* value LASTUID can be used for the <code>end</code> parameter
* to indicate the UID of the last message in the folder. <p>
*
* Note that <code>end</code> need not be greater than <code>start</code>;
* the order of the range doesn't matter.
* Note also that, unless the folder is empty, use of LASTUID ensures
* that at least one message will be returned - the last message in the
* folder.
*
* @param start start UID
* @param end end UID
* @return array of Message objects
* @exception MessagingException
* @see #LASTUID
*/
public Message[] getMessagesByUID(long start, long end)
throws MessagingException;
/**
* Get the Messages specified by the given array of UIDs. If any UID is
* invalid, <code>null</code> is returned for that entry. <p>
*
* Note that the returned array will be of the same size as the specified
* array of UIDs, and <code>null</code> entries may be present in the
* array to indicate invalid UIDs.
*
* @param uids array of UIDs
* @return array of Message objects
* @exception MessagingException
*/
public Message[] getMessagesByUID(long[] uids)
throws MessagingException;
/**
* Get the UID for the specified message. Note that the message
* <strong>must</strong> belong to this folder. Otherwise
* java.util.NoSuchElementException is thrown.
*
* @param message Message from this folder
* @return UID for this message
* @exception NoSuchElementException if the given Message
* is not in this Folder.
*/
public long getUID(Message message) throws MessagingException;
}
+770
View File
@@ -0,0 +1,770 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail;
import java.net.*;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.BitSet;
import java.util.Locale;
/**
* The name of a URL. This class represents a URL name and also
* provides the basic parsing functionality to parse most internet
* standard URL schemes. <p>
*
* Note that this class differs from <code>java.net.URL</code>
* in that this class just represents the name of a URL, it does
* not model the connection to a URL.
*
* @author Christopher Cotton
* @author Bill Shannon
*/
public class URLName {
/**
* The full version of the URL
*/
protected String fullURL;
/**
* The protocol to use (ftp, http, nntp, imap, pop3 ... etc.) .
*/
private String protocol;
/**
* The username to use when connecting
*/
private String username;
/**
* The password to use when connecting.
*/
private String password;
/**
* The host name to which to connect.
*/
private String host;
/**
* The host's IP address, used in equals and hashCode.
* Computed on demand.
*/
private InetAddress hostAddress;
private boolean hostAddressKnown = false;
/**
* The protocol port to connect to.
*/
private int port = -1;
/**
* The specified file name on that host.
*/
private String file;
/**
* # reference.
*/
private String ref;
/**
* Our hash code.
*/
private int hashCode = 0;
/**
* A way to turn off encoding, just in case...
*/
private static boolean doEncode = true;
static {
try {
doEncode = !Boolean.getBoolean("mail.URLName.dontencode");
} catch (Exception ex) {
// ignore any errors
}
}
/**
* Creates a URLName object from the specified protocol,
* host, port number, file, username, and password. Specifying a port
* number of -1 indicates that the URL should use the default port for
* the protocol.
*/
public URLName(
String protocol,
String host,
int port,
String file,
String username,
String password
)
{
this.protocol = protocol;
this.host = host;
this.port = port;
int refStart;
if (file != null && (refStart = file.indexOf('#')) != -1) {
this.file = file.substring(0, refStart);
this.ref = file.substring(refStart + 1);
} else {
this.file = file;
this.ref = null;
}
this.username = doEncode ? encode(username) : username;
this.password = doEncode ? encode(password) : password;
}
/**
* Construct a URLName from a java.net.URL object.
*/
public URLName(URL url) {
this(url.toString());
}
/**
* Construct a URLName from the string. Parses out all the possible
* information (protocol, host, port, file, username, password).
*/
public URLName(String url) {
parseString(url);
}
/**
* Constructs a string representation of this URLName.
*/
public String toString() {
if (fullURL == null) {
// add the "protocol:"
StringBuffer tempURL = new StringBuffer();
if (protocol != null) {
tempURL.append(protocol);
tempURL.append(":");
}
if (username != null || host != null) {
// add the "//"
tempURL.append("//");
// add the user:password@
// XXX - can you just have a password? without a username?
if (username != null) {
tempURL.append(username);
if (password != null){
tempURL.append(":");
tempURL.append(password);
}
tempURL.append("@");
}
// add host
if (host != null) {
tempURL.append(host);
}
// add port (if needed)
if (port != -1) {
tempURL.append(":");
tempURL.append(Integer.toString(port));
}
if (file != null)
tempURL.append("/");
}
// add the file
if (file != null) {
tempURL.append(file);
}
// add the ref
if (ref != null) {
tempURL.append("#");
tempURL.append(ref);
}
// create the fullURL now
fullURL = tempURL.toString();
}
return fullURL;
}
/**
* Method which does all of the work of parsing the string.
*/
protected void parseString(String url) {
// initialize everything in case called from subclass
// (URLName really should be a final class)
protocol = file = ref = host = username = password = null;
port = -1;
int len = url.length();
// find the protocol
// XXX - should check for only legal characters before the colon
// (legal: a-z, A-Z, 0-9, "+", ".", "-")
int protocolEnd = url.indexOf(':');
if (protocolEnd != -1)
protocol = url.substring(0, protocolEnd);
// is this an Internet standard URL that contains a host name?
if (url.regionMatches(protocolEnd + 1, "//", 0, 2)) {
// find where the file starts
String fullhost = null;
int fileStart = url.indexOf('/', protocolEnd + 3);
if (fileStart != -1) {
fullhost = url.substring(protocolEnd + 3, fileStart);
if (fileStart + 1 < len)
file = url.substring(fileStart + 1);
else
file = "";
} else
fullhost = url.substring(protocolEnd + 3);
// examine the fullhost, for username password etc.
int i = fullhost.indexOf('@');
if (i != -1) {
String fulluserpass = fullhost.substring(0, i);
fullhost = fullhost.substring(i + 1);
// get user and password
int passindex = fulluserpass.indexOf(':');
if (passindex != -1) {
username = fulluserpass.substring(0, passindex);
password = fulluserpass.substring(passindex + 1);
} else {
username = fulluserpass;
}
}
// get the port (if there)
int portindex;
if (fullhost.length() > 0 && fullhost.charAt(0) == '[') {
// an IPv6 address?
portindex = fullhost.indexOf(':', fullhost.indexOf(']'));
} else {
portindex = fullhost.indexOf(':');
}
if (portindex != -1) {
String portstring = fullhost.substring(portindex + 1);
if (portstring.length() > 0) {
try {
port = Integer.parseInt(portstring);
} catch (NumberFormatException nfex) {
port = -1;
}
}
host = fullhost.substring(0, portindex);
} else {
host = fullhost;
}
} else {
if (protocolEnd + 1 < len)
file = url.substring(protocolEnd + 1);
}
// extract the reference from the file name, if any
int refStart;
if (file != null && (refStart = file.indexOf('#')) != -1) {
ref = file.substring(refStart + 1);
file = file.substring(0, refStart);
}
}
/**
* Returns the port number of this URLName.
* Returns -1 if the port is not set.
*/
public int getPort() {
return port;
}
/**
* Returns the protocol of this URLName.
* Returns null if this URLName has no protocol.
*/
public String getProtocol() {
return protocol;
}
/**
* Returns the file name of this URLName.
* Returns null if this URLName has no file name.
*/
public String getFile() {
return file;
}
/**
* Returns the reference of this URLName.
* Returns null if this URLName has no reference.
*/
public String getRef() {
return ref;
}
/**
* Returns the host of this URLName.
* Returns null if this URLName has no host.
*/
public String getHost() {
return host;
}
/**
* Returns the user name of this URLName.
* Returns null if this URLName has no user name.
*/
public String getUsername() {
return doEncode ? decode(username) : username;
}
/**
* Returns the password of this URLName.
* Returns null if this URLName has no password.
*/
public String getPassword() {
return doEncode ? decode(password) : password;
}
/**
* Constructs a URL from the URLName.
*/
public URL getURL() throws MalformedURLException {
return new URL(getProtocol(), getHost(), getPort(), getFile());
}
/**
* Compares two URLNames. The result is true if and only if the
* argument is not null and is a URLName object that represents the
* same URLName as this object. Two URLName objects are equal if
* they have the same protocol and the same host,
* the same port number on the host, the same username,
* and the same file on the host. The fields (host, username,
* file) are also considered the same if they are both
* null. <p>
*
* Hosts are considered equal if the names are equal (case independent)
* or if host name lookups for them both succeed and they both reference
* the same IP address. <p>
*
* Note that URLName has no knowledge of default port numbers for
* particular protocols, so "imap://host" and "imap://host:143"
* would not compare as equal. <p>
*
* Note also that the password field is not included in the comparison,
* nor is any reference field appended to the filename.
*/
public boolean equals(Object obj) {
if (!(obj instanceof URLName))
return false;
URLName u2 = (URLName)obj;
// compare protocols
if (u2.protocol == null || !u2.protocol.equals(protocol))
return false;
// compare hosts
InetAddress a1 = getHostAddress(), a2 = u2.getHostAddress();
// if we have internet address for both, and they're not the same, fail
if (a1 != null && a2 != null) {
if (!a1.equals(a2))
return false;
// else, if we have host names for both, and they're not the same, fail
} else if (host != null && u2.host != null) {
if (!host.equalsIgnoreCase(u2.host))
return false;
// else, if not both null
} else if (host != u2.host) {
return false;
}
// at this point, hosts match
// compare usernames
if (!(username == u2.username ||
(username != null && username.equals(u2.username))))
return false;
// Forget about password since it doesn't
// really denote a different store.
// compare files
String f1 = file == null ? "" : file;
String f2 = u2.file == null ? "" : u2.file;
if (!f1.equals(f2))
return false;
// compare ports
if (port != u2.port)
return false;
// all comparisons succeeded, they're equal
return true;
}
/**
* Compute the hash code for this URLName.
*/
public int hashCode() {
if (hashCode != 0)
return hashCode;
if (protocol != null)
hashCode += protocol.hashCode();
InetAddress addr = getHostAddress();
if (addr != null)
hashCode += addr.hashCode();
else if (host != null)
hashCode += host.toLowerCase(Locale.ENGLISH).hashCode();
if (username != null)
hashCode += username.hashCode();
if (file != null)
hashCode += file.hashCode();
hashCode += port;
return hashCode;
}
/**
* Get the IP address of our host. Look up the
* name the first time and remember that we've done
* so, whether the lookup fails or not.
*/
private synchronized InetAddress getHostAddress() {
if (hostAddressKnown)
return hostAddress;
if (host == null)
return null;
try {
hostAddress = InetAddress.getByName(host);
} catch (UnknownHostException ex) {
hostAddress = null;
}
hostAddressKnown = true;
return hostAddress;
}
/**
* The class contains a utility method for converting a
* <code>String</code> into a MIME format called
* "<code>x-www-form-urlencoded</code>" format.
* <p>
* To convert a <code>String</code>, each character is examined in turn:
* <ul>
* <li>The ASCII characters '<code>a</code>' through '<code>z</code>',
* '<code>A</code>' through '<code>Z</code>', '<code>0</code>'
* through '<code>9</code>', and &quot;.&quot;, &quot;-&quot;,
* &quot;*&quot;, &quot;_&quot; remain the same.
* <li>The space character '<code>&nbsp;</code>' is converted into a
* plus sign '<code>+</code>'.
* <li>All other characters are converted into the 3-character string
* "<code>%<i>xy</i></code>", where <i>xy</i> is the two-digit
* hexadecimal representation of the lower 8-bits of the character.
* </ul>
*
* @author Herb Jellinek
* @since JDK1.0
*/
static BitSet dontNeedEncoding;
static final int caseDiff = ('a' - 'A');
/* The list of characters that are not encoded have been determined by
referencing O'Reilly's "HTML: The Definitive Guide" (page 164). */
static {
dontNeedEncoding = new BitSet(256);
int i;
for (i = 'a'; i <= 'z'; i++) {
dontNeedEncoding.set(i);
}
for (i = 'A'; i <= 'Z'; i++) {
dontNeedEncoding.set(i);
}
for (i = '0'; i <= '9'; i++) {
dontNeedEncoding.set(i);
}
/* encoding a space to a + is done in the encode() method */
dontNeedEncoding.set(' ');
dontNeedEncoding.set('-');
dontNeedEncoding.set('_');
dontNeedEncoding.set('.');
dontNeedEncoding.set('*');
}
/**
* Translates a string into <code>x-www-form-urlencoded</code> format.
*
* @param s <code>String</code> to be translated.
* @return the translated <code>String</code>.
*/
static String encode(String s) {
if (s == null)
return null;
// the common case is no encoding is needed
for (int i = 0; i < s.length(); i++) {
int c = (int)s.charAt(i);
if (c == ' ' || !dontNeedEncoding.get(c))
return _encode(s);
}
return s;
}
private static String _encode(String s) {
int maxBytesPerChar = 10;
StringBuffer out = new StringBuffer(s.length());
ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
OutputStreamWriter writer = new OutputStreamWriter(buf);
for (int i = 0; i < s.length(); i++) {
int c = (int)s.charAt(i);
if (dontNeedEncoding.get(c)) {
if (c == ' ') {
c = '+';
}
out.append((char)c);
} else {
// convert to external encoding before hex conversion
try {
writer.write(c);
writer.flush();
} catch(IOException e) {
buf.reset();
continue;
}
byte[] ba = buf.toByteArray();
for (int j = 0; j < ba.length; j++) {
out.append('%');
char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16);
// converting to use uppercase letter as part of
// the hex value if ch is a letter.
if (Character.isLetter(ch)) {
ch -= caseDiff;
}
out.append(ch);
ch = Character.forDigit(ba[j] & 0xF, 16);
if (Character.isLetter(ch)) {
ch -= caseDiff;
}
out.append(ch);
}
buf.reset();
}
}
return out.toString();
}
/**
* The class contains a utility method for converting from
* a MIME format called "<code>x-www-form-urlencoded</code>"
* to a <code>String</code>
* <p>
* To convert to a <code>String</code>, each character is examined in turn:
* <ul>
* <li>The ASCII characters '<code>a</code>' through '<code>z</code>',
* '<code>A</code>' through '<code>Z</code>', and '<code>0</code>'
* through '<code>9</code>' remain the same.
* <li>The plus sign '<code>+</code>'is converted into a
* space character '<code>&nbsp;</code>'.
* <li>The remaining characters are represented by 3-character
* strings which begin with the percent sign,
* "<code>%<i>xy</i></code>", where <i>xy</i> is the two-digit
* hexadecimal representation of the lower 8-bits of the character.
* </ul>
*
* @author Mark Chamness
* @author Michael McCloskey
* @since 1.2
*/
/**
* Decodes a &quot;x-www-form-urlencoded&quot;
* to a <tt>String</tt>.
* @param s the <code>String</code> to decode
* @return the newly decoded <code>String</code>
*/
static String decode(String s) {
if (s == null)
return null;
if (indexOfAny(s, "+%") == -1)
return s; // the common case
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '+':
sb.append(' ');
break;
case '%':
try {
sb.append((char)Integer.parseInt(
s.substring(i+1,i+3),16));
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
"Illegal URL encoded value: " +
s.substring(i,i+3));
}
i += 2;
break;
default:
sb.append(c);
break;
}
}
// Undo conversion to external encoding
String result = sb.toString();
try {
byte[] inputBytes = result.getBytes("8859_1");
result = new String(inputBytes);
} catch (UnsupportedEncodingException e) {
// The system should always have 8859_1
}
return result;
}
/**
* Return the first index of any of the characters in "any" in "s",
* or -1 if none are found.
*
* This should be a method on String.
*/
private static int indexOfAny(String s, String any) {
return indexOfAny(s, any, 0);
}
private static int indexOfAny(String s, String any, int start) {
try {
int len = s.length();
for (int i = start; i < len; i++) {
if (any.indexOf(s.charAt(i)) >= 0)
return i;
}
return -1;
} catch (StringIndexOutOfBoundsException e) {
return -1;
}
}
/*
// Do not remove, this is needed when testing new URL cases
public static void main(String[] argv) {
String [] testURLNames = {
"protocol://userid:password@host:119/file",
"http://funny/folder/file.html",
"http://funny/folder/file.html#ref",
"http://funny/folder/file.html#",
"http://funny/#ref",
"imap://jmr:secret@labyrinth//var/mail/jmr",
"nntp://fred@labyrinth:143/save/it/now.mbox",
"imap://jmr@labyrinth/INBOX",
"imap://labryrinth",
"imap://labryrinth/",
"file:",
"file:INBOX",
"file:/home/shannon/mail/foo",
"/tmp/foo",
"//host/tmp/foo",
":/tmp/foo",
"/really/weird:/tmp/foo#bar",
""
};
URLName url =
new URLName("protocol", "host", 119, "file", "userid", "password");
System.out.println("Test URL: " + url.toString());
if (argv.length == 0) {
for (int i = 0; i < testURLNames.length; i++) {
print(testURLNames[i]);
System.out.println();
}
} else {
for (int i = 0; i < argv.length; i++) {
print(argv[i]);
System.out.println();
}
if (argv.length == 2) {
URLName u1 = new URLName(argv[0]);
URLName u2 = new URLName(argv[1]);
System.out.println("URL1 hash code: " + u1.hashCode());
System.out.println("URL2 hash code: " + u2.hashCode());
if (u1.equals(u2))
System.out.println("success, equal");
else
System.out.println("fail, not equal");
if (u2.equals(u1))
System.out.println("success, equal");
else
System.out.println("fail, not equal");
if (u1.hashCode() == u2.hashCode())
System.out.println("success, hashCodes equal");
else
System.out.println("fail, hashCodes not equal");
}
}
}
private static void print(String name) {
URLName url = new URLName(name);
System.out.println("Original URL: " + name);
System.out.println("The fullUrl : " + url.toString());
if (!name.equals(url.toString()))
System.out.println(" : NOT EQUAL!");
System.out.println("The protocol is: " + url.getProtocol());
System.out.println("The host is: " + url.getHost());
System.out.println("The port is: " + url.getPort());
System.out.println("The user is: " + url.getUsername());
System.out.println("The password is: " + url.getPassword());
System.out.println("The file is: " + url.getFile());
System.out.println("The ref is: " + url.getRef());
}
*/
}
@@ -0,0 +1,55 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
/**
* The adapter which receives connection events.
* The methods in this class are empty; this class is provided as a
* convenience for easily creating listeners by extending this class
* and overriding only the methods of interest.
*
* @author John Mani
*/
public abstract class ConnectionAdapter implements ConnectionListener {
public void opened(ConnectionEvent e) {}
public void disconnected(ConnectionEvent e) {}
public void closed(ConnectionEvent e) {}
}
@@ -0,0 +1,98 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
import javax.mail.*;
/**
* This class models Connection events.
*
* @author John Mani
*/
public class ConnectionEvent extends MailEvent {
/** A connection was opened. */
public static final int OPENED = 1;
/** A connection was disconnected (not currently used). */
public static final int DISCONNECTED = 2;
/** A connection was closed. */
public static final int CLOSED = 3;
/**
* The event type.
*
* @serial
*/
protected int type;
private static final long serialVersionUID = -1855480171284792957L;
/**
* Constructor
* @param source The source object
*/
public ConnectionEvent(Object source, int type) {
super(source);
this.type = type;
}
/**
* Return the type of this event
* @return type
*/
public int getType() {
return type;
}
/**
* Invokes the appropriate ConnectionListener method
*/
public void dispatch(Object listener) {
if (type == OPENED)
((ConnectionListener)listener).opened(this);
else if (type == DISCONNECTED)
((ConnectionListener)listener).disconnected(this);
else if (type == CLOSED)
((ConnectionListener)listener).closed(this);
}
}
@@ -0,0 +1,68 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
/**
* This is the Listener interface for Connection events.
*
* @author John Mani
*/
public interface ConnectionListener extends java.util.EventListener {
/**
* Invoked when a Store/Folder/Transport is opened.
*/
public void opened(ConnectionEvent e);
/**
* Invoked when a Store is disconnected. Note that a folder
* cannot be disconnected, so a folder will not fire this event
*/
public void disconnected(ConnectionEvent e);
/**
* Invoked when a Store/Folder/Transport is closed.
*/
public void closed(ConnectionEvent e);
}
@@ -0,0 +1,55 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
/**
* The adapter which receives Folder events.
* The methods in this class are empty; this class is provided as a
* convenience for easily creating listeners by extending this class
* and overriding only the methods of interest.
*
* @author John Mani
*/
public abstract class FolderAdapter implements FolderListener {
public void folderCreated(FolderEvent e) {}
public void folderRenamed(FolderEvent e) {}
public void folderDeleted(FolderEvent e) {}
}
@@ -0,0 +1,167 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
import javax.mail.*;
/**
* This class models Folder <em>existence</em> events. FolderEvents are
* delivered to FolderListeners registered on the affected Folder as
* well as the containing Store. <p>
*
* Service providers vary widely in their ability to notify clients of
* these events. At a minimum, service providers must notify listeners
* registered on the same Store or Folder object on which the operation
* occurs. Service providers may also notify listeners when changes
* are made through operations on other objects in the same virtual
* machine, or by other clients in the same or other hosts. Such
* notifications are not required and are typically not supported
* by mail protocols (including IMAP).
*
* @author John Mani
* @author Bill Shannon
*/
public class FolderEvent extends MailEvent {
/** The folder was created. */
public static final int CREATED = 1;
/** The folder was deleted. */
public static final int DELETED = 2;
/** The folder was renamed. */
public static final int RENAMED = 3;
/**
* The event type.
*
* @serial
*/
protected int type;
/**
* The folder the event occurred on.
*/
transient protected Folder folder;
/**
* The folder that represents the new name, in case of a RENAMED event.
*
* @since JavaMail 1.1
*/
transient protected Folder newFolder;
private static final long serialVersionUID = 5278131310563694307L;
/**
* Constructor. <p>
*
* @param source The source of the event
* @param folder The affected folder
* @param type The event type
*/
public FolderEvent(Object source, Folder folder, int type) {
this(source, folder, folder, type);
}
/**
* Constructor. Use for RENAMED events.
*
* @param source The source of the event
* @param oldFolder The folder that is renamed
* @param newFolder The folder that represents the new name
* @param type The event type
* @since JavaMail 1.1
*/
public FolderEvent(Object source, Folder oldFolder,
Folder newFolder, int type) {
super(source);
this.folder = oldFolder;
this.newFolder = newFolder;
this.type = type;
}
/**
* Return the type of this event.
*
* @return type
*/
public int getType() {
return type;
}
/**
* Return the affected folder.
*
* @return the affected folder
* @see #getNewFolder
*/
public Folder getFolder() {
return folder;
}
/**
* If this event indicates that a folder is renamed, (i.e, the event type
* is RENAMED), then this method returns the Folder object representing the
* new name. <p>
*
* The <code>getFolder()</code> method returns the folder that is renamed.
*
* @return Folder representing the new name.
* @see #getFolder
* @since JavaMail 1.1
*/
public Folder getNewFolder() {
return newFolder;
}
/**
* Invokes the appropriate FolderListener method
*/
public void dispatch(Object listener) {
if (type == CREATED)
((FolderListener)listener).folderCreated(this);
else if (type == DELETED)
((FolderListener)listener).folderDeleted(this);
else if (type == RENAMED)
((FolderListener)listener).folderRenamed(this);
}
}
@@ -0,0 +1,66 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
/**
* This is the Listener interface for Folder events.
*
* @author John Mani
*/
public interface FolderListener extends java.util.EventListener {
/**
* Invoked when a Folder is created.
*/
public void folderCreated(FolderEvent e);
/**
* Invoked when a folder is deleted.
*/
public void folderDeleted(FolderEvent e);
/**
* Invoked when a folder is renamed.
*/
public void folderRenamed(FolderEvent e);
}
@@ -0,0 +1,63 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.EventObject;
/**
* Common base class for mail events, defining the dispatch method.
*
* @author Bill Shannon
*/
public abstract class MailEvent extends EventObject {
private static final long serialVersionUID = 1846275636325456631L;
public MailEvent(Object source) {
super(source);
}
/**
* This method invokes the appropriate method on a listener for
* this event. Subclasses provide the implementation.
*/
public abstract void dispatch(Object listener);
}
@@ -0,0 +1,107 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
import javax.mail.*;
/**
* This class models Message change events.
*
* @author John Mani
*/
public class MessageChangedEvent extends MailEvent {
/** The message's flags changed. */
public static final int FLAGS_CHANGED = 1;
/** The message's envelope (headers, but not body) changed. */
public static final int ENVELOPE_CHANGED = 2;
/**
* The event type.
*
* @serial
*/
protected int type;
/**
* The message that changed.
*/
transient protected Message msg;
private static final long serialVersionUID = -4974972972105535108L;
/**
* Constructor.
* @param source The folder that owns the message
* @param type The change type
* @param msg The changed message
*/
public MessageChangedEvent(Object source, int type, Message msg) {
super(source);
this.msg = msg;
this.type = type;
}
/**
* Return the type of this event.
* @return type
*/
public int getMessageChangeType() {
return type;
}
/**
* Return the changed Message.
* @return the message
*/
public Message getMessage() {
return msg;
}
/**
* Invokes the appropriate MessageChangedListener method.
*/
public void dispatch(Object listener) {
((MessageChangedListener)listener).messageChanged(this);
}
}
@@ -0,0 +1,59 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
/**
* This is the Listener interface for MessageChanged events
*
* @author John Mani
*/
public interface MessageChangedListener extends java.util.EventListener {
/**
* Invoked when a message is changed. The change-type specifies
* what changed.
* @see MessageChangedEvent#FLAGS_CHANGED
* @see MessageChangedEvent#ENVELOPE_CHANGED
*/
public void messageChanged(MessageChangedEvent e);
}
@@ -0,0 +1,54 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
/**
* The adapter which receives MessageCount events.
* The methods in this class are empty; this class is provided as a
* convenience for easily creating listeners by extending this class
* and overriding only the methods of interest.
*
* @author John Mani
*/
public abstract class MessageCountAdapter implements MessageCountListener {
public void messagesAdded(MessageCountEvent e) {}
public void messagesRemoved(MessageCountEvent e) {}
}
@@ -0,0 +1,154 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
import javax.mail.*;
/**
* This class notifies changes in the number of messages in a folder. <p>
*
* Note that some folder types may only deliver MessageCountEvents at
* certain times or after certain operations. IMAP in particular will
* only notify the client of MessageCountEvents when a client issues a
* new command.
* Refer to RFC 2060 <A HREF="http://www.ietf.org/rfc/rfc2060.txt">
* http://www.ietf.org/rfc/rfc2060.txt</A> for details.
* A client may want "poll" the folder by occasionally calling the
* <code>getMessageCount</code> or <code>isConnected</code> methods
* to solicit any such notifications.
*
* @author John Mani
*/
public class MessageCountEvent extends MailEvent {
/** The messages were added to their folder */
public static final int ADDED = 1;
/** The messages were removed from their folder */
public static final int REMOVED = 2;
/**
* The event type.
*
* @serial
*/
protected int type;
/**
* If true, this event is the result of an explicit
* expunge by this client, and the messages in this
* folder have been renumbered to account for this.
* If false, this event is the result of an expunge
* by external sources.
*
* @serial
*/
protected boolean removed;
/**
* The messages.
*/
transient protected Message[] msgs;
private static final long serialVersionUID = -7447022340837897369L;
/**
* Constructor.
* @param folder The containing folder
* @param type The event type
* @param removed If true, this event is the result of an explicit
* expunge by this client, and the messages in this
* folder have been renumbered to account for this.
* If false, this event is the result of an expunge
* by external sources.
*
* @param msgs The messages added/removed
*/
public MessageCountEvent(Folder folder, int type,
boolean removed, Message[] msgs) {
super(folder);
this.type = type;
this.removed = removed;
this.msgs = msgs;
}
/**
* Return the type of this event.
* @return type
*/
public int getType() {
return type;
}
/**
* Indicates whether this event is the result of an explicit
* expunge by this client, or due to an expunge from external
* sources. If <code>true</code>, this event is due to an
* explicit expunge and hence all remaining messages in this
* folder have been renumbered. If <code>false</code>, this event
* is due to an external expunge. <p>
*
* Note that this method is valid only if the type of this event
* is <code>REMOVED</code>
*/
public boolean isRemoved() {
return removed;
}
/**
* Return the array of messages added or removed.
* @return array of messages
*/
public Message[] getMessages() {
return msgs;
}
/**
* Invokes the appropriate MessageCountListener method.
*/
public void dispatch(Object listener) {
if (type == ADDED)
((MessageCountListener)listener).messagesAdded(this);
else // REMOVED
((MessageCountListener)listener).messagesRemoved(this);
}
}
@@ -0,0 +1,61 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
/**
* This is the Listener interface for MessageCount events.
*
* @author John Mani
*/
public interface MessageCountListener extends java.util.EventListener {
/**
* Invoked when messages are added into a folder.
*/
public void messagesAdded(MessageCountEvent e);
/**
* Invoked when messages are removed (expunged) from a folder.
*/
public void messagesRemoved(MessageCountEvent e);
}
@@ -0,0 +1,119 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
import javax.mail.*;
/**
* This class models notifications from the Store connection. These
* notifications can be ALERTS or NOTICES. ALERTS must be presented
* to the user in a fashion that calls the user's attention to the
* message.
*
* @author John Mani
*/
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 event type.
*
* @serial
*/
protected int type;
/**
* The message text to be presented to the user.
*
* @serial
*/
protected String message;
private static final long serialVersionUID = 1938704919992515330L;
/**
* Constructor.
* @param store The source Store
*/
public StoreEvent(Store store, int type, String message) {
super(store);
this.type = type;
this.message = message;
}
/**
* Return the type of this event.
*
* @return type
* @see #ALERT
* @see #NOTICE
*/
public int getMessageType() {
return type;
}
/**
* Get the message from the Store.
*
* @return message from the Store
*/
public String getMessage() {
return message;
}
/**
* Invokes the appropriate StoreListener method.
*/
public void dispatch(Object listener) {
((StoreListener)listener).notification(this);
}
}
@@ -0,0 +1,60 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
/**
* This is the Listener interface for Store Notifications.
*
* @author John Mani
*/
public interface StoreListener extends java.util.EventListener {
/**
* Invoked when the Store generates a notification event.
*
* @see StoreEvent#ALERT
* @see StoreEvent#NOTICE
*/
public void notification(StoreEvent e);
}
@@ -0,0 +1,55 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
/**
* The adapter which receives Transport events.
* The methods in this class are empty; this class is provided as a
* convenience for easily creating listeners by extending this class
* and overriding only the methods of interest.
*
* @author John Mani
*/
public abstract class TransportAdapter implements TransportListener {
public void messageDelivered(TransportEvent e) {}
public void messageNotDelivered(TransportEvent e) {}
public void messagePartiallyDelivered(TransportEvent e) {}
}
@@ -0,0 +1,166 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
import javax.mail.*;
/**
* This class models Transport events.
*
* @author John Mani
* @author Max Spivak
*
* @see javax.mail.Transport
* @see javax.mail.event.TransportListener
*/
public class TransportEvent extends MailEvent {
/**
* Message has been successfully delivered to all recipients by the
* transport firing this event. validSent[] contains all the addresses
* this transport sent to successfully. validUnsent[] and invalid[]
* should be null,
*/
public static final int MESSAGE_DELIVERED = 1;
/**
* Message was not sent for some reason. validSent[] should be null.
* validUnsent[] may have addresses that are valid (but the message
* wasn't sent to them). invalid[] should likely contain invalid addresses.
*/
public static final int MESSAGE_NOT_DELIVERED = 2;
/**
* Message was successfully sent to some recipients but not to all.
* validSent[] holds addresses of recipients to whom the message was sent.
* validUnsent[] holds valid addresses to which the message was not sent.
* invalid[] holds invalid addresses, if any.
*/
public static final int MESSAGE_PARTIALLY_DELIVERED = 3;
/**
* The event type.
*
* @serial
*/
protected int type;
transient protected Address[] validSent;
transient protected Address[] validUnsent;
transient protected Address[] invalid;
transient protected Message msg;
private static final long serialVersionUID = -4729852364684273073L;
/**
* Constructor.
* @param transport The Transport object
*/
public TransportEvent(Transport transport, int type, Address[] validSent,
Address[] validUnsent, Address[] invalid,
Message msg) {
super(transport);
this.type = type;
this.validSent = validSent;
this.validUnsent = validUnsent;
this.invalid = invalid;
this.msg = msg;
}
/**
* Return the type of this event.
* @return type
*/
public int getType() {
return type;
}
/**
* Return the addresses to which this message was sent succesfully.
* @return Addresses to which the message was sent successfully or null
*/
public Address[] getValidSentAddresses() {
return validSent;
}
/**
* Return the addresses that are valid but to which this message
* was not sent.
* @return Addresses that are valid but to which the message was
* not sent successfully or null
*/
public Address[] getValidUnsentAddresses() {
return validUnsent;
}
/**
* Return the addresses to which this message could not be sent.
* @return Addresses to which the message sending failed or null
*/
public Address[] getInvalidAddresses() {
return invalid;
}
/**
* Get the Message object associated with this Transport Event.
*
* @return the Message object
* @since JavaMail 1.2
*/
public Message getMessage() {
return msg;
}
/**
* Invokes the appropriate TransportListener method.
*/
public void dispatch(Object listener) {
if (type == MESSAGE_DELIVERED)
((TransportListener)listener).messageDelivered(this);
else if (type == MESSAGE_NOT_DELIVERED)
((TransportListener)listener).messageNotDelivered(this);
else // MESSAGE_PARTIALLY_DELIVERED
((TransportListener)listener).messagePartiallyDelivered(this);
}
}
@@ -0,0 +1,76 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.event;
import java.util.*;
/**
* This is the Listener interface for Transport events
*
* @author John Mani
* @author Max Spivak
*
* @see javax.mail.Transport
* @see javax.mail.event.TransportEvent
*/
public interface TransportListener extends java.util.EventListener {
/**
* Invoked when a Message is succesfully delivered.
* @param e TransportEvent
*/
public void messageDelivered(TransportEvent e);
/**
* Invoked when a Message is not delivered.
* @param e TransportEvent
* @see TransportEvent
*/
public void messageNotDelivered(TransportEvent e);
/**
* Invoked when a Message is partially delivered.
* @param e TransportEvent
* @see TransportEvent
*/
public void messagePartiallyDelivered(TransportEvent e);
}
@@ -0,0 +1,54 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can
obtain a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
or packager/legal/LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.
When distributing the software, include this License Header Notice in each
file and include the License file at packager/legal/LICENSE.txt.
GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.
Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"
Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->
</HEAD>
<BODY BGCOLOR="white">
Listeners and events for the JavaMail API.
This package defines listener classes and event classes used by the classes
defined in the <code>javax.mail</code> package.
</BODY>
</HTML>
@@ -0,0 +1,130 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
/**
* The exception thrown when a wrongly formatted address is encountered.
*
* @author Bill Shannon
* @author Max Spivak
*/
public class AddressException extends ParseException {
/**
* The string being parsed.
*
* @serial
*/
protected String ref = null;
/**
* The index in the string where the error occurred, or -1 if not known.
*
* @serial
*/
protected int pos = -1;
private static final long serialVersionUID = 9134583443539323120L;
/**
* Constructs an AddressException with no detail message.
*/
public AddressException() {
super();
}
/**
* Constructs an AddressException with the specified detail message.
* @param s the detail message
*/
public AddressException(String s) {
super(s);
}
/**
* Constructs an AddressException with the specified detail message
* and reference info.
*
* @param s the detail message
*/
public AddressException(String s, String ref) {
super(s);
this.ref = ref;
}
/**
* Constructs an AddressException with the specified detail message
* and reference info.
*
* @param s the detail message
*/
public AddressException(String s, String ref, int pos) {
super(s);
this.ref = ref;
this.pos = pos;
}
/**
* Get the string that was being parsed when the error was detected
* (null if not relevant).
*/
public String getRef() {
return ref;
}
/**
* Get the position with the reference string where the error was
* detected (-1 if not relevant).
*/
public int getPos() {
return pos;
}
public String toString() {
String s = super.toString();
if (ref == null)
return s;
s += " in string ``" + ref + "''";
if (pos < 0)
return s;
return s + " at position " + pos;
}
}
@@ -0,0 +1,192 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import javax.mail.*;
import java.util.*;
import java.io.*;
/**
* This class represents a MIME ContentDisposition value. It provides
* methods to parse a ContentDisposition string into individual components
* and to generate a MIME style ContentDisposition string.
*
* @author John Mani
*/
public class ContentDisposition {
private String disposition; // disposition
private ParameterList list; // parameter list
/**
* No-arg Constructor.
*/
public ContentDisposition() { }
/**
* Constructor.
*
* @param disposition disposition
* @param list ParameterList
* @since JavaMail 1.2
*/
public ContentDisposition(String disposition, ParameterList list) {
this.disposition = disposition;
this.list = list;
}
/**
* Constructor that takes a ContentDisposition string. The String
* is parsed into its constituents: dispostion and parameters.
* A ParseException is thrown if the parse fails.
*
* @param s the ContentDisposition string.
* @exception ParseException if the parse fails.
* @since JavaMail 1.2
*/
public ContentDisposition(String s) throws ParseException {
HeaderTokenizer h = new HeaderTokenizer(s, HeaderTokenizer.MIME);
HeaderTokenizer.Token tk;
// First "disposition" ..
tk = h.next();
if (tk.getType() != HeaderTokenizer.Token.ATOM)
throw new ParseException("Expected disposition, got " +
tk.getValue());
disposition = tk.getValue();
// Then parameters ..
String rem = h.getRemainder();
if (rem != null)
list = new ParameterList(rem);
}
/**
* Return the disposition value.
* @return the disposition
* @since JavaMail 1.2
*/
public String getDisposition() {
return disposition;
}
/**
* Return the specified parameter value. Returns <code>null</code>
* if this parameter is absent.
* @return parameter value
* @since JavaMail 1.2
*/
public String getParameter(String name) {
if (list == null)
return null;
return list.get(name);
}
/**
* Return a ParameterList object that holds all the available
* parameters. Returns null if no parameters are available.
*
* @return ParameterList
* @since JavaMail 1.2
*/
public ParameterList getParameterList() {
return list;
}
/**
* Set the disposition. Replaces the existing disposition.
* @param disposition the disposition
* @since JavaMail 1.2
*/
public void setDisposition(String disposition) {
this.disposition = disposition;
}
/**
* Set the specified parameter. If this parameter already exists,
* it is replaced by this new value.
*
* @param name parameter name
* @param value parameter value
* @since JavaMail 1.2
*/
public void setParameter(String name, String value) {
if (list == null)
list = new ParameterList();
list.set(name, value);
}
/**
* Set a new ParameterList.
* @param list ParameterList
* @since JavaMail 1.2
*/
public void setParameterList(ParameterList list) {
this.list = list;
}
/**
* Retrieve a RFC2045 style string representation of
* this ContentDisposition. Returns an empty string if
* the conversion failed.
*
* @return RFC2045 style string
* @since JavaMail 1.2
*/
public String toString() {
if (disposition == null)
return "";
if (list == null)
return disposition;
StringBuffer sb = new StringBuffer(disposition);
// append the parameter list
// use the length of the string buffer + the length of
// the header name formatted as follows "Content-Disposition: "
sb.append(list.toString(sb.length() + 21));
return sb.toString();
}
}
@@ -0,0 +1,285 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import javax.mail.*;
import java.util.*;
import java.io.*;
/**
* This class represents a MIME Content-Type value. It provides
* methods to parse a Content-Type string into individual components
* and to generate a MIME style Content-Type string.
*
* @author John Mani
*/
public class ContentType {
private String primaryType; // primary type
private String subType; // subtype
private ParameterList list; // parameter list
/**
* No-arg Constructor.
*/
public ContentType() { }
/**
* Constructor.
*
* @param primaryType primary type
* @param subType subType
* @param list ParameterList
*/
public ContentType(String primaryType, String subType,
ParameterList list) {
this.primaryType = primaryType;
this.subType = subType;
this.list = list;
}
/**
* Constructor that takes a Content-Type string. The String
* is parsed into its constituents: primaryType, subType
* and parameters. A ParseException is thrown if the parse fails.
*
* @param s the Content-Type string.
* @exception ParseException if the parse fails.
*/
public ContentType(String s) throws ParseException {
HeaderTokenizer h = new HeaderTokenizer(s, HeaderTokenizer.MIME);
HeaderTokenizer.Token tk;
// First "type" ..
tk = h.next();
if (tk.getType() != HeaderTokenizer.Token.ATOM)
throw new ParseException("Expected MIME type, got " +
tk.getValue());
primaryType = tk.getValue();
// The '/' separator ..
tk = h.next();
if ((char)tk.getType() != '/')
throw new ParseException("Expected '/', got " + tk.getValue());
// Then "subType" ..
tk = h.next();
if (tk.getType() != HeaderTokenizer.Token.ATOM)
throw new ParseException("Expected MIME subtype, got " +
tk.getValue());
subType = tk.getValue();
// Finally parameters ..
String rem = h.getRemainder();
if (rem != null)
list = new ParameterList(rem);
}
/**
* Return the primary type.
* @return the primary type
*/
public String getPrimaryType() {
return primaryType;
}
/**
* Return the subType.
* @return the subType
*/
public String getSubType() {
return subType;
}
/**
* Return the MIME type string, without the parameters.
* The returned value is basically the concatenation of
* the primaryType, the '/' character and the secondaryType.
*
* @return the type
*/
public String getBaseType() {
return primaryType + '/' + subType;
}
/**
* Return the specified parameter value. Returns <code>null</code>
* if this parameter is absent.
* @return parameter value
*/
public String getParameter(String name) {
if (list == null)
return null;
return list.get(name);
}
/**
* Return a ParameterList object that holds all the available
* parameters. Returns null if no parameters are available.
*
* @return ParameterList
*/
public ParameterList getParameterList() {
return list;
}
/**
* Set the primary type. Overrides existing primary type.
* @param primaryType primary type
*/
public void setPrimaryType(String primaryType) {
this.primaryType = primaryType;
}
/**
* Set the subType. Replaces the existing subType.
* @param subType the subType
*/
public void setSubType(String subType) {
this.subType = subType;
}
/**
* Set the specified parameter. If this parameter already exists,
* it is replaced by this new value.
*
* @param name parameter name
* @param value parameter value
*/
public void setParameter(String name, String value) {
if (list == null)
list = new ParameterList();
list.set(name, value);
}
/**
* Set a new ParameterList.
* @param list ParameterList
*/
public void setParameterList(ParameterList list) {
this.list = list;
}
/**
* Retrieve a RFC2045 style string representation of
* this Content-Type. Returns an empty string if
* the conversion failed.
*
* @return RFC2045 style string
*/
public String toString() {
if (primaryType == null || subType == null) // need both
return "";
StringBuffer sb = new StringBuffer();
sb.append(primaryType).append('/').append(subType);
if (list != null)
// append the parameter list
// use the length of the string buffer + the length of
// the header name formatted as follows "Content-Type: "
sb.append(list.toString(sb.length() + 14));
return sb.toString();
}
/**
* Match with the specified ContentType object. This method
* compares <strong>only the <code>primaryType</code> and
* <code>subType</code> </strong>. The parameters of both operands
* are ignored. <p>
*
* For example, this method will return <code>true</code> when
* comparing the ContentTypes for <strong>"text/plain"</strong>
* and <strong>"text/plain; charset=foobar"</strong>.
*
* If the <code>subType</code> of either operand is the special
* character '*', then the subtype is ignored during the match.
* For example, this method will return <code>true</code> when
* comparing the ContentTypes for <strong>"text/plain"</strong>
* and <strong>"text/*" </strong>
*
* @param cType ContentType to compare this against
*/
public boolean match(ContentType cType) {
// Match primaryType
if (!primaryType.equalsIgnoreCase(cType.getPrimaryType()))
return false;
String sType = cType.getSubType();
// If either one of the subTypes is wildcarded, return true
if ((subType.charAt(0) == '*') || (sType.charAt(0) == '*'))
return true;
// Match subType
if (!subType.equalsIgnoreCase(sType))
return false;
return true;
}
/**
* Match with the specified content-type string. This method
* compares <strong>only the <code>primaryType</code> and
* <code>subType</code> </strong>.
* The parameters of both operands are ignored. <p>
*
* For example, this method will return <code>true</code> when
* comparing the ContentType for <strong>"text/plain"</strong>
* with <strong>"text/plain; charset=foobar"</strong>.
*
* If the <code>subType</code> of either operand is the special
* character '*', then the subtype is ignored during the match.
* For example, this method will return <code>true</code> when
* comparing the ContentType for <strong>"text/plain"</strong>
* with <strong>"text/*" </strong>
*/
public boolean match(String s) {
try {
return match(new ContentType(s));
} catch (ParseException pex) {
return false;
}
}
}
@@ -0,0 +1,489 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import java.util.*;
/**
* This class tokenizes RFC822 and MIME headers into the basic
* symbols specified by RFC822 and MIME. <p>
*
* This class handles folded headers (ie headers with embedded
* CRLF SPACE sequences). The folds are removed in the returned
* tokens.
*
* @author John Mani
* @author Bill Shannon
*/
public class HeaderTokenizer {
/**
* The Token class represents tokens returned by the
* HeaderTokenizer.
*/
public static class Token {
private int type;
private String value;
/**
* Token type indicating an ATOM.
*/
public static final int ATOM = -1;
/**
* Token type indicating a quoted string. The value
* field contains the string without the quotes.
*/
public static final int QUOTEDSTRING = -2;
/**
* Token type indicating a comment. The value field
* contains the comment string without the comment
* start and end symbols.
*/
public static final int COMMENT = -3;
/**
* Token type indicating end of input.
*/
public static final int EOF = -4;
/**
* Constructor.
* @param type Token type
* @param value Token value
*/
public Token(int type, String value) {
this.type = type;
this.value = value;
}
/**
* Return the type of the token. If the token represents a
* delimiter or a control character, the type is that character
* itself, converted to an integer. Otherwise, it's value is
* one of the following:
* <ul>
* <li><code>ATOM</code> A sequence of ASCII characters
* delimited by either SPACE, CTL, "(", <"> or the
* specified SPECIALS
* <li><code>QUOTEDSTRING</code> A sequence of ASCII characters
* within quotes
* <li><code>COMMENT</code> A sequence of ASCII characters
* within "(" and ")".
* <li><code>EOF</code> End of header
* </ul>
*/
public int getType() {
return type;
}
/**
* Returns the value of the token just read. When the current
* token is a quoted string, this field contains the body of the
* string, without the quotes. When the current token is a comment,
* this field contains the body of the comment.
*
* @return token value
*/
public String getValue() {
return value;
}
}
private String string; // the string to be tokenized
private boolean skipComments; // should comments be skipped ?
private String delimiters; // delimiter string
private int currentPos; // current parse position
private int maxPos; // string length
private int nextPos; // track start of next Token for next()
private int peekPos; // track start of next Token for peek()
/**
* RFC822 specials
*/
public final static String RFC822 = "()<>@,;:\\\"\t .[]";
/**
* MIME specials
*/
public final static String MIME = "()<>@,;:\\\"\t []/?=";
// The EOF Token
private final static Token EOFToken = new Token(Token.EOF, null);
/**
* Constructor that takes a rfc822 style header.
*
* @param header The rfc822 header to be tokenized
* @param delimiters Set of delimiter characters
* to be used to delimit ATOMS. These
* are usually <code>RFC822</code> or
* <code>MIME</code>
* @param skipComments If true, comments are skipped and
* not returned as tokens
*/
public HeaderTokenizer(String header, String delimiters,
boolean skipComments) {
string = (header == null) ? "" : header; // paranoia ?!
this.skipComments = skipComments;
this.delimiters = delimiters;
currentPos = nextPos = peekPos = 0;
maxPos = string.length();
}
/**
* Constructor. Comments are ignored and not returned as tokens
*
* @param header The header that is tokenized
* @param delimiters The delimiters to be used
*/
public HeaderTokenizer(String header, String delimiters) {
this(header, delimiters, true);
}
/**
* Constructor. The RFC822 defined delimiters - RFC822 - are
* used to delimit ATOMS. Also comments are skipped and not
* returned as tokens
*/
public HeaderTokenizer(String header) {
this(header, RFC822);
}
/**
* Parses the next token from this String. <p>
*
* Clients sit in a loop calling next() to parse successive
* tokens until an EOF Token is returned.
*
* @return the next Token
* @exception ParseException if the parse fails
*/
public Token next() throws ParseException {
return next('\0', false);
}
/**
* Parses the next token from this String.
* If endOfAtom is not NUL, the token extends until the
* endOfAtom character is seen, or to the end of the header.
* This method is useful when parsing headers that don't
* obey the MIME specification, e.g., by failing to quote
* parameter values that contain spaces.
*
* @param endOfAtom if not NUL, character marking end of token
* @return the next Token
* @exception ParseException if the parse fails
* @since JavaMail 1.5
*/
public Token next(char endOfAtom) throws ParseException {
return next(endOfAtom, false);
}
/**
* Parses the next token from this String.
* endOfAtom is handled as above. If keepEscapes is true,
* any backslash escapes are preserved in the returned string.
* This method is useful when parsing headers that don't
* obey the MIME specification, e.g., by failing to escape
* backslashes in the filename parameter.
*
* @param endOfAtom if not NUL, character marking end of token
* @param keepEscapes keep all backslashes in returned string?
* @return the next Token
* @exception ParseException if the parse fails
* @since JavaMail 1.5
*/
public Token next(char endOfAtom, boolean keepEscapes)
throws ParseException {
Token tk;
currentPos = nextPos; // setup currentPos
tk = getNext(endOfAtom, keepEscapes);
nextPos = peekPos = currentPos; // update currentPos and peekPos
return tk;
}
/**
* Peek at the next token, without actually removing the token
* from the parse stream. Invoking this method multiple times
* will return successive tokens, until <code>next()</code> is
* called. <p>
*
* @return the next Token
* @exception ParseException if the parse fails
*/
public Token peek() throws ParseException {
Token tk;
currentPos = peekPos; // setup currentPos
tk = getNext('\0', false);
peekPos = currentPos; // update peekPos
return tk;
}
/**
* Return the rest of the Header.
*
* @return String rest of header. null is returned if we are
* already at end of header
*/
public String getRemainder() {
return string.substring(nextPos);
}
/*
* Return the next token starting from 'currentPos'. After the
* parse, 'currentPos' is updated to point to the start of the
* next token.
*/
private Token getNext(char endOfAtom, boolean keepEscapes)
throws ParseException {
// If we're already at end of string, return EOF
if (currentPos >= maxPos)
return EOFToken;
// Skip white-space, position currentPos beyond the space
if (skipWhiteSpace() == Token.EOF)
return EOFToken;
char c;
int start;
boolean filter = false;
c = string.charAt(currentPos);
// Check or Skip comments and position currentPos
// beyond the comment
while (c == '(') {
// Parsing comment ..
int nesting;
for (start = ++currentPos, nesting = 1;
nesting > 0 && currentPos < maxPos;
currentPos++) {
c = string.charAt(currentPos);
if (c == '\\') { // Escape sequence
currentPos++; // skip the escaped character
filter = true;
} else if (c == '\r')
filter = true;
else if (c == '(')
nesting++;
else if (c == ')')
nesting--;
}
if (nesting != 0)
throw new ParseException("Unbalanced comments");
if (!skipComments) {
// Return the comment, if we are asked to.
// Note that the comment start & end markers are ignored.
String s;
if (filter) // need to go thru the token again.
s = filterToken(string, start, currentPos-1, keepEscapes);
else
s = string.substring(start,currentPos-1);
return new Token(Token.COMMENT, s);
}
// Skip any whitespace after the comment.
if (skipWhiteSpace() == Token.EOF)
return EOFToken;
c = string.charAt(currentPos);
}
// Check for quoted-string and position currentPos
// beyond the terminating quote
if (c == '"') {
currentPos++; // skip initial quote
return collectString('"', keepEscapes);
}
// Check for SPECIAL or CTL
if (c < 040 || c >= 0177 || delimiters.indexOf(c) >= 0) {
if (endOfAtom > 0 && c != endOfAtom) {
// not expecting a special character here,
// pretend it's a quoted string
return collectString(endOfAtom, keepEscapes);
}
currentPos++; // re-position currentPos
char ch[] = new char[1];
ch[0] = c;
return new Token((int)c, new String(ch));
}
// Check for ATOM
for (start = currentPos; currentPos < maxPos; currentPos++) {
c = string.charAt(currentPos);
// ATOM is delimited by either SPACE, CTL, "(", <">
// or the specified SPECIALS
if (c < 040 || c >= 0177 || c == '(' || c == ' ' ||
c == '"' || delimiters.indexOf(c) >= 0) {
if (endOfAtom > 0 && c != endOfAtom) {
// not the expected atom after all;
// back up and pretend it's a quoted string
currentPos = start;
return collectString(endOfAtom, keepEscapes);
}
break;
}
}
return new Token(Token.ATOM, string.substring(start, currentPos));
}
private Token collectString(char eos, boolean keepEscapes)
throws ParseException {
int start;
boolean filter = false;
for (start = currentPos; currentPos < maxPos; currentPos++) {
char c = string.charAt(currentPos);
if (c == '\\') { // Escape sequence
currentPos++;
filter = true;
} else if (c == '\r')
filter = true;
else if (c == eos) {
currentPos++;
String s;
if (filter)
s = filterToken(string, start, currentPos-1, keepEscapes);
else
s = string.substring(start, currentPos-1);
if (c != '"') { // not a real quoted string
s = trimWhiteSpace(s);
currentPos--; // back up before the eos char
}
return new Token(Token.QUOTEDSTRING, s);
}
}
// ran off the end of the string
// if we're looking for a matching quote, that's an error
if (eos == '"')
throw new ParseException("Unbalanced quoted string");
// otherwise, just return whatever's left
String s;
if (filter)
s = filterToken(string, start, currentPos, keepEscapes);
else
s = string.substring(start, currentPos);
s = trimWhiteSpace(s);
return new Token(Token.QUOTEDSTRING, s);
}
// Skip SPACE, HT, CR and NL
private int skipWhiteSpace() {
char c;
for (; currentPos < maxPos; currentPos++)
if (((c = string.charAt(currentPos)) != ' ') &&
(c != '\t') && (c != '\r') && (c != '\n'))
return currentPos;
return Token.EOF;
}
// Trim SPACE, HT, CR and NL from end of string
private static String trimWhiteSpace(String s) {
char c;
int i;
for (i = s.length() - 1; i >= 0; i--) {
if (((c = s.charAt(i)) != ' ') &&
(c != '\t') && (c != '\r') && (c != '\n'))
break;
}
if (i <= 0)
return "";
else
return s.substring(0, i + 1);
}
/* Process escape sequences and embedded LWSPs from a comment or
* quoted string.
*/
private static String filterToken(String s, int start, int end,
boolean keepEscapes) {
StringBuffer sb = new StringBuffer();
char c;
boolean gotEscape = false;
boolean gotCR = false;
for (int i = start; i < end; i++) {
c = s.charAt(i);
if (c == '\n' && gotCR) {
// This LF is part of an unescaped
// CRLF sequence (i.e, LWSP). Skip it.
gotCR = false;
continue;
}
gotCR = false;
if (!gotEscape) {
// Previous character was NOT '\'
if (c == '\\') // skip this character
gotEscape = true;
else if (c == '\r') // skip this character
gotCR = true;
else // append this character
sb.append(c);
} else {
// Previous character was '\'. So no need to
// bother with any special processing, just
// append this character. If keepEscapes is
// set, keep the backslash. IE6 fails to escape
// backslashes in quoted strings in HTTP headers,
// e.g., in the filename parameter.
if (keepEscapes)
sb.append('\\');
sb.append(c);
gotEscape = false;
}
}
return sb.toString();
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,609 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import java.io.*;
import java.util.*;
import javax.mail.*;
import com.sun.mail.util.LineInputStream;
import com.sun.mail.util.PropUtil;
/**
* InternetHeaders is a utility class that manages RFC822 style
* headers. Given an RFC822 format message stream, it reads lines
* until the blank line that indicates end of header. The input stream
* is positioned at the start of the body. The lines are stored
* within the object and can be extracted as either Strings or
* {@link javax.mail.Header} objects. <p>
*
* This class is mostly intended for service providers. MimeMessage
* and MimeBody use this class for holding their headers. <p>
*
* <hr> <strong>A note on RFC822 and MIME headers</strong><p>
*
* RFC822 and MIME header fields <strong>must</strong> contain only
* US-ASCII characters. If a header contains non US-ASCII characters,
* it must be encoded as per the rules in RFC 2047. The MimeUtility
* class provided in this package can be used to to achieve this.
* Callers of the <code>setHeader</code>, <code>addHeader</code>, and
* <code>addHeaderLine</code> methods are responsible for enforcing
* the MIME requirements for the specified headers. In addition, these
* header fields must be folded (wrapped) before being sent if they
* exceed the line length limitation for the transport (1000 bytes for
* SMTP). Received headers may have been folded. The application is
* responsible for folding and unfolding headers as appropriate. <p>
*
* The current implementation supports the System property
* <code>mail.mime.ignorewhitespacelines</code>, which if set to true
* will cause a line containing only whitespace to be considered
* a blank line terminating the header.
*
* @see javax.mail.internet.MimeUtility
* @author John Mani
* @author Bill Shannon
*/
public class InternetHeaders {
private static final boolean ignoreWhitespaceLines =
PropUtil.getBooleanSystemProperty("mail.mime.ignorewhitespacelines",
false);
/**
* An individual internet header. This class is only used by
* subclasses of InternetHeaders. <p>
*
* An InternetHeader object with a null value is used as a placeholder
* for headers of that name, to preserve the order of headers.
* A placeholder InternetHeader object with a name of ":" marks
* the location in the list of headers where new headers are
* added by default.
*
* @since JavaMail 1.4
*/
protected static final class InternetHeader extends Header {
/*
* Note that the value field from the superclass
* isn't used in this class. We extract the value
* from the line field as needed. We store the line
* rather than just the value to ensure that we can
* get back the exact original line, with the original
* whitespace, etc.
*/
String line; // the entire RFC822 header "line",
// or null if placeholder
/**
* Constructor that takes a line and splits out
* the header name.
*/
public InternetHeader(String l) {
super("", ""); // XXX - we'll change it later
int i = l.indexOf(':');
if (i < 0) {
// should never happen
name = l.trim();
} else {
name = l.substring(0, i).trim();
}
line = l;
}
/**
* Constructor that takes a header name and value.
*/
public InternetHeader(String n, String v) {
super(n, "");
if (v != null)
line = n + ": " + v;
else
line = null;
}
/**
* Return the "value" part of the header line.
*/
public String getValue() {
int i = line.indexOf(':');
if (i < 0)
return line;
// skip whitespace after ':'
int j;
for (j = i + 1; j < line.length(); j++) {
char c = line.charAt(j);
if (!(c == ' ' || c == '\t' || c == '\r' || c == '\n'))
break;
}
return line.substring(j);
}
}
/*
* The enumeration object used to enumerate an
* InternetHeaders object. Can return
* either a String or a Header object.
*/
static class matchEnum implements Enumeration {
private Iterator e; // enum object of headers List
// XXX - is this overkill? should we step through in index
// order instead?
private String names[]; // names to match, or not
private boolean match; // return matching headers?
private boolean want_line; // return header lines?
private InternetHeader next_header; // the next header to be returned
/*
* Constructor. Initialize the enumeration for the entire
* List of headers, the set of headers, whether to return
* matching or non-matching headers, and whether to return
* header lines or Header objects.
*/
matchEnum(List v, String n[], boolean m, boolean l) {
e = v.iterator();
names = n;
match = m;
want_line = l;
next_header = null;
}
/*
* Any more elements in this enumeration?
*/
public boolean hasMoreElements() {
// if necessary, prefetch the next matching header,
// and remember it.
if (next_header == null)
next_header = nextMatch();
return next_header != null;
}
/*
* Return the next element.
*/
public Object nextElement() {
if (next_header == null)
next_header = nextMatch();
if (next_header == null)
throw new NoSuchElementException("No more headers");
InternetHeader h = next_header;
next_header = null;
if (want_line)
return h.line;
else
return new Header(h.getName(), h.getValue());
}
/*
* Return the next Header object according to the match
* criteria, or null if none left.
*/
private InternetHeader nextMatch() {
next:
while (e.hasNext()) {
InternetHeader h = (InternetHeader)e.next();
// skip "place holder" headers
if (h.line == null)
continue;
// if no names to match against, return appropriately
if (names == null)
return match ? null : h;
// check whether this header matches any of the names
for (int i = 0; i < names.length; i++) {
if (names[i].equalsIgnoreCase(h.getName())) {
if (match)
return h;
else
// found a match, but we're
// looking for non-matches.
// try next header.
continue next;
}
}
// found no matches. if that's what we wanted, return it.
if (!match)
return h;
}
return null;
}
}
/**
* The actual list of Headers, including placeholder entries.
* Placeholder entries are Headers with a null value and
* are never seen by clients of the InternetHeaders class.
* Placeholder entries are used to keep track of the preferred
* order of headers. Headers are never actually removed from
* the list, they're converted into placeholder entries.
* New headers are added after existing headers of the same name
* (or before in the case of <code>Received</code> and
* <code>Return-Path</code> headers). If no existing header
* or placeholder for the header is found, new headers are
* added after the special placeholder with the name ":".
*
* @since JavaMail 1.4
*/
protected List headers;
/**
* Create an empty InternetHeaders object. Placeholder entries
* are inserted to indicate the preferred order of headers.
*/
public InternetHeaders() {
headers = new ArrayList(40);
headers.add(new InternetHeader("Return-Path", null));
headers.add(new InternetHeader("Received", null));
headers.add(new InternetHeader("Resent-Date", null));
headers.add(new InternetHeader("Resent-From", null));
headers.add(new InternetHeader("Resent-Sender", null));
headers.add(new InternetHeader("Resent-To", null));
headers.add(new InternetHeader("Resent-Cc", null));
headers.add(new InternetHeader("Resent-Bcc", null));
headers.add(new InternetHeader("Resent-Message-Id", null));
headers.add(new InternetHeader("Date", null));
headers.add(new InternetHeader("From", null));
headers.add(new InternetHeader("Sender", null));
headers.add(new InternetHeader("Reply-To", null));
headers.add(new InternetHeader("To", null));
headers.add(new InternetHeader("Cc", null));
headers.add(new InternetHeader("Bcc", null));
headers.add(new InternetHeader("Message-Id", null));
headers.add(new InternetHeader("In-Reply-To", null));
headers.add(new InternetHeader("References", null));
headers.add(new InternetHeader("Subject", null));
headers.add(new InternetHeader("Comments", null));
headers.add(new InternetHeader("Keywords", null));
headers.add(new InternetHeader("Errors-To", null));
headers.add(new InternetHeader("MIME-Version", null));
headers.add(new InternetHeader("Content-Type", null));
headers.add(new InternetHeader("Content-Transfer-Encoding", null));
headers.add(new InternetHeader("Content-MD5", null));
headers.add(new InternetHeader(":", null));
headers.add(new InternetHeader("Content-Length", null));
headers.add(new InternetHeader("Status", null));
}
/**
* Read and parse the given RFC822 message stream till the
* blank line separating the header from the body. The input
* stream is left positioned at the start of the body. The
* header lines are stored internally. <p>
*
* For efficiency, wrap a BufferedInputStream around the actual
* input stream and pass it as the parameter. <p>
*
* No placeholder entries are inserted; the original order of
* the headers is preserved.
*
* @param is RFC822 input stream
*/
public InternetHeaders(InputStream is) throws MessagingException {
headers = new ArrayList(40);
load(is);
}
/**
* Read and parse the given RFC822 message stream till the
* blank line separating the header from the body. Store the
* header lines inside this InternetHeaders object. The order
* of header lines is preserved. <p>
*
* Note that the header lines are added into this InternetHeaders
* object, so any existing headers in this object will not be
* affected. Headers are added to the end of the existing list
* of headers, in order.
*
* @param is RFC822 input stream
*/
public void load(InputStream is) throws MessagingException {
// Read header lines until a blank line. It is valid
// to have BodyParts with no header lines.
String line;
LineInputStream lis = new LineInputStream(is);
String prevline = null; // the previous header line, as a string
// a buffer to accumulate the header in, when we know it's needed
StringBuffer lineBuffer = new StringBuffer();
try {
//while ((line = lis.readLine()) != null) {
do {
line = lis.readLine();
if (line != null &&
(line.startsWith(" ") || line.startsWith("\t"))) {
// continuation of header
if (prevline != null) {
lineBuffer.append(prevline);
prevline = null;
}
lineBuffer.append("\r\n");
lineBuffer.append(line);
} else {
// new header
if (prevline != null)
addHeaderLine(prevline);
else if (lineBuffer.length() > 0) {
// store previous header first
addHeaderLine(lineBuffer.toString());
lineBuffer.setLength(0);
}
prevline = line;
}
} while (line != null && !isEmpty(line));
} catch (IOException ioex) {
throw new MessagingException("Error in input stream", ioex);
}
}
/**
* Is this line an empty (blank) line?
*/
private static final boolean isEmpty(String line) {
return line.length() == 0 ||
(ignoreWhitespaceLines && line.trim().length() == 0);
}
/**
* Return all the values for the specified header. The
* values are String objects. Returns <code>null</code>
* if no headers with the specified name exist.
*
* @param name header name
* @return array of header values, or null if none
*/
public String[] getHeader(String name) {
Iterator e = headers.iterator();
// XXX - should we just step through in index order?
List v = new ArrayList(); // accumulate return values
while (e.hasNext()) {
InternetHeader h = (InternetHeader)e.next();
if (name.equalsIgnoreCase(h.getName()) && h.line != null) {
v.add(h.getValue());
}
}
if (v.size() == 0)
return (null);
// convert List to an array for return
String r[] = new String[v.size()];
r = (String[])v.toArray(r);
return (r);
}
/**
* Get all the headers for this header name, returned as a single
* String, with headers separated by the delimiter. If the
* delimiter is <code>null</code>, only the first header is
* returned. Returns <code>null</code>
* if no headers with the specified name exist.
*
* @param name header name
* @param delimiter delimiter
* @return the value fields for all headers with
* this name, or null if none
*/
public String getHeader(String name, String delimiter) {
String s[] = getHeader(name);
if (s == null)
return null;
if ((s.length == 1) || delimiter == null)
return s[0];
StringBuffer r = new StringBuffer(s[0]);
for (int i = 1; i < s.length; i++) {
r.append(delimiter);
r.append(s[i]);
}
return r.toString();
}
/**
* Change the first header line that matches name
* to have value, adding a new header if no existing header
* matches. Remove all matching headers but the first. <p>
*
* Note that RFC822 headers can only contain US-ASCII characters
*
* @param name header name
* @param value header value
*/
public void setHeader(String name, String value) {
boolean found = false;
for (int i = 0; i < headers.size(); i++) {
InternetHeader h = (InternetHeader)headers.get(i);
if (name.equalsIgnoreCase(h.getName())) {
if (!found) {
int j;
if (h.line != null && (j = h.line.indexOf(':')) >= 0) {
h.line = h.line.substring(0, j + 1) + " " + value;
// preserves capitalization, spacing
} else {
h.line = name + ": " + value;
}
found = true;
} else {
headers.remove(i);
i--; // have to look at i again
}
}
}
if (!found) {
addHeader(name, value);
}
}
/**
* Add a header with the specified name and value to the header list. <p>
*
* The current implementation knows about the preferred order of most
* well-known headers and will insert headers in that order. In
* addition, it knows that <code>Received</code> headers should be
* inserted in reverse order (newest before oldest), and that they
* should appear at the beginning of the headers, preceeded only by
* a possible <code>Return-Path</code> header. <p>
*
* Note that RFC822 headers can only contain US-ASCII characters.
*
* @param name header name
* @param value header value
*/
public void addHeader(String name, String value) {
int pos = headers.size();
boolean addReverse =
name.equalsIgnoreCase("Received") ||
name.equalsIgnoreCase("Return-Path");
if (addReverse)
pos = 0;
for (int i = headers.size() - 1; i >= 0; i--) {
InternetHeader h = (InternetHeader)headers.get(i);
if (name.equalsIgnoreCase(h.getName())) {
if (addReverse) {
pos = i;
} else {
headers.add(i + 1, new InternetHeader(name, value));
return;
}
}
// marker for default place to add new headers
if (!addReverse && h.getName().equals(":"))
pos = i;
}
headers.add(pos, new InternetHeader(name, value));
}
/**
* Remove all header entries that match the given name
* @param name header name
*/
public void removeHeader(String name) {
for (int i = 0; i < headers.size(); i++) {
InternetHeader h = (InternetHeader)headers.get(i);
if (name.equalsIgnoreCase(h.getName())) {
h.line = null;
//headers.remove(i);
//i--; // have to look at i again
}
}
}
/**
* Return all the headers as an Enumeration of
* {@link javax.mail.Header} objects.
*
* @return Header objects
*/
public Enumeration getAllHeaders() {
return (new matchEnum(headers, null, false, false));
}
/**
* Return all matching {@link javax.mail.Header} objects.
*
* @return matching Header objects
*/
public Enumeration getMatchingHeaders(String[] names) {
return (new matchEnum(headers, names, true, false));
}
/**
* Return all non-matching {@link javax.mail.Header} objects.
*
* @return non-matching Header objects
*/
public Enumeration getNonMatchingHeaders(String[] names) {
return (new matchEnum(headers, names, false, false));
}
/**
* Add an RFC822 header line to the header store.
* If the line starts with a space or tab (a continuation line),
* add it to the last header line in the list. Otherwise,
* append the new header line to the list. <p>
*
* Note that RFC822 headers can only contain US-ASCII characters
*
* @param line raw RFC822 header line
*/
public void addHeaderLine(String line) {
try {
char c = line.charAt(0);
if (c == ' ' || c == '\t') {
InternetHeader h =
(InternetHeader)headers.get(headers.size() - 1);
h.line += "\r\n" + line;
} else
headers.add(new InternetHeader(line));
} catch (StringIndexOutOfBoundsException e) {
// line is empty, ignore it
return;
} catch (NoSuchElementException e) {
// XXX - vector is empty?
}
}
/**
* Return all the header lines as an Enumeration of Strings.
*/
public Enumeration getAllHeaderLines() {
return (getNonMatchingHeaderLines(null));
}
/**
* Return all matching header lines as an Enumeration of Strings.
*/
public Enumeration getMatchingHeaderLines(String[] names) {
return (new matchEnum(headers, names, true, true));
}
/**
* Return all non-matching header lines
*/
public Enumeration getNonMatchingHeaderLines(String[] names) {
return (new matchEnum(headers, names, false, true));
}
}
@@ -0,0 +1,913 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.logging.Level;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.NumberFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.ParseException;
import com.sun.mail.util.MailLogger;
/**
* Formats and parses date specification based on the
* draft-ietf-drums-msg-fmt-08 dated January 26, 2000. This is a followup
* spec to RFC822.<p>
*
* This class does not take pattern strings. It always formats the
* date based on the specification below.<p>
*
* 3.3 Date and Time Specification<p>
*
* Date and time occur in several header fields of a message. This section
* specifies the syntax for a full date and time specification. Though folding
* whitespace is permitted throughout the date-time specification, it is
* recommended that only a single space be used where FWS is required and no
* space be used where FWS is optional in the date-time specification; some
* older implementations may not interpret other occurrences of folding
* whitespace correctly.<p>
*
* date-time = [ day-of-week "," ] date FWS time [CFWS]<p>
*
* day-of-week = ([FWS] day-name) / obs-day-of-week<p>
*
* day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"<p>
*
* date = day month year<p>
*
* year = 4*DIGIT / obs-year<p>
*
* month = (FWS month-name FWS) / obs-month<p>
*
*<pre>month-name = "Jan" / "Feb" / "Mar" / "Apr" /
* "May" / "Jun" / "Jul" / "Aug" /
* "Sep" / "Oct" / "Nov" / "Dec"
* </pre><p>
* day = ([FWS] 1*2DIGIT) / obs-day<p>
*
* time = time-of-day FWS zone<p>
*
* time-of-day = hour ":" minute [ ":" second ]<p>
*
* hour = 2DIGIT / obs-hour<p>
*
* minute = 2DIGIT / obs-minute<p>
*
* second = 2DIGIT / obs-second<p>
*
* zone = (( "+" / "-" ) 4DIGIT) / obs-zone<p>
*
*
* The day is the numeric day of the month. The year is any numeric year in
* the common era.<p>
*
* The time-of-day specifies the number of hours, minutes, and optionally
* seconds since midnight of the date indicated.<p>
*
* The date and time-of-day SHOULD express local time.<p>
*
* The zone specifies the offset from Coordinated Universal Time (UTC,
* formerly referred to as "Greenwich Mean Time") that the date and
* time-of-day represent. The "+" or "-" indicates whether the time-of-day is
* ahead of or behind Universal Time. The first two digits indicate the number
* of hours difference from Universal Time, and the last two digits indicate
* the number of minutes difference from Universal Time. (Hence, +hhmm means
* +(hh * 60 + mm) minutes, and -hhmm means -(hh * 60 + mm) minutes). The form
* "+0000" SHOULD be used to indicate a time zone at Universal Time. Though
* "-0000" also indicates Universal Time, it is used to indicate that the time
* was generated on a system that may be in a local time zone other than
* Universal Time.<p>
*
* A date-time specification MUST be semantically valid. That is, the
* day-of-the week (if included) MUST be the day implied by the date, the
* numeric day-of-month MUST be between 1 and the number of days allowed for
* the specified month (in the specified year), the time-of-day MUST be in the
* range 00:00:00 through 23:59:60 (the number of seconds allowing for a leap
* second; see [STD-12]), and the zone MUST be within the range -9959 through
* +9959.<p>
*
* @author Max Spivak
* @since JavaMail 1.2
*/
public class MailDateFormat extends SimpleDateFormat {
private static final long serialVersionUID = -8148227605210628779L;
public MailDateFormat() {
super("EEE, d MMM yyyy HH:mm:ss 'XXXXX' (z)", Locale.US);
}
/**
* Formats the given date in the format specified by
* draft-ietf-drums-msg-fmt-08 in the current TimeZone.
*
* @param date the Date object
* @param dateStrBuf the formatted string
* @param fieldPosition the current field position
* @return StringBuffer the formatted String
* @since JavaMail 1.2
*/
public StringBuffer format(Date date, StringBuffer dateStrBuf,
FieldPosition fieldPosition) {
/* How this method works: First format the date with the
* format specified in the constructor inserting string 'XXXXX'
* where the timezone offset goes. Find where in the string the
* string 'XXXXX' appears and remember that in var "pos".
* Calculate the offset, taking the DST into account and insert
* it into the stringbuffer at position pos.
*/
int start = dateStrBuf.length();
super.format(date, dateStrBuf, fieldPosition);
int pos = 0;
// find the beginning of the 'XXXXX' string in the formatted date
// 25 is the first position that we expect to find XXXXX at
for (pos = start + 25; dateStrBuf.charAt(pos) != 'X'; pos++)
;
// set the timezone to +HHMM or -HHMM
calendar.clear();
calendar.setTime(date);
int offset = calendar.get(Calendar.ZONE_OFFSET) +
calendar.get(Calendar.DST_OFFSET);
// take care of the sign
if (offset < 0) {
dateStrBuf.setCharAt(pos++, '-');
offset = (-offset);
} else
dateStrBuf.setCharAt(pos++, '+');
int rawOffsetInMins = offset / 60 / 1000; // offset from GMT in mins
int offsetInHrs = rawOffsetInMins / 60;
int offsetInMins = rawOffsetInMins % 60;
dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInHrs/10), 10));
dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInHrs%10), 10));
dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInMins/10), 10));
dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInMins%10), 10));
// done with timezone
return dateStrBuf;
}
////////////////////////////////////////////////////////////
/**
* Parses the given date in the format specified by
* draft-ietf-drums-msg-fmt-08 in the current TimeZone.
*
* @param text the formatted date to be parsed
* @param pos the current parse position
* @return Date the parsed date in a Date object
* @since JavaMail 1.2
*/
public Date parse(String text, ParsePosition pos) {
return parseDate(text.toCharArray(), pos, isLenient());
}
/*
Valid Examples:
Date: Sun, 21 Mar 1993 23:56:48 -0800 (PST)
Date:
Date: Mon, 22 Mar 1993 09:41:09 -0800 (PST)
Date: 26 Aug 76 14:29 EDT
*/
/**
* method of what to look for:
*
*
* skip WS
* skip day "," (this is "Mon", "Tue")
* skip WS
*
* parse number (until WS) ==> 1*2DIGIT (day of month)
*
* skip WS
*
* parse alpha chars (until WS) ==> find month
*
* skip WS
*
* parse number (until WS) ==> 2*4DIGIT (year)
*
* skip WS
*
* // now looking for time
* parse number (until ':') ==> hours
* parse number (until ':') ==> minutes
* parse number (until WS) ==> seconds
*
* // now look for Time Zone
* skip WS
* if ('+' or '-') then numerical time zone offset
* if (alpha) then alpha time zone offset
*/
static boolean debug = false;
private static MailLogger logger = new MailLogger(
MailDateFormat.class,
"DEBUG",
debug,
System.out);
/**
* create a Date by parsing the char array
*/
static private Date parseDate(char[] orig, ParsePosition pos,
boolean lenient) {
try {
int day = -1;
int month = -1;
int year = -1;
int hours = 0;
int minutes = 0;
int seconds = 0;
int offset = 0;
MailDateParser p = new MailDateParser(orig, pos.getIndex());
// get the day
p.skipUntilNumber();
day = p.parseNumber();
if (!p.skipIfChar('-')) { // for IMAP internal Date
p.skipWhiteSpace();
}
// get the month
month = p.parseMonth();
if (!p.skipIfChar('-')) { // for IMAP internal Date
p.skipWhiteSpace();
}
// get the year
year = p.parseNumber(); // should not return a negative number
if (year < 50) {
year += 2000;
} else if (year < 100) {
year += 1900;
} // otherwise the year is correct (and should be 4 digits)
// get the time
// first get hours
p.skipWhiteSpace();
hours = p.parseNumber();
// get minutes
p.skipChar(':');
minutes = p.parseNumber();
// get seconds (may be no seconds)
if (p.skipIfChar(':')) {
seconds = p.parseNumber();
}
// try to get a Time Zone
try {
p.skipWhiteSpace();
offset = p.parseTimeZone();
} catch (ParseException pe) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE,
"No timezone? : '" + new String(orig) + "'", pe);
}
}
pos.setIndex(p.getIndex());
Date d = ourUTC(year, month, day, hours, minutes, seconds, offset,
lenient);
return d;
} catch (Exception e) {
// Catch *all* exceptions, including RuntimeExceptions like
// ArrayIndexOutofBoundsException ... we need to be
// extra tolerant of all those bogus dates that might screw
// up our parser. Sigh.
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE,
"Bad date: '" + new String(orig) + "'", e);
}
pos.setIndex(1); // to prevent DateFormat.parse() from throwing ex
return null;
}
}
private static final Calendar cal =
new GregorianCalendar(TimeZone.getTimeZone("GMT"));
private synchronized static Date ourUTC(int year, int mon, int mday,
int hour, int min, int sec,
int tzoffset, boolean lenient) {
// clear the time and then set all the values
cal.clear();
cal.setLenient(lenient);
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, mon);
cal.set(Calendar.DATE, mday);
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
cal.add(Calendar.MINUTE, tzoffset); // adjust for the timezone
cal.set(Calendar.SECOND, sec);
return cal.getTime();
}
////////////////////////////////////////////////////////////
/** Don't allow setting the calendar */
public void setCalendar(Calendar newCalendar) {
throw new RuntimeException("Method setCalendar() shouldn't be called");
}
/** Don't allow setting the NumberFormat */
public void setNumberFormat(NumberFormat newNumberFormat) {
throw new RuntimeException("Method setNumberFormat() shouldn't be called");
}
/* test code for MailDateFormat */
/*
public static void main(String[] args) {
DateFormat df = new MailDateFormat();
Date d = new Date();
// test output in all the timezones
System.out.println("------- test all timezones ---------------");
System.out.println("Current date: " + d);
String[] allIDs = TimeZone.getAvailableIDs();
for (int i = 0; i < allIDs.length; i++) {
TimeZone tz = TimeZone.getTimeZone(allIDs[i]);
df.setTimeZone(tz);
System.out.println("Date in " + tz.getID() + ": " +
df.format(new Date()));
}
try {
System.out.println(df.parse("Sun, 21 Mar 1993 23:56:48 -0800 (PST)"));
System.out.println(df.parse("Mon, 22 Mar 1994 13:34:51 +0000"));
System.out.println(df.parse("26 Aug 76 14:29 EDT"));
System.out.println(df.parse("15 Apr 11 23:49 EST"));
System.out.println(df.parse("15 Apr 11 23:49 ABC"));
} catch (ParseException pex) {
pex.printStackTrace();
}
// reset DateFormat TZ
df.setTimeZone(TimeZone.getDefault());
// test all days in a month
System.out.println();
System.out.println("------- test all days in a month ---------------");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1972);
cal.set(Calendar.MONTH, Calendar.OCTOBER);
cal.set(Calendar.DATE, 1);
cal.set(Calendar.HOUR, 10);
cal.set(Calendar.MINUTE, 50);
cal.set(Calendar.AM_PM, Calendar.PM);
System.out.println("Initial Date: " + cal.getTime());
System.out.println("Current Date: " + df.format(cal.getTime()));
for (int i = 0; i < 30; i++) {
cal.roll(Calendar.DATE, true);
System.out.println("Current Date: " + df.format(cal.getTime()));
}
// test all months
System.out.println();
System.out.println("------- test all months in a year -----------");
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DATE, 7);
System.out.println("Initial Date: " + cal.getTime());
System.out.println("Current Date: " + df.format(cal.getTime()));
for (int i = 1; i < 12; i++) {
cal.roll(Calendar.MONTH, true);
System.out.println("Current Date: " + df.format(cal.getTime()));
}
// test leap years
System.out.println();
System.out.println("------- test leap years -----------");
cal.set(Calendar.YEAR, 1999);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DATE, 31);
cal.roll(Calendar.MONTH, true);
System.out.println("Initial Date: " + cal.getTime());
System.out.println("Current Date: " + df.format(cal.getTime()));
for (int i = 1; i < 12; i++) {
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DATE, 31);
cal.roll(Calendar.YEAR, true);
cal.roll(Calendar.MONTH, true);
System.out.println("Current Date: " + df.format(cal.getTime()));
}
}
*/
}
/**
* Helper class to deal with parsing the characters
*/
class MailDateParser {
int index = 0;
char[] orig = null;
public MailDateParser(char[] orig, int index) {
this.orig = orig;
this.index = index;
}
/**
* skips chars until it finds a number (0-9)
*
* if it does not find a number, it will throw
* an ArrayIndexOutOfBoundsException
*/
public void skipUntilNumber() throws ParseException {
try {
while (true) {
switch ( orig[index] ) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return;
default:
index++;
break;
}
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new ParseException("No Number Found", index);
}
}
/**
* skips any number of tabs, spaces, CR, and LF - folding whitespace
*/
public void skipWhiteSpace() {
int len = orig.length;
while (index < len) {
switch (orig[index]) {
case ' ': // space
case '\t': // tab
case '\r': // CR
case '\n': // LF
index++;
break;
default:
return;
}
}
}
/**
* used to look at the next character without "parsing" that
* character.
*/
public int peekChar() throws ParseException {
if (index < orig.length)
return orig[index];
else
throw new ParseException("No more characters", index);
}
/**
* skips the given character. if the current char does not
* match a ParseException will be thrown
*/
public void skipChar(char c) throws ParseException {
if (index < orig.length) {
if (orig[index] == c) {
index++;
} else {
throw new ParseException("Wrong char", index);
}
} else {
throw new ParseException("No more characters", index);
}
}
/**
* will only skip the current char if it matches the given
* char
*/
public boolean skipIfChar(char c) throws ParseException {
if (index < orig.length) {
if (orig[index] == c) {
index++;
return true;
} else {
return false;
}
} else {
throw new ParseException("No more characters", index);
}
}
/**
* current char must point to a number. the number will be
* parsed and the resulting number will be returned. if a
* number is not found, a ParseException will be thrown
*/
public int parseNumber() throws ParseException {
int length = orig.length;
boolean gotNum = false;
int result = 0;
while (index < length) {
switch( orig[index] ) {
case '0':
result *= 10;
gotNum = true;
break;
case '1':
result = result * 10 + 1;
gotNum = true;
break;
case '2':
result = result * 10 + 2;
gotNum = true;
break;
case '3':
result = result * 10 + 3;
gotNum = true;
break;
case '4':
result = result * 10 + 4;
gotNum = true;
break;
case '5':
result = result * 10 + 5;
gotNum = true;
break;
case '6':
result = result * 10 + 6;
gotNum = true;
break;
case '7':
result = result * 10 + 7;
gotNum = true;
break;
case '8':
result = result * 10 + 8;
gotNum = true;
break;
case '9':
result = result * 10 + 9;
gotNum = true;
break;
default:
if (gotNum)
return result;
else
throw new ParseException("No Number found", index);
}
index++;
}
// check the result
if (gotNum)
return result;
// else, throw a parse error
throw new ParseException("No Number found", index);
}
/**
* will look for one of "Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dev"
* and return the numerical version of the month. (0-11). a ParseException
* error is thrown if a month cannot be found.
*/
public int parseMonth() throws ParseException {
char curr;
try {
switch(orig[index++]) {
case 'J':
case 'j': // "Jan" (0) / "Jun" (5) / "Jul" (6)
// check next char
switch(orig[index++]) {
case 'A':
case 'a':
curr = orig[index++];
if (curr == 'N' || curr == 'n') {
return 0;
}
break;
case 'U':
case 'u':
curr = orig[index++];
if (curr == 'N' || curr == 'n') {
return 5;
} else if (curr == 'L' || curr == 'l') {
return 6;
}
break;
}
break;
case 'F':
case 'f': // "Feb"
curr = orig[index++];
if (curr == 'E' || curr == 'e') {
curr = orig[index++];
if (curr == 'B' || curr == 'b') {
return 1;
}
}
break;
case 'M':
case 'm': // "Mar" (2) / "May" (4)
curr = orig[index++];
if (curr == 'A' || curr == 'a') {
curr = orig[index++];
if (curr == 'R' || curr == 'r') {
return 2;
} else if (curr == 'Y' || curr == 'y') {
return 4;
}
}
break;
case 'A':
case 'a': // "Apr" (3) / "Aug" (7)
curr = orig[index++];
if (curr == 'P' || curr == 'p') {
curr = orig[index++];
if (curr == 'R' || curr == 'r') {
return 3;
}
} else if (curr == 'U' || curr == 'u') {
curr = orig[index++];
if (curr == 'G' || curr == 'g') {
return 7;
}
}
break;
case 'S':
case 's': // "Sep" (8)
curr = orig[index++];
if (curr == 'E' || curr == 'e') {
curr = orig[index++];
if (curr == 'P' || curr == 'p') {
return 8;
}
}
break;
case 'O':
case 'o': // "Oct"
curr = orig[index++];
if (curr == 'C' || curr == 'c') {
curr = orig[index++];
if (curr == 'T' || curr == 't') {
return 9;
}
}
break;
case 'N':
case 'n': // "Nov"
curr = orig[index++];
if (curr == 'O' || curr == 'o') {
curr = orig[index++];
if (curr == 'V' || curr == 'v') {
return 10;
}
}
break;
case 'D':
case 'd': // "Dec"
curr = orig[index++];
if (curr == 'E' || curr == 'e') {
curr = orig[index++];
if (curr == 'C' || curr == 'c') {
return 11;
}
}
break;
}
} catch (ArrayIndexOutOfBoundsException e) {
}
throw new ParseException("Bad Month", index);
}
/**
* will parse the timezone - either Numerical version (e.g. +0800, -0500)
* or the alpha version (e.g. PDT, PST). the result will be returned in
* minutes needed to be added to the date to bring it to GMT.
*/
public int parseTimeZone() throws ParseException {
if (index >= orig.length)
throw new ParseException("No more characters", index);
char test = orig[index];
if ( test == '+' || test == '-' ) {
return parseNumericTimeZone();
} else {
return parseAlphaTimeZone();
}
}
/**
* will parse the Numerical time zone version (e.g. +0800, -0500)
* the result will be returned in minutes needed to be added
* to the date to bring it to GMT.
*/
public int parseNumericTimeZone() throws ParseException {
// we switch the sign if it is a '+'
// since the time in the string we are
// parsing is off from GMT by that amount.
// and we want to get the time back into
// GMT, so we substract it.
boolean switchSign = false;
char first = orig[index++];
if (first == '+') {
switchSign = true;
} else if (first != '-') {
throw new ParseException("Bad Numeric TimeZone", index);
}
int oindex = index;
int tz = parseNumber();
if (tz >= 2400)
throw new ParseException("Numeric TimeZone out of range", oindex);
int offset = (tz / 100) * 60 + (tz % 100);
if (switchSign) {
return -offset;
} else {
return offset;
}
}
/**
* will parse the alpha time zone version (e.g. PDT, PST).
* the result will be returned in minutes needed to be added
* to the date to bring it to GMT.
*/
public int parseAlphaTimeZone() throws ParseException {
int result = 0;
boolean foundCommon = false;
char curr;
try {
switch(orig[index++]) {
case 'U':
case 'u': // "UT" / Universal Time
curr = orig[index++];
if (curr == 'T' || curr == 't') {
result = 0;
break;
}
throw new ParseException("Bad Alpha TimeZone", index);
case 'G':
case 'g': // "GMT" ; Universal Time
curr = orig[index++];
if (curr == 'M' || curr == 'm') {
curr = orig[index++];
if (curr == 'T' || curr == 't') {
result = 0;
break;
}
}
throw new ParseException("Bad Alpha TimeZone", index);
case 'E':
case 'e': // "EST" / "EDT" ; Eastern: - 5/ - 4
result = 300;
foundCommon = true;
break;
case 'C':
case 'c': // "CST" / "CDT" ; Central: - 6/ - 5
result = 360;
foundCommon = true;
break;
case 'M':
case 'm': // "MST" / "MDT" ; Mountain: - 7/ - 6
result = 420;
foundCommon = true;
break;
case 'P':
case 'p': // "PST" / "PDT" ; Pacific: - 8/ - 7
result = 480;
foundCommon = true;
break;
default:
throw new ParseException("Bad Alpha TimeZone", index);
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new ParseException("Bad Alpha TimeZone", index);
}
if (foundCommon) {
curr = orig[index++];
if (curr == 'S' || curr == 's') {
curr = orig[index++];
if (curr != 'T' && curr != 't') {
throw new ParseException("Bad Alpha TimeZone", index);
}
} else if (curr == 'D' || curr == 'd') {
curr = orig[index++];
if (curr == 'T' || curr != 't') {
// for daylight time
result -= 60;
} else {
throw new ParseException("Bad Alpha TimeZone", index);
}
}
}
return result;
}
int getIndex() {
return index;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,228 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import javax.mail.*;
import java.io.*;
import java.util.Enumeration;
/**
* The MimePart interface models an <strong>Entity</strong> as defined
* by MIME (RFC2045, Section 2.4). <p>
*
* MimePart extends the Part interface to add additional RFC822 and MIME
* specific semantics and attributes. It provides the base interface for
* the MimeMessage and MimeBodyPart classes
*
* <hr> <strong>A note on RFC822 and MIME headers</strong><p>
*
* RFC822 and MIME header fields <strong>must</strong> contain only
* US-ASCII characters. If a header contains non US-ASCII characters,
* it must be encoded as per the rules in RFC 2047. The MimeUtility
* class provided in this package can be used to to achieve this.
* Callers of the <code>setHeader</code>, <code>addHeader</code>, and
* <code>addHeaderLine</code> methods are responsible for enforcing
* the MIME requirements for the specified headers. In addition, these
* header fields must be folded (wrapped) before being sent if they
* exceed the line length limitation for the transport (1000 bytes for
* SMTP). Received headers may have been folded. The application is
* responsible for folding and unfolding headers as appropriate. <p>
*
* @see MimeUtility
* @see javax.mail.Part
* @author John Mani
*/
public interface MimePart extends Part {
/**
* Get the values of all header fields available for this header,
* returned as a single String, with the values separated by the
* delimiter. If the delimiter is <code>null</code>, only the
* first value is returned.
*
* @param name the name of this header
* @param delimiter delimiter between fields in returned string
* @return the value fields for all headers with
* this name
* @exception MessagingException
*/
public String getHeader(String name, String delimiter)
throws MessagingException;
/**
* Add a raw RFC822 header-line.
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* @exception IllegalStateException if this Part is
* obtained from a READ_ONLY folder
*/
public void addHeaderLine(String line) throws MessagingException;
/**
* Get all header lines as an Enumeration of Strings. A Header
* line is a raw RFC822 header-line, containing both the "name"
* and "value" field.
*/
public Enumeration getAllHeaderLines() throws MessagingException;
/**
* Get matching header lines as an Enumeration of Strings.
* A Header line is a raw RFC822 header-line, containing both
* the "name" and "value" field.
*/
public Enumeration getMatchingHeaderLines(String[] names)
throws MessagingException;
/**
* Get non-matching header lines as an Enumeration of Strings.
* A Header line is a raw RFC822 header-line, containing both
* the "name" and "value" field.
*/
public Enumeration getNonMatchingHeaderLines(String[] names)
throws MessagingException;
/**
* Get the transfer encoding of this part.
*
* @return content-transfer-encoding
* @exception MessagingException
*/
public String getEncoding() throws MessagingException;
/**
* Get the Content-ID of this part. Returns null if none present.
*
* @return content-ID
*/
public String getContentID() throws MessagingException;
/**
* Get the Content-MD5 digest of this part. Returns null if
* none present.
*
* @return content-MD5
*/
public String getContentMD5() throws MessagingException;
/**
* Set the Content-MD5 of this part.
*
* @param md5 the MD5 value
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* @exception IllegalStateException if this Part is
* obtained from a READ_ONLY folder
*/
public void setContentMD5(String md5) throws MessagingException;
/**
* Get the language tags specified in the Content-Language header
* of this MimePart. The Content-Language header is defined by
* RFC 1766. Returns <code>null</code> if this header is not
* available.
*/
public String[] getContentLanguage() throws MessagingException;
/**
* Set the Content-Language header of this MimePart. The
* Content-Language header is defined by RFC1766.
*
* @param languages array of language tags
* @exception IllegalWriteException if the underlying
* implementation does not support modification
* @exception IllegalStateException if this Part is
* obtained from a READ_ONLY folder
*/
public void setContentLanguage(String[] languages)
throws MessagingException;
/**
* Convenience method that sets the given String as this
* part's content, with a MIME type of "text/plain". If the
* string contains non US-ASCII characters. it will be encoded
* using the platform's default charset. The charset is also
* used to set the "charset" parameter. <p>
*
* Note that there may be a performance penalty if
* <code>text</code> is large, since this method may have
* to scan all the characters to determine what charset to
* use. <p>
*
* If the charset is already known, use the
* <code>setText</code> method that takes the charset parameter.
*
* @param text the text content to set
* @exception MessagingException if an error occurs
* @see #setText(String text, String charset)
*/
public void setText(String text) throws MessagingException;
/**
* Convenience method that sets the given String as this part's
* content, with a MIME type of "text/plain" and the specified
* charset. The given Unicode string will be charset-encoded
* using the specified charset. The charset is also used to set
* "charset" parameter.
*
* @param text the text content to set
* @param charset the charset to use for the text
* @exception MessagingException if an error occurs
*/
public void setText(String text, String charset)
throws MessagingException;
/**
* Convenience method that sets the given String as this part's
* content, with a primary MIME type of "text" and the specified
* MIME subtype. The given Unicode string will be charset-encoded
* using the specified charset. The charset is also used to set
* the "charset" parameter.
*
* @param text the text content to set
* @param charset the charset to use for the text
* @param subtype the MIME subtype to use (e.g., "html")
* @exception MessagingException if an error occurs
* @since JavaMail 1.4
*/
public void setText(String text, String charset, String subtype)
throws MessagingException;
}
@@ -0,0 +1,168 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import javax.mail.*;
import javax.activation.*;
import java.io.*;
import java.net.UnknownServiceException;
import com.sun.mail.util.PropUtil;
import com.sun.mail.util.FolderClosedIOException;
/**
* A utility class that implements a DataSource out of
* a MimePart. This class is primarily meant for service providers.
*
* @see javax.mail.internet.MimePart
* @see javax.activation.DataSource
* @author John Mani
*/
public class MimePartDataSource implements DataSource, MessageAware {
/**
* The MimePart that provides the data for this DataSource.
*
* @since JavaMail 1.4
*/
protected MimePart part;
private MessageContext context;
/**
* Constructor, that constructs a DataSource from a MimePart.
*/
public MimePartDataSource(MimePart part) {
this.part = part;
}
/**
* Returns an input stream from this MimePart. <p>
*
* This method applies the appropriate transfer-decoding, based
* on the Content-Transfer-Encoding attribute of this MimePart.
* Thus the returned input stream is a decoded stream of bytes.<p>
*
* This implementation obtains the raw content from the Part
* using the <code>getContentStream()</code> method and decodes
* it using the <code>MimeUtility.decode()</code> method.
*
* @see javax.mail.internet.MimeMessage#getContentStream
* @see javax.mail.internet.MimeBodyPart#getContentStream
* @see javax.mail.internet.MimeUtility#decode
* @return decoded input stream
*/
public InputStream getInputStream() throws IOException {
InputStream is;
try {
if (part instanceof MimeBodyPart)
is = ((MimeBodyPart)part).getContentStream();
else if (part instanceof MimeMessage)
is = ((MimeMessage)part).getContentStream();
else
throw new MessagingException("Unknown part");
String encoding =
MimeBodyPart.restrictEncoding(part, part.getEncoding());
if (encoding != null)
return MimeUtility.decode(is, encoding);
else
return is;
} catch (FolderClosedException fex) {
throw new FolderClosedIOException(fex.getFolder(),
fex.getMessage());
} catch (MessagingException mex) {
throw new IOException(mex.getMessage());
}
}
/**
* DataSource method to return an output stream. <p>
*
* This implementation throws the UnknownServiceException.
*/
public OutputStream getOutputStream() throws IOException {
throw new UnknownServiceException("Writing not supported");
}
/**
* Returns the content-type of this DataSource. <p>
*
* This implementation just invokes the <code>getContentType</code>
* method on the MimePart.
*/
public String getContentType() {
try {
return part.getContentType();
} catch (MessagingException mex) {
// would like to be able to reflect the exception to the
// application, but since we can't do that we return a
// generic "unknown" value here and hope for another
// exception later.
return "application/octet-stream";
}
}
/**
* DataSource method to return a name. <p>
*
* This implementation just returns an empty string.
*/
public String getName() {
try {
if (part instanceof MimeBodyPart)
return ((MimeBodyPart)part).getFileName();
} catch (MessagingException mex) {
// ignore it
}
return "";
}
/**
* Return the <code>MessageContext</code> for the current part.
* @since JavaMail 1.1
*/
public synchronized MessageContext getMessageContext() {
if (context == null)
context = new MessageContext(part);
return context;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,212 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import java.util.Vector;
import java.util.StringTokenizer;
import java.util.Locale;
import javax.mail.*;
/**
* This class models an RFC1036 newsgroup address.
*
* @author Bill Shannon
* @author John Mani
*/
public class NewsAddress extends Address {
protected String newsgroup;
protected String host; // may be null
private static final long serialVersionUID = -4203797299824684143L;
/**
* Default constructor.
*/
public NewsAddress() { }
/**
* Construct a NewsAddress with the given newsgroup.
*
* @param newsgroup the newsgroup
*/
public NewsAddress(String newsgroup) {
this(newsgroup, null);
}
/**
* Construct a NewsAddress with the given newsgroup and host.
*
* @param newsgroup the newsgroup
* @param host the host
*/
public NewsAddress(String newsgroup, String host) {
this.newsgroup = newsgroup;
this.host = host;
}
/**
* Return the type of this address. The type of a NewsAddress
* is "news".
*/
public String getType() {
return "news";
}
/**
* Set the newsgroup.
*
* @param newsgroup the newsgroup
*/
public void setNewsgroup(String newsgroup) {
this.newsgroup = newsgroup;
}
/**
* Get the newsgroup.
*
* @return newsgroup
*/
public String getNewsgroup() {
return newsgroup;
}
/**
* Set the host.
*
* @param host the host
*/
public void setHost(String host) {
this.host = host;
}
/**
* Get the host.
*
* @return host
*/
public String getHost() {
return host;
}
/**
* Convert this address into a RFC 1036 address.
*
* @return newsgroup
*/
public String toString() {
return newsgroup;
}
/**
* The equality operator.
*/
public boolean equals(Object a) {
if (!(a instanceof NewsAddress))
return false;
NewsAddress s = (NewsAddress)a;
return newsgroup.equals(s.newsgroup) &&
((host == null && s.host == null) ||
(host != null && s.host != null && host.equalsIgnoreCase(s.host)));
}
/**
* Compute a hash code for the address.
*/
public int hashCode() {
int hash = 0;
if (newsgroup != null)
hash += newsgroup.hashCode();
if (host != null)
hash += host.toLowerCase(Locale.ENGLISH).hashCode();
return hash;
}
/**
* Convert the given array of NewsAddress objects into
* a comma separated sequence of address strings. The
* resulting string contains only US-ASCII characters, and
* hence is mail-safe.
*
* @param addresses array of NewsAddress objects
* @exception ClassCastException, if any address object in the
* given array is not a NewsAddress objects. Note
* that this is a RuntimeException.
* @return comma separated address strings
*/
public static String toString(Address[] addresses) {
if (addresses == null || addresses.length == 0)
return null;
StringBuffer s =
new StringBuffer(((NewsAddress)addresses[0]).toString());
for (int i = 1; i < addresses.length; i++)
s.append(",").append(((NewsAddress)addresses[i]).toString());
return s.toString();
}
/**
* Parse the given comma separated sequence of newsgroup into
* NewsAddress objects.
*
* @param newsgroups comma separated newsgroup string
* @return array of NewsAddress objects
* @exception AddressException if the parse failed
*/
public static NewsAddress[] parse(String newsgroups)
throws AddressException {
// XXX - verify format of newsgroup name?
StringTokenizer st = new StringTokenizer(newsgroups, ",");
Vector nglist = new Vector();
while (st.hasMoreTokens()) {
String ng = st.nextToken();
nglist.addElement(new NewsAddress(ng));
}
int size = nglist.size();
NewsAddress[] na = new NewsAddress[size];
if (size > 0)
nglist.copyInto(na);
return na;
}
}
@@ -0,0 +1,828 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import java.util.*;
import java.io.*;
import com.sun.mail.util.PropUtil;
import com.sun.mail.util.ASCIIUtility;
/**
* This class holds MIME parameters (attribute-value pairs).
* The <code>mail.mime.encodeparameters</code> and
* <code>mail.mime.decodeparameters</code> System properties
* control whether encoded parameters, as specified by
* <a href="http://www.ietf.org/rfc/rfc2231.txt">RFC 2231</a>,
* are supported. By default, such encoded parameters <b>are</b>
* supported. <p>
*
* Also, in the current implementation, setting the System property
* <code>mail.mime.decodeparameters.strict</code> to <code>"true"</code>
* will cause a <code>ParseException</code> to be thrown for errors
* detected while decoding encoded parameters. By default, if any
* decoding errors occur, the original (undecoded) string is used. <p>
*
* The current implementation supports the System property
* <code>mail.mime.parameters.strict</code>, which if set to false
* when parsing a parameter list allows parameter values
* to contain whitespace and other special characters without
* being quoted; the parameter value ends at the next semicolon.
* If set to true (the default), parameter values are required to conform
* to the MIME specification and must be quoted if they contain whitespace
* or special characters.
*
* @author John Mani
* @author Bill Shannon
*/
public class ParameterList {
/**
* The map of name, value pairs.
* The value object is either a String, for unencoded
* values, or a Value object, for encoded values,
* or a MultiValue object, for multi-segment parameters.
*
* We use a LinkedHashMap so that parameters are (as much as
* possible) kept in the original order. Note however that
* multi-segment parameters (see below) will appear in the
* position of the first seen segment and orphan segments
* will all move to the end.
*/
private Map list = new LinkedHashMap(); // keep parameters in order
/**
* A set of names for multi-segment parameters that we
* haven't processed yet. Normally such names are accumulated
* during the inital parse and processed at the end of the parse,
* but such names can also be set via the set method when the
* IMAP provider accumulates pre-parsed pieces of a parameter list.
* (A special call to the set method tells us when the IMAP provider
* is done setting parameters.)
*
* A multi-segment parameter is defined by RFC 2231. For example,
* "title*0=part1; title*1=part2", which represents a parameter
* named "title" with value "part1part2".
*
* Note also that each segment of the value might or might not be
* encoded, indicated by a trailing "*" on the parameter name.
* If any segment is encoded, the first segment must be encoded.
* Only the first segment contains the charset and language
* information needed to decode any encoded segments.
*
* RFC 2231 introduces many possible failure modes, which we try
* to handle as gracefully as possible. Generally, a failure to
* decode a parameter value causes the non-decoded parameter value
* to be used instead. Missing segments cause all later segments
* to be appear as independent parameters with names that include
* the segment number. For example, "title*0=part1; title*1=part2;
* title*3=part4" appears as two parameters named "title" and "title*3".
*/
private Set multisegmentNames;
/**
* A map containing the segments for all not-yet-processed
* multi-segment parameters. The map is indexed by "name*seg".
* The value object is either a String or a Value object.
* The Value object is not decoded during the initial parse
* because the segments may appear in any order and until the
* first segment appears we don't know what charset to use to
* decode the encoded segments. The segments are hex decoded
* in order, combined into a single byte array, and converted
* to a String using the specified charset in the
* combineMultisegmentNames method.
*/
private Map slist;
/**
* MWB 3BView: The name of the last parameter added to the map.
* Used for the AppleMail hack.
*/
private String lastName = null;
private static final boolean encodeParameters =
PropUtil.getBooleanSystemProperty("mail.mime.encodeparameters", true);
private static final boolean decodeParameters =
PropUtil.getBooleanSystemProperty("mail.mime.decodeparameters", true);
private static final boolean decodeParametersStrict =
PropUtil.getBooleanSystemProperty(
"mail.mime.decodeparameters.strict", false);
private static final boolean applehack =
PropUtil.getBooleanSystemProperty("mail.mime.applefilenames", false);
private static final boolean windowshack =
PropUtil.getBooleanSystemProperty("mail.mime.windowsfilenames", false);
private static final boolean parametersStrict =
PropUtil.getBooleanSystemProperty("mail.mime.parameters.strict", true);
/**
* A struct to hold an encoded value.
* A parsed encoded value is stored as both the
* decoded value and the original encoded value
* (so that toString will produce the same result).
* An encoded value that is set explicitly is stored
* as the original value and the encoded value, to
* ensure that get will return the same value that
* was set.
*/
private static class Value {
String value;
String charset;
String encodedValue;
}
/**
* A struct for a multi-segment parameter. Each entry in the
* List is either a String or a Value object. When all the
* segments are present and combined in the combineMultisegmentNames
* method, the value field contains the combined and decoded value.
* Until then the value field contains an empty string as a placeholder.
*/
private static class MultiValue extends ArrayList {
String value;
}
/**
* Map the LinkedHashMap's keySet iterator to an Enumeration.
*/
private static class ParamEnum implements Enumeration {
private Iterator it;
ParamEnum(Iterator it) {
this.it = it;
}
public boolean hasMoreElements() {
return it.hasNext();
}
public Object nextElement() {
return it.next();
}
}
/**
* No-arg Constructor.
*/
public ParameterList() {
// initialize other collections only if they'll be needed
if (decodeParameters) {
multisegmentNames = new HashSet();
slist = new HashMap();
}
}
/**
* Constructor that takes a parameter-list string. The String
* is parsed and the parameters are collected and stored internally.
* A ParseException is thrown if the parse fails.
* Note that an empty parameter-list string is valid and will be
* parsed into an empty ParameterList.
*
* @param s the parameter-list string.
* @exception ParseException if the parse fails.
*/
public ParameterList(String s) throws ParseException {
this();
HeaderTokenizer h = new HeaderTokenizer(s, HeaderTokenizer.MIME);
for (;;) {
HeaderTokenizer.Token tk = h.next();
int type = tk.getType();
String name, value;
if (type == HeaderTokenizer.Token.EOF) // done
break;
if ((char)type == ';') {
// expect parameter name
tk = h.next();
// tolerate trailing semicolon, even though it violates the spec
if (tk.getType() == HeaderTokenizer.Token.EOF)
break;
// parameter name must be a MIME Atom
if (tk.getType() != HeaderTokenizer.Token.ATOM)
throw new ParseException("Expected parameter name, " +
"got \"" + tk.getValue() + "\"");
name = tk.getValue().toLowerCase(Locale.ENGLISH);
// expect '='
tk = h.next();
if ((char)tk.getType() != '=')
throw new ParseException("Expected '=', " +
"got \"" + tk.getValue() + "\"");
// expect parameter value
if (windowshack &&
(name.equals("name") || name.equals("filename")))
tk = h.next(';', true);
else if (parametersStrict)
tk = h.next();
else
tk = h.next(';');
type = tk.getType();
// parameter value must be a MIME Atom or Quoted String
if (type != HeaderTokenizer.Token.ATOM &&
type != HeaderTokenizer.Token.QUOTEDSTRING)
throw new ParseException("Expected parameter value, " +
"got \"" + tk.getValue() + "\"");
value = tk.getValue();
lastName = name;
if (decodeParameters)
putEncodedName(name, value);
else
list.put(name, value);
} else {
// MWB 3BView new code to add in filenames generated by
// AppleMail.
// Note - one space is assumed between name elements.
// This may not be correct but it shouldn't matter too much.
// Note: AppleMail encodes filenames with non-ascii characters
// correctly, so we don't need to worry about the name* subkeys.
if (type == HeaderTokenizer.Token.ATOM && lastName != null &&
((applehack &&
(lastName.equals("name") ||
lastName.equals("filename"))) ||
!parametersStrict)
) {
// Add value to previous value
String lastValue = (String)list.get(lastName);
value = lastValue + " " + tk.getValue();
list.put(lastName, value);
} else {
throw new ParseException("Expected ';', " +
"got \"" + tk.getValue() + "\"");
}
}
}
if (decodeParameters) {
/*
* After parsing all the parameters, combine all the
* multi-segment parameter values together.
*/
combineMultisegmentNames(false);
}
}
/**
* Normal users of this class will use simple parameter names.
* In some cases, for example, when processing IMAP protocol
* messages, individual segments of a multi-segment name
* (specified by RFC 2231) will be encountered and passed to
* the {@link #set} method. After all these segments are added
* to this ParameterList, they need to be combined to represent
* the logical parameter name and value. This method will combine
* all segments of multi-segment names. <p>
*
* Normal users should never need to call this method.
*
* @since JavaMail 1.5
*/
public void combineSegments() {
/*
* If we've accumulated any multi-segment names from calls to
* the set method from (e.g.) the IMAP provider, combine the pieces.
* Ignore any parse errors (e.g., from decoding the values)
* because it's too late to report them.
*/
if (decodeParameters && multisegmentNames.size() > 0) {
try {
combineMultisegmentNames(true);
} catch (ParseException pex) {
// too late to do anything about it
}
}
}
/**
* If the name is an encoded or multi-segment name (or both)
* handle it appropriately, storing the appropriate String
* or Value object. Multi-segment names are stored in the
* main parameter list as an emtpy string as a placeholder,
* replaced later in combineMultisegmentNames with a MultiValue
* object. This causes all pieces of the multi-segment parameter
* to appear in the position of the first seen segment of the
* parameter.
*/
private void putEncodedName(String name, String value)
throws ParseException {
int star = name.indexOf('*');
if (star < 0) {
// single parameter, unencoded value
list.put(name, value);
} else if (star == name.length() - 1) {
// single parameter, encoded value
name = name.substring(0, star);
Value v = extractCharset(value);
try {
v.value = decodeBytes(v.value, v.charset);
} catch (UnsupportedEncodingException ex) {
if (decodeParametersStrict)
throw new ParseException(ex.toString());
}
list.put(name, v);
} else {
// multiple segments
String rname = name.substring(0, star);
multisegmentNames.add(rname);
list.put(rname, "");
Object v;
if (name.endsWith("*")) {
// encoded value
if (name.endsWith("*0*")) { // first segment
v = extractCharset(value);
} else {
v = new Value();
((Value)v).encodedValue = value;
((Value)v).value = value; // default; decoded later
}
name = name.substring(0, name.length() - 1);
} else {
// unencoded value
v = value;
}
slist.put(name, v);
}
}
/**
* Iterate through the saved set of names of multi-segment parameters,
* for each parameter find all segments stored in the slist map,
* decode each segment as needed, combine the segments together into
* a single decoded value, and save all segments in a MultiValue object
* in the main list indexed by the parameter name.
*/
private void combineMultisegmentNames(boolean keepConsistentOnFailure)
throws ParseException {
boolean success = false;
try {
Iterator it = multisegmentNames.iterator();
while (it.hasNext()) {
String name = (String)it.next();
StringBuffer sb = new StringBuffer();
MultiValue mv = new MultiValue();
/*
* Now find all the segments for this name and
* decode each segment as needed.
*/
String charset = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int segment;
for (segment = 0; ; segment++) {
String sname = name + "*" + segment;
Object v = slist.get(sname);
if (v == null) // out of segments
break;
mv.add(v);
try {
if (v instanceof Value) {
Value vv = (Value)v;
if (segment == 0) {
// the first segment specifies the charset
// for all other encoded segments
charset = vv.charset;
} else {
if (charset == null) {
// should never happen
multisegmentNames.remove(name);
break;
}
}
decodeBytes(vv.value, bos);
} else {
bos.write(ASCIIUtility.getBytes((String)v));
}
} catch (IOException ex) {
// XXX - should never happen
}
slist.remove(sname);
}
if (segment == 0) {
// didn't find any segments at all
list.remove(name);
} else {
try {
if (charset != null)
mv.value = bos.toString(charset);
else
mv.value = bos.toString();
} catch (UnsupportedEncodingException uex) {
if (decodeParametersStrict)
throw new ParseException(uex.toString());
// convert as if ASCII
mv.value = bos.toString(0);
}
list.put(name, mv);
}
}
success = true;
} finally {
/*
* If we get here because of an exception that's going to
* be thrown (success == false) from the constructor
* (keepConsistentOnFailure == false), this is all wasted effort.
*/
if (keepConsistentOnFailure || success) {
// we should never end up with anything in slist,
// but if we do, add it all to list
if (slist.size() > 0) {
// first, decode any values that we'll add to the list
Iterator sit = slist.values().iterator();
while (sit.hasNext()) {
Object v = sit.next();
if (v instanceof Value) {
Value vv = (Value)v;
try {
vv.value =
decodeBytes(vv.value, vv.charset);
} catch (UnsupportedEncodingException ex) {
if (decodeParametersStrict)
throw new ParseException(ex.toString());
}
}
}
list.putAll(slist);
}
// clear out the set of names and segments
multisegmentNames.clear();
slist.clear();
}
}
}
/**
* Return the number of parameters in this list.
*
* @return number of parameters.
*/
public int size() {
return list.size();
}
/**
* Returns the value of the specified parameter. Note that
* parameter names are case-insensitive.
*
* @param name parameter name.
* @return Value of the parameter. Returns
* <code>null</code> if the parameter is not
* present.
*/
public String get(String name) {
String value;
Object v = list.get(name.trim().toLowerCase(Locale.ENGLISH));
if (v instanceof MultiValue)
value = ((MultiValue)v).value;
else if (v instanceof Value)
value = ((Value)v).value;
else
value = (String)v;
return value;
}
/**
* Set a parameter. If this parameter already exists, it is
* replaced by this new value.
*
* @param name name of the parameter.
* @param value value of the parameter.
*/
public void set(String name, String value) {
name = name.trim().toLowerCase(Locale.ENGLISH);
if (decodeParameters) {
try {
putEncodedName(name, value);
} catch (ParseException pex) {
// ignore it
list.put(name, value);
}
} else
list.put(name, value);
}
/**
* Set a parameter. If this parameter already exists, it is
* replaced by this new value. If the
* <code>mail.mime.encodeparameters</code> System property
* is true, and the parameter value is non-ASCII, it will be
* encoded with the specified charset, as specified by RFC 2231.
*
* @param name name of the parameter.
* @param value value of the parameter.
* @param charset charset of the parameter value.
* @since JavaMail 1.4
*/
public void set(String name, String value, String charset) {
if (encodeParameters) {
Value ev = encodeValue(value, charset);
// was it actually encoded?
if (ev != null)
list.put(name.trim().toLowerCase(Locale.ENGLISH), ev);
else
set(name, value);
} else
set(name, value);
}
/**
* Removes the specified parameter from this ParameterList.
* This method does nothing if the parameter is not present.
*
* @param name name of the parameter.
*/
public void remove(String name) {
list.remove(name.trim().toLowerCase(Locale.ENGLISH));
}
/**
* Return an enumeration of the names of all parameters in this
* list.
*
* @return Enumeration of all parameter names in this list.
*/
public Enumeration getNames() {
return new ParamEnum(list.keySet().iterator());
}
/**
* Convert this ParameterList into a MIME String. If this is
* an empty list, an empty string is returned.
*
* @return String
*/
public String toString() {
return toString(0);
}
/**
* Convert this ParameterList into a MIME String. If this is
* an empty list, an empty string is returned.
*
* The 'used' parameter specifies the number of character positions
* already taken up in the field into which the resulting parameter
* list is to be inserted. It's used to determine where to fold the
* resulting parameter list.
*
* @param used number of character positions already used, in
* the field into which the parameter list is to
* be inserted.
* @return String
*/
public String toString(int used) {
ToStringBuffer sb = new ToStringBuffer(used);
Iterator e = list.keySet().iterator();
while (e.hasNext()) {
String name = (String)e.next();
Object v = list.get(name);
if (v instanceof MultiValue) {
MultiValue vv = (MultiValue)v;
String ns = name + "*";
for (int i = 0; i < vv.size(); i++) {
Object va = vv.get(i);
if (va instanceof Value)
sb.addNV(ns + i + "*", ((Value)va).encodedValue);
else
sb.addNV(ns + i, (String)va);
}
} else if (v instanceof Value)
sb.addNV(name + "*", ((Value)v).encodedValue);
else
sb.addNV(name, (String)v);
}
return sb.toString();
}
/**
* A special wrapper for a StringBuffer that keeps track of the
* number of characters used in a line, wrapping to a new line
* as necessary; for use by the toString method.
*/
private static class ToStringBuffer {
private int used; // keep track of how much used on current line
private StringBuffer sb = new StringBuffer();
public ToStringBuffer(int used) {
this.used = used;
}
public void addNV(String name, String value) {
value = quote(value);
sb.append("; ");
used += 2;
int len = name.length() + value.length() + 1;
if (used + len > 76) { // overflows ...
sb.append("\r\n\t"); // .. start new continuation line
used = 8; // account for the starting <tab> char
}
sb.append(name).append('=');
used += name.length() + 1;
if (used + value.length() > 76) { // still overflows ...
// have to fold value
String s = MimeUtility.fold(used, value);
sb.append(s);
int lastlf = s.lastIndexOf('\n');
if (lastlf >= 0) // always true
used += s.length() - lastlf - 1;
else
used += s.length();
} else {
sb.append(value);
used += value.length();
}
}
public String toString() {
return sb.toString();
}
}
// Quote a parameter value token if required.
private static String quote(String value) {
return MimeUtility.quote(value, HeaderTokenizer.MIME);
}
private static final char hex[] = {
'0','1', '2', '3', '4', '5', '6', '7',
'8','9', 'A', 'B', 'C', 'D', 'E', 'F'
};
/**
* Encode a parameter value, if necessary.
* If the value is encoded, a Value object is returned.
* Otherwise, null is returned.
* XXX - Could return a MultiValue object if parameter value is too long.
*/
private static Value encodeValue(String value, String charset) {
if (MimeUtility.checkAscii(value) == MimeUtility.ALL_ASCII)
return null; // no need to encode it
byte[] b; // charset encoded bytes from the string
try {
b = value.getBytes(MimeUtility.javaCharset(charset));
} catch (UnsupportedEncodingException ex) {
return null;
}
StringBuffer sb = new StringBuffer(b.length + charset.length() + 2);
sb.append(charset).append("''");
for (int i = 0; i < b.length; i++) {
char c = (char)(b[i] & 0xff);
// do we need to encode this character?
if (c <= ' ' || c >= 0x7f || c == '*' || c == '\'' || c == '%' ||
HeaderTokenizer.MIME.indexOf(c) >= 0) {
sb.append('%').append(hex[c>>4]).append(hex[c&0xf]);
} else
sb.append(c);
}
Value v = new Value();
v.charset = charset;
v.value = value;
v.encodedValue = sb.toString();
return v;
}
/**
* Extract charset and encoded value.
* Value will be decoded later.
*/
private static Value extractCharset(String value) throws ParseException {
Value v = new Value();
v.value = v.encodedValue = value;
try {
int i = value.indexOf('\'');
if (i <= 0) {
if (decodeParametersStrict)
throw new ParseException(
"Missing charset in encoded value: " + value);
return v; // not encoded correctly? return as is.
}
String charset = value.substring(0, i);
int li = value.indexOf('\'', i + 1);
if (li < 0) {
if (decodeParametersStrict)
throw new ParseException(
"Missing language in encoded value: " + value);
return v; // not encoded correctly? return as is.
}
String lang = value.substring(i + 1, li);
v.value = value.substring(li + 1);
v.charset = charset;
} catch (NumberFormatException nex) {
if (decodeParametersStrict)
throw new ParseException(nex.toString());
} catch (StringIndexOutOfBoundsException ex) {
if (decodeParametersStrict)
throw new ParseException(ex.toString());
}
return v;
}
/**
* Decode the encoded bytes in value using the specified charset.
*/
private static String decodeBytes(String value, String charset)
throws ParseException, UnsupportedEncodingException {
/*
* Decode the ASCII characters in value
* into an array of bytes, and then convert
* the bytes to a String using the specified
* charset. We'll never need more bytes than
* encoded characters, so use that to size the
* array.
*/
byte[] b = new byte[value.length()];
int i, bi;
for (i = 0, bi = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (c == '%') {
try {
String hex = value.substring(i + 1, i + 3);
c = (char)Integer.parseInt(hex, 16);
i += 2;
} catch (NumberFormatException ex) {
if (decodeParametersStrict)
throw new ParseException(ex.toString());
} catch (StringIndexOutOfBoundsException ex) {
if (decodeParametersStrict)
throw new ParseException(ex.toString());
}
}
b[bi++] = (byte)c;
}
charset = MimeUtility.javaCharset(charset);
if (charset == null)
charset = MimeUtility.getDefaultJavaCharset();
return new String(b, 0, bi, charset);
}
/**
* Decode the encoded bytes in value and write them to the OutputStream.
*/
private static void decodeBytes(String value, OutputStream os)
throws ParseException, IOException {
/*
* Decode the ASCII characters in value
* and write them to the stream.
*/
int i;
for (i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (c == '%') {
try {
String hex = value.substring(i + 1, i + 3);
c = (char)Integer.parseInt(hex, 16);
i += 2;
} catch (NumberFormatException ex) {
if (decodeParametersStrict)
throw new ParseException(ex.toString());
} catch (StringIndexOutOfBoundsException ex) {
if (decodeParametersStrict)
throw new ParseException(ex.toString());
}
}
os.write((byte)c);
}
}
}
@@ -0,0 +1,70 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import javax.mail.MessagingException;
/**
* The exception thrown due to an error in parsing RFC822
* or MIME headers
*
* @author John Mani
*/
public class ParseException extends MessagingException {
private static final long serialVersionUID = 7649991205183658089L;
/**
* Constructs a ParseException with no detail message.
*/
public ParseException() {
super();
}
/**
* Constructs a ParseException with the specified detail message.
* @param s the detail message
*/
public ParseException(String s) {
super(s);
}
}
@@ -0,0 +1,124 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import java.io.*;
import java.util.Enumeration;
import javax.mail.*;
import com.sun.mail.util.LineOutputStream;
/**
* A MimeBodyPart that handles data that has already been encoded.
* This class is useful when constructing a message and attaching
* data that has already been encoded (for example, using base64
* encoding). The data may have been encoded by the application,
* or may have been stored in a file or database in encoded form.
* The encoding is supplied when this object is created. The data
* is attached to this object in the usual fashion, by using the
* <code>setText</code>, <code>setContent</code>, or
* <code>setDataHandler</code> methods.
*
* @since JavaMail 1.4
*/
public class PreencodedMimeBodyPart extends MimeBodyPart {
private String encoding;
/**
* Create a PreencodedMimeBodyPart that assumes the data is
* encoded using the specified encoding. The encoding must
* be a MIME supported Content-Transfer-Encoding.
*/
public PreencodedMimeBodyPart(String encoding) {
this.encoding = encoding;
}
/**
* Returns the content transfer encoding specified when
* this object was created.
*/
public String getEncoding() throws MessagingException {
return encoding;
}
/**
* Output the body part as an RFC 822 format stream.
*
* @exception MessagingException
* @exception IOException if an error occurs writing to the
* stream or if an error is generated
* by the javax.activation layer.
* @see javax.activation.DataHandler#writeTo
*/
public void writeTo(OutputStream os)
throws IOException, MessagingException {
// see if we already have a LOS
LineOutputStream los = null;
if (os instanceof LineOutputStream) {
los = (LineOutputStream) os;
} else {
los = new LineOutputStream(os);
}
// First, write out the header
Enumeration hdrLines = getAllHeaderLines();
while (hdrLines.hasMoreElements())
los.writeln((String)hdrLines.nextElement());
// The CRLF separator between header and content
los.writeln();
// Finally, the content, already encoded.
getDataHandler().writeTo(os);
os.flush();
}
/**
* Force the <code>Content-Transfer-Encoding</code> header to use
* the encoding that was specified when this object was created.
*/
protected void updateHeaders() throws MessagingException {
super.updateHeaders();
MimeBodyPart.setEncoding(this, encoding);
}
}
@@ -0,0 +1,84 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import java.io.*;
/**
* An InputStream that is backed by data that can be shared by multiple
* readers may implement this interface. This allows users of such an
* InputStream to determine the current position in the InputStream, and
* to create new InputStreams representing a subset of the data in the
* original InputStream. The new InputStream will access the same
* underlying data as the original, without copying the data. <p>
*
* Note that implementations of this interface must ensure that the
* <code>close</code> method does not close any underlying stream
* that might be shared by multiple instances of <code>SharedInputStream</code>
* until all shared instances have been closed.
*
* @author Bill Shannon
* @since JavaMail 1.2
*/
public interface SharedInputStream {
/**
* Return the current position in the InputStream, as an
* offset from the beginning of the InputStream.
*
* @return the current position
*/
public long getPosition();
/**
* Return a new InputStream representing a subset of the data
* from this InputStream, starting at <code>start</code> (inclusive)
* up to <code>end</code> (exclusive). <code>start</code> must be
* non-negative. If <code>end</code> is -1, the new stream ends
* at the same place as this stream. The returned InputStream
* will also implement the SharedInputStream interface.
*
* @param start the starting position
* @param end the ending position + 1
* @return the new stream
*/
public InputStream newStream(long start, long end);
}
@@ -0,0 +1,123 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.internet;
import java.net.*;
import javax.mail.Session;
/**
* This is a utility class that generates unique values. The generated
* String contains only US-ASCII characters and hence is safe for use
* in RFC822 headers. <p>
*
* This is a package private class.
*
* @author John Mani
* @author Max Spivak
* @author Bill Shannon
*/
class UniqueValue {
/**
* A global unique number, to ensure uniqueness of generated strings.
*/
private static int id = 0;
/**
* Get a unique value for use in a multipart boundary string.
*
* This implementation generates it by concatenating a global
* part number, a newly created object's <code>hashCode()</code>,
* and the current time (in milliseconds).
*/
public static String getUniqueBoundaryValue() {
StringBuffer s = new StringBuffer();
// Unique string is ----=_Part_<part>_<hashcode>.<currentTime>
s.append("----=_Part_").append(getUniqueId()).append("_").
append(s.hashCode()).append('.').
append(System.currentTimeMillis());
return s.toString();
}
/**
* Get a unique value for use in a Message-ID.
*
* This implementation generates it by concatenating a newly
* created object's <code>hashCode()</code>, a global ID
* (incremented on every use), the current
* time (in milliseconds), the string "JavaMail", and
* this user's local address generated by
* <code>InternetAddress.getLocalAddress()</code>.
* (The address defaults to "javamailuser@localhost" if
* <code>getLocalAddress()</code> returns null.)
*
* @param ssn Session object used to get the local address
* @see javax.mail.internet.InternetAddress
*/
public static String getUniqueMessageIDValue(Session ssn) {
String suffix = null;
InternetAddress addr = InternetAddress.getLocalAddress(ssn);
if (addr != null)
suffix = addr.getAddress();
else {
suffix = "javamailuser@localhost"; // worst-case default
}
StringBuffer s = new StringBuffer();
// Unique string is <hashcode>.<id>.<currentTime>.JavaMail.<suffix>
s.append(s.hashCode()).append('.').append(getUniqueId()).append('.').
append(System.currentTimeMillis()).append('.').
append("JavaMail.").
append(suffix);
return s.toString();
}
/**
* Ensure ID is unique by synchronizing access.
* XXX - Could use AtomicInteger.getAndIncrement() in J2SE 5.0.
*/
private static synchronized int getUniqueId() {
return id++;
}
}
@@ -0,0 +1,502 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can
obtain a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
or packager/legal/LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.
When distributing the software, include this License Header Notice in each
file and include the License file at packager/legal/LICENSE.txt.
GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.
Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"
Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->
</HEAD>
<BODY BGCOLOR="white">
Classes specific to Internet mail systems.
This package supports features that are specific to Internet mail systems
based on the MIME standard
(<A HREF="http://www.ietf.org/rfc/rfc2045.txt" TARGET="_top">RFC 2045</A>,
<A HREF="http://www.ietf.org/rfc/rfc2045.txt" TARGET="_top">RFC 2046</A>, and
<A HREF="http://www.ietf.org/rfc/rfc2045.txt" TARGET="_top">RFC 2047</A>).
The IMAP, SMTP, and POP3 protocols use
{@link javax.mail.internet.MimeMessage MimeMessages}.
<P>
The JavaMail API specification requires support for the following properties,
which must be set in the <code>System</code> properties.
The properties are always set as strings; the Type column describes
how the string is interpreted. For example, use (in J2SE 1.2 and newer)
<PRE>
System.setProperty("mail.mime.address.strict", "false");
</PRE>
to set the <CODE>mail.mime.address.strict</CODE> property,
which is of type boolean.
<P>
<TABLE BORDER>
<TR>
<TH>Name</TH>
<TH>Type</TH>
<TH>Description</TH>
</TR>
<TR>
<TD>mail.mime.address.strict</TD>
<TD>boolean</TD>
<TD>
The <code>mail.mime.address.strict</code> session property controls
the parsing of address headers. By default, strict parsing of address
headers is done. If this property is set to <code>"false"</code>,
strict parsing is not done and many illegal addresses that sometimes
occur in real messages are allowed. See the <code>InternetAddress</code>
class for details.
</TD>
</TR>
<TR>
<TD>mail.mime.charset</TD>
<TD>String</TD>
<TD>
The <code>mail.mime.charset</code> System property can
be used to specify the default MIME charset to use for encoded words
and text parts that don't otherwise specify a charset. Normally, the
default MIME charset is derived from the default Java charset, as
specified in the <code>file.encoding</code> System property. Most
applications will have no need to explicitly set the default MIME
charset. In cases where the default MIME charset to be used for
mail messages is different than the charset used for files stored on
the system, this property should be set.
</TD>
</TR>
<TR>
<TD>mail.mime.decodetext.strict</TD>
<TD>boolean</TD>
<TD>
The <code>mail.mime.decodetext.strict</code> property controls
decoding of MIME encoded words. The MIME spec requires that encoded
words start at the beginning of a whitespace separated word. Some
mailers incorrectly include encoded words in the middle of a word.
If the <code>mail.mime.decodetext.strict</code> System property is
set to <code>"false"</code>, an attempt will be made to decode these
illegal encoded words. The default is true.
</TD>
</TR>
<TR>
<TD>mail.mime.encodeeol.strict</TD>
<TD>boolean</TD>
<TD>
The <code>mail.mime.encodeeol.strict</code> property controls the
choice of Content-Transfer-Encoding for MIME parts that are not of
type "text". Often such parts will contain textual data for which
an encoding that allows normal end of line conventions is appropriate.
In rare cases, such a part will appear to contain entirely textual
data, but will require an encoding that preserves CR and LF characters
without change. If the <code>mail.mime.encodeeol.strict</code>
System property is set to <code>"true"</code>, such an encoding will
be used when necessary. The default is false.
</TD>
</TR>
<TR>
<TD>mail.mime.decodefilename</TD>
<TD>boolean</TD>
<TD>
If set to <code>"true"</code>, the <code>getFileName</code> method
uses the <code>MimeUtility</code>
method <code>decodeText</code> to decode any
non-ASCII characters in the filename. Note that this decoding
violates the MIME specification, but is useful for interoperating
with some mail clients that use this convention.
The default is false.
</TD>
</TR>
<TR>
<TD>mail.mime.encodefilename</TD>
<TD>boolean</TD>
<TD>
If set to <code>"true"</code>, the <code>setFileName</code> method
uses the <code>MimeUtility</code>
method <code>encodeText</code> to encode any
non-ASCII characters in the filename. Note that this encoding
violates the MIME specification, but is useful for interoperating
with some mail clients that use this convention.
The default is false.
</TD>
</TR>
<TR>
<TD>mail.mime.decodeparameters</TD>
<TD>boolean</TD>
<TD>
If set to <code>"false"</code>, non-ASCII parameters in a
<code>ParameterList</code>, e.g., in a Content-Type header,
will <b>not</b> be decoded as specified by
<A HREF="http://www.ietf.org/rfc/rfc2231.txt" TARGET="_top">RFC 2231</A>.
The default is true.
</TD>
</TR>
<TR>
<TD>mail.mime.encodeparameters</TD>
<TD>boolean</TD>
<TD>
If set to <code>"false"</code>, non-ASCII parameters in a
<code>ParameterList</code>, e.g., in a Content-Type header,
will <b>not</b> be encoded as specified by
<A HREF="http://www.ietf.org/rfc/rfc2231.txt" TARGET="_top">RFC 2231</A>.
The default is true.
</TD>
</TR>
<TR>
<TD>mail.mime.multipart. ignoremissingendboundary</TD>
<TD>boolean</TD>
<TD>
Normally, when parsing a multipart MIME message, a message that is
missing the final end boundary line is not considered an error.
The data simply ends at the end of the input. Note that messages
of this form violate the MIME specification. If the property
<code>mail.mime.multipart.ignoremissingendboundary</code> is set
to <code>false</code>, such messages are considered an error and a
<code>MesagingException</code> will be thrown when parsing such a
message.
</TD>
</TR>
<TR>
<TD>mail.mime.multipart. ignoremissingboundaryparameter</TD>
<TD>boolean</TD>
<TD>
If the Content-Type header for a multipart content does not have
a <code>boundary</code> parameter, the multipart parsing code
will look for the first line in the content that looks like a
boundary line and extract the boundary parameter from the line.
If this property is set to <code>"false"</code>, a
<code>MessagingException</code> will be thrown if the Content-Type
header doesn't specify a boundary parameter.
The default is true.
</TD>
</TR>
<TR>
<TD>mail.mime.multipart. ignoreexistingboundaryparameter</TD>
<TD>boolean</TD>
<TD>
Normally the boundary parameter in the Content-Type header of a multipart
body part is used to specify the separator between parts of the multipart
body. This System property may be set to <code>"true"</code> to cause
the parser to look for a line in the multipart body that looks like a
boundary line and use that value as the separator between subsequent parts.
This may be useful in cases where a broken anti-virus product has rewritten
the message incorrectly such that the boundary parameter and the actual
boundary value no longer match.
The default value of this property is false.
</TD>
</TR>
<TR>
<TD>mail.mime.multipart. allowempty</TD>
<TD>boolean</TD>
<TD>
Normally, when writing out a MimeMultipart that contains no body
parts, or when trying to parse a multipart message with no body parts,
a <code>MessagingException</code> is thrown. The MIME spec does not allow
multipart content with no body parts. This
System property may be set to <code>"true"</code> to override this behavior.
When writing out such a MimeMultipart, a single empty part will be
included. When reading such a multipart, a MimeMultipart will be created
with no body parts.
The default value of this property is false.
</TD>
</TR>
</TABLE>
<P>
The following properties are supported by Sun's implementation of
JavaMail, but are not currently a required part of the specification.
As above, these must be set as <CODE>System</CODE> properties.
The names, types, defaults, and semantics of these properties may
change in future releases.
<P>
<TABLE BORDER>
<TR>
<TH>Name</TH>
<TH>Type</TH>
<TH>Description</TH>
</TR>
<TR>
<TD>mail.mime.base64.ignoreerrors</TD>
<TD>boolean</TD>
<TD>
If set to <code>"true"</code>, the BASE64 decoder will ignore errors
in the encoded data, returning EOF. This may be useful when dealing
with improperly encoded messages that contain extraneous data at the
end of the encoded stream. Note however that errors anywhere in the
stream will cause the decoder to stop decoding so this should be used
with extreme caution. The default is false.
</TD>
</TR>
<TR>
<TD>mail.mime.foldtext</TD>
<TD>boolean</TD>
<TD>
If set to <code>"true"</code>, header fields containing just text
such as the <code>Subject</code> and <code>Content-Description</code>
header fields, and long parameter values in structured headers such
as <code>Content-Type</code> will be folded (broken into 76 character lines)
when set and unfolded when read. The default is true.
</TD>
</TR>
<TR>
<TD>mail.mime.setcontenttypefilename</TD>
<TD>boolean</TD>
<TD>
If set to <code>"true"</code>, the <code>setFileName</code> method
will also set the <code>name</code> parameter on the <code>Content-Type</code>
header to the specified filename. This supports interoperability with
some old mail clients. The default is true.
</TD>
</TR>
<TR>
<TD>mail.mime.setdefaulttextcharset</TD>
<TD>boolean</TD>
<TD>
When updating the headers of a message, a body
part with a <code>text</code> content type but no <code>charset</code>
parameter will have a <code>charset</code> parameter added to it
if this property is set to <code>"true"</code>.
The default is true.
</TD>
</TR>
<TR>
<TD>mail.mime.parameters.strict</TD>
<TD>boolean</TD>
<TD>
If set to false, when reading a message, parameter values in header fields
such as <code>Content-Type</code> and <code>Content-Disposition</code>
are allowed to contain whitespace and other special characters without
being quoted; the parameter value ends at the next semicolon.
If set to true (the default), parameter values are required to conform
to the MIME specification and must be quoted if they contain whitespace
or special characters.
</TD>
</TR>
<TR>
<TD>mail.mime.applefilenames</TD>
<TD>boolean</TD>
<TD>
Apple Mail incorrectly encodes filenames that contain spaces,
forgetting to quote the parameter value. If this property is
set to <code>"true"</code>, JavaMail will try to detect this
situation when parsing parameters and work around it.
The default is false.
Note that this property handles a subset of the cases handled
by setting the mail.mime.parameters.strict property to false.
This property will likely be removed in a future release.
</TD>
</TR>
<TR>
<TD>mail.mime.windowsfilenames</TD>
<TD>boolean</TD>
<TD>
Internet Explorer 6 incorrectly includes a complete pathname
in the filename parameter of the Content-Disposition header
for uploaded files, and fails to properly escape the backslashes
in the pathname. If this property is
set to <code>"true"</code>, JavaMail will preserve all backslashes
in the "filename" and "name" parameters of any MIME header.
The default is false.
Note that this is a violation of the MIME specification but may
be useful when using JavaMail to parse HTTP messages for uploaded
files sent by IE6.
</TD>
</TR>
<TR>
<TD>mail.mime. ignoreunknownencoding</TD>
<TD>boolean</TD>
<TD>
If set to <code>"true"</code>, an unknown value in the
<code>Content-Transfer-Encoding</code> header will be ignored
when reading a message and an encoding of "8bit" will be assumed.
If set to <code>"false"</code>, an exception is thrown for an
unknown encoding value. The default is false.
</TD>
</TR>
<TR>
<TD>mail.mime.uudecode. ignoreerrors</TD>
<TD>boolean</TD>
<TD>
If set to <code>"true"</code>, errors in the encoded format of a
uuencoded document will be ignored when reading a message part.
If set to <code>"false"</code>, an exception is thrown for an
incorrectly encoded message part. The default is false.
</TD>
</TR>
<TR>
<TD>mail.mime.uudecode. ignoremissingbeginend</TD>
<TD>boolean</TD>
<TD>
If set to <code>"true"</code>, a missing "being" or "end" line in a
uuencoded document will be ignored when reading a message part.
If set to <code>"false"</code>, an exception is thrown for a
uuencoded message part without the required "begin" and "end" lines.
The default is false.
</TD>
</TR>
<TR>
<TD>mail.mime. ignorewhitespacelines</TD>
<TD>boolean</TD>
<TD>
Normally the header of a MIME part is separated from the body by an empty
line. This System property may be set to <code>"true"</code> to cause
the parser to consider a line containing only whitespace to be an empty
line. The default value of this property is false.
</TD>
</TR>
<TR>
<TD>mail.mime. ignoremultipartencoding</TD>
<TD>boolean</TD>
<TD>
The MIME spec does not allow body parts of type multipart/* to be encoded.
The Content-Transfer-Encoding header is ignored in this case.
Setting this System property to <code>"false"</code> will
cause the Content-Transfer-Encoding header to be honored for multipart
content.
The default value of this property is true.
</TD>
</TR>
<TR>
<TD>mail.mime.allowencodedmessages</TD>
<TD>boolean</TD>
<TD>
The MIME spec does not allow body parts of type message/* to be encoded.
The Content-Transfer-Encoding header is ignored in this case.
Some versions of Microsoft Outlook will incorrectly encode message
attachments. Setting this System property to <code>"true"</code> will
cause the Content-Transfer-Encoding header to be honored for message
attachments.
The default value of this property is false.
</TD>
</TR>
<TR>
<TD>mail.mime.contenttypehandler</TD>
<TD>String</TD>
<TD>
In some cases JavaMail is unable to process messages with an invalid
Content-Type header. The header may have incorrect syntax or other
problems. This property specifies the name of a class that will be
used to clean up the Content-Type header value before JavaMail uses it.
The class must have a method with this signature:
<CODE>public static String cleanContentType(MimePart mp, String contentType)</CODE>
Whenever JavaMail accesses the Content-Type header of a message, it
will pass the value to this method and use the returned value instead.
The value may be null if the Content-Type header isn't present.
Returning null will cause the default Content-Type to be used.
The MimePart may be used to access other headers of the message part
to determine how to correct the Content-Type.
Note that the Content-Type handler doesn't affect the
<CODE>getHeader</CODE> method, which still returns the raw header value.
Note also that the handler doesn't affect the IMAP provider; the IMAP
server is responsible for returning pre-parsed, syntactically correct
Content-Type information.
</TD>
</TR>
<TR>
<TD>mail.alternates</TD>
<TD>String</TD>
<TD>
A string containing other email addresses that the current user is known by.
The <code>MimeMessage</code> <code>reply</code> method will eliminate any
of these addresses from the recipient list in the message it constructs,
to avoid sending the reply back to the sender.
</TD>
</TR>
<TR>
<TD>mail.replyallcc</TD>
<TD>boolean</TD>
<TD>
If set to <code>"true"</code>, the <code>MimeMessage</code>
<code>reply</code> method will put all recipients except the original
sender in the <code>Cc</code> list of the newly constructed message.
Normally, recipients in the <code>To</code> header of the original
message will also appear in the <code>To</code> list of the newly
constructed message.
</TD>
</TR>
</TABLE>
<P>
The current
implementation of classes in this package log debugging information using
{@link java.util.logging.Logger} as described in the following table:
<P>
<TABLE BORDER>
<TR>
<TH>Logger Name</TH>
<TH>Logging Level</TH>
<TH>Purpose</TH>
</TR>
<TR>
<TD>javax.mail.internet</TD>
<TD>FINE</TD>
<TD>General debugging output</TD>
</TR>
</TABLE>
</BODY>
</HTML>
+312
View File
@@ -0,0 +1,312 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<!--
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 2 only ("GPL") or the Common Development
and Distribution License("CDDL") (collectively, the "License"). You
may not use this file except in compliance with the License. You can
obtain a copy of the License at
https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
or packager/legal/LICENSE.txt. See the License for the specific
language governing permissions and limitations under the License.
When distributing the software, include this License Header Notice in each
file and include the License file at packager/legal/LICENSE.txt.
GPL Classpath Exception:
Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the GPL Version 2 section of the License
file that accompanied this code.
Modifications:
If applicable, add the following below the License Header, with the fields
enclosed by brackets [] replaced by your own identifying information:
"Portions Copyright [year] [name of copyright owner]"
Contributor(s):
If you wish your version of this file to be governed by only the CDDL or
only the GPL Version 2, indicate your decision by adding "[Contributor]
elects to include this software in this distribution under the [CDDL or GPL
Version 2] license." If you don't indicate a single choice of license, a
recipient has the option to distribute your version of this file under
either the CDDL, the GPL Version 2 or to extend the choice of license to
its licensees as provided above. However, if you add GPL Version 2 code
and therefore, elected the GPL Version 2 license, then the option applies
only if the new code is made subject to such option by the copyright
holder.
-->
</HEAD>
<BODY BGCOLOR="white">
The JavaMail<sup><font size="-2">TM</font></sup> API
provides classes that model a mail system.
The <code>javax.mail</code> package defines classes that are common to
all mail systems.
The <code>javax.mail.internet</code> package defines classes that are specific
to mail systems based on internet standards such as MIME, SMTP, POP3, and IMAP.
The JavaMail API includes the <code>javax.mail</code> package and subpackages.
<P>
For an overview of the JavaMail API, read the JavaMail specification
<A HREF="../../../JavaMail-1.5.pdf" TARGET="_top">
included in the download bundle</A> or
<A HREF="http://www.oracle.com/technetwork/java/javamail-1-149769.pdf" TARGET="_top">
available on the JavaMail web site</A>.
<P>
The code to send a plain text message can be as simple as the following:
<PRE>
Properties props = new Properties();
props.put("mail.smtp.host", "my-mail-server");
Session session = Session.getInstance(props, null);
try {
MimeMessage msg = new MimeMessage(session);
msg.setFrom("me@example.com");
msg.setRecipients(Message.RecipientType.TO,
"you@example.com");
msg.setSubject("JavaMail hello world example");
msg.setSentDate(new Date());
msg.setText("Hello, world!\n");
Transport.send(msg, "me@example.com", "my-password");
} catch (MessagingException mex) {
System.out.println("send failed, exception: " + mex);
}
</PRE>
The JavaMail download bundle contains many more complete examples
in the "demo" directory.
<P>
Don't forget to see the
<A HREF="http://www.oracle.com/technetwork/java/javamail/faq/" TARGET="_top">
JavaMail API FAQ</A>
for answers to the most common questions.
The <A HREF="http://www.oracle.com/technetwork/java/javamail/" TARGET="_top">
JavaMail web site</A>
contains many additional resources.
<P>
The JavaMail API supports the following standard properties,
which may be set in the <code>Session</code> object, or in the
<code>Properties</code> object used to create the <code>Session</code> object.
The properties are always set as strings; the Type column describes
how the string is interpreted. For example, use
<PRE>
props.put("mail.debug", "true");
</PRE>
to set the <code>mail.debug</code> property, which is of type boolean.
<P>
<TABLE BORDER>
<TR>
<TH>Name</TH>
<TH>Type</TH>
<TH>Description</TH>
</TR>
<TR>
<TD>mail.debug</TD>
<TD>boolean</TD>
<TD>
The initial debug mode.
Default is false.
</TD>
</TR>
<TR>
<TD>mail.from</TD>
<TD>String</TD>
<TD>
The return email address of the current user, used by the
<code>InternetAddress</code> method <code>getLocalAddress</code>.
</TD>
</TR>
<TR>
<TD>mail.mime.address.strict</TD>
<TD>boolean</TD>
<TD>
The MimeMessage class uses the <code>InternetAddress</code> method
<code>parseHeader</code> to parse headers in messages. This property
controls the strict flag passed to the <code>parseHeader</code>
method. The default is true.
</TD>
</TR>
<TR>
<TD>mail.host</TD>
<TD>String</TD>
<TD>
The default host name of the mail server for both Stores and Transports.
Used if the <code>mail.<i>protocol</i>.host</code> property isn't set.
</TD>
</TR>
<TR>
<TD>mail.store.protocol</TD>
<TD>String</TD>
<TD>
Specifies the default message access protocol. The
<code>Session</code> method <code>getStore()</code> returns a Store
object that implements this protocol. By default the first Store
provider in the configuration files is returned.
</TD>
</TR>
<TR>
<TD>mail.transport.protocol</TD>
<TD>String</TD>
<TD>
Specifies the default message transport protocol. The
<code>Session</code> method <code>getTransport()</code> returns a Transport
object that implements this protocol. By default the first Transport
provider in the configuration files is returned.
</TD>
</TR>
<TR>
<TD>mail.user</TD>
<TD>String</TD>
<TD>
The default user name to use when connecting to the mail server.
Used if the <code>mail.<i>protocol</i>.user</code> property isn't set.
</TD>
</TR>
<TR>
<TD>mail.<i>protocol</i>.class</TD>
<TD>String</TD>
<TD>
Specifies the fully qualified class name of the provider for the
specified protocol. Used in cases where more than one provider
for a given protocol exists; this property can be used to specify
which provider to use by default. The provider must still be listed
in a configuration file.
</TD>
</TR>
<TR>
<TD>mail.<i>protocol</i>.host</TD>
<TD>String</TD>
<TD>
The host name of the mail server for the specified protocol.
Overrides the <code>mail.host</code> property.
</TD>
</TR>
<TR>
<TD>mail.<i>protocol</i>.port</TD>
<TD>int</TD>
<TD>
The port number of the mail server for the specified protocol.
If not specified the protocol's default port number is used.
</TD>
</TR>
<TR>
<TD>mail.<i>protocol</i>.user</TD>
<TD>String</TD>
<TD>
The user name to use when connecting to mail servers
using the specified protocol.
Overrides the <code>mail.user</code> property.
</TD>
</TR>
</TABLE>
<P>
The following properties are supported by Sun's implementation of
JavaMail, but are not currently a required part of the specification.
The names, types, defaults, and semantics of these properties may
change in future releases.
<P>
<TABLE BORDER>
<TR>
<TH>Name</TH>
<TH>Type</TH>
<TH>Description</TH>
</TR>
<TR>
<TD>mail.debug.auth</TD>
<TD>boolean</TD>
<TD>
Include protocol authentication commands (including usernames and passwords)
in the debug output.
Default is false.
</TD>
</TR>
<TR>
<TD>mail.transport.protocol.<i>address-type</i></TD>
<TD>String</TD>
<TD>
Specifies the default message transport protocol for the specified address type.
The <code>Session</code> method <code>getTransport(Address)</code> returns a
Transport object that implements this protocol when the address is of the
specified type (e.g., "rfc822" for standard internet addresses).
By default the first Transport configured for that address type is used.
This property can be used to override the behavior of the
{@link javax.mail.Transport#send send} method of the
{@link javax.mail.Transport Transport} class so that (for example) the "smtps"
protocol is used instead of the "smtp" protocol by setting the property
<code>mail.transport.protocol.rfc822</code> to <code>"smtps"</code>.
</TD>
</TR>
</TABLE>
<P>
The JavaMail API also supports several System properties;
see the {@link javax.mail.internet} package documentation
for details.
<P>
The JavaMail reference
implementation from Sun includes protocol providers in subpackages of
<code>com.sun.mail</code>. Note that the APIs to these protocol
providers are not part of the standard JavaMail API. Portable
programs will not use these APIs.
<P>
Nonportable programs may use the APIs of the Sun protocol providers
by (for example) casting a returned <code>Folder</code> object to a
<code>com.sun.mail.imap.IMAPFolder</code> object. Similarly for
<code>Store</code> and <code>Message</code> objects returned from the
standard JavaMail APIs.
<P>
The Sun protocol providers also support properties that are specific to
those providers. The package documentation for the
{@link com.sun.mail.imap IMAP}, {@link com.sun.mail.pop3 POP3},
and {@link com.sun.mail.smtp SMTP} packages provide details.
<P>
In addition to printing debugging output as controlled by the
{@link javax.mail.Session Session} configuration, the current
implementation of classes in this package log the same information using
{@link java.util.logging.Logger} as described in the following table:
<P>
<TABLE BORDER>
<TR>
<TH>Logger Name</TH>
<TH>Logging Level</TH>
<TH>Purpose</TH>
</TR>
<TR>
<TD>javax.mail</TD>
<TD>CONFIG</TD>
<TD>Configuration of the Session</TD>
</TR>
<TR>
<TD>javax.mail</TD>
<TD>FINE</TD>
<TD>General debugging output</TD>
</TR>
</TABLE>
</BODY>
</HTML>
@@ -0,0 +1,103 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
import javax.mail.Address;
import javax.mail.internet.InternetAddress;
/**
* This abstract class implements string comparisons for Message
* addresses. <p>
*
* Note that this class differs from the <code>AddressTerm</code> class
* in that this class does comparisons on address strings rather than
* Address objects.
*
* @since JavaMail 1.1
*/
public abstract class AddressStringTerm extends StringTerm {
private static final long serialVersionUID = 3086821234204980368L;
/**
* Constructor.
*
* @param pattern the address pattern to be compared.
*/
protected AddressStringTerm(String pattern) {
super(pattern, true); // we need case-insensitive comparison.
}
/**
* Check whether the address pattern specified in the constructor is
* a substring of the string representation of the given Address
* object. <p>
*
* Note that if the string representation of the given Address object
* contains charset or transfer encodings, the encodings must be
* accounted for, during the match process. <p>
*
* @param a The comparison is applied to this Address object.
* @return true if the match succeeds, otherwise false.
*/
protected boolean match(Address a) {
if (a instanceof InternetAddress) {
InternetAddress ia = (InternetAddress)a;
// We dont use toString() to get "a"'s String representation,
// because InternetAddress.toString() returns a RFC 2047
// encoded string, which isn't what we need here.
return super.match(ia.toUnicodeString());
} else
return super.match(a.toString());
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof AddressStringTerm))
return false;
return super.equals(obj);
}
}
@@ -0,0 +1,96 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Address;
/**
* This class implements Message Address comparisons.
*
* @author Bill Shannon
* @author John Mani
*/
public abstract class AddressTerm extends SearchTerm {
/**
* The address.
*
* @serial
*/
protected Address address;
private static final long serialVersionUID = 2005405551929769980L;
protected AddressTerm(Address address) {
this.address = address;
}
/**
* Return the address to match with.
*/
public Address getAddress() {
return address;
}
/**
* Match against the argument Address.
*/
protected boolean match(Address a) {
return (a.equals(address));
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof AddressTerm))
return false;
AddressTerm at = (AddressTerm)obj;
return at.address.equals(this.address);
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return address.hashCode();
}
}
@@ -0,0 +1,135 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
/**
* This class implements the logical AND operator on individual
* SearchTerms.
*
* @author Bill Shannon
* @author John Mani
*/
public final class AndTerm extends SearchTerm {
/**
* The array of terms on which the AND operator should be
* applied.
*
* @serial
*/
private SearchTerm[] terms;
private static final long serialVersionUID = -3583274505380989582L;
/**
* Constructor that takes two terms.
*
* @param t1 first term
* @param t2 second term
*/
public AndTerm(SearchTerm t1, SearchTerm t2) {
terms = new SearchTerm[2];
terms[0] = t1;
terms[1] = t2;
}
/**
* Constructor that takes an array of SearchTerms.
*
* @param t array of terms
*/
public AndTerm(SearchTerm[] t) {
terms = new SearchTerm[t.length]; // clone the array
for (int i = 0; i < t.length; i++)
terms[i] = t[i];
}
/**
* Return the search terms.
*/
public SearchTerm[] getTerms() {
return (SearchTerm[])terms.clone();
}
/**
* The AND operation. <p>
*
* The terms specified in the constructor are applied to
* the given object and the AND operator is applied to their results.
*
* @param msg The specified SearchTerms are applied to this Message
* and the AND operator is applied to their results.
* @return true if the AND succeds, otherwise false
*/
public boolean match(Message msg) {
for (int i=0; i < terms.length; i++)
if (!terms[i].match(msg))
return false;
return true;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof AndTerm))
return false;
AndTerm at = (AndTerm)obj;
if (at.terms.length != terms.length)
return false;
for (int i=0; i < terms.length; i++)
if (!terms[i].equals(at.terms[i]))
return false;
return true;
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
int hash = 0;
for (int i=0; i < terms.length; i++)
hash += terms[i].hashCode();
return hash;
}
}
@@ -0,0 +1,122 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.*;
/**
* This class implements searches on a message body.
* All parts of the message that are of MIME type "text/*" are searched.
* The pattern is a simple string that must appear as a substring in
* the message body.
*
* @author Bill Shannon
* @author John Mani
*/
public final class BodyTerm extends StringTerm {
private static final long serialVersionUID = -4888862527916911385L;
/**
* Constructor
* @param pattern The String to search for
*/
public BodyTerm(String pattern) {
// Note: comparison is case-insensitive
super(pattern);
}
/**
* The match method.
*
* @param msg The pattern search is applied on this Message's body
* @return true if the pattern is found; otherwise false
*/
public boolean match(Message msg) {
return matchPart(msg);
}
/**
* Search all the parts of the message for any text part
* that matches the pattern.
*/
private boolean matchPart(Part p) {
try {
/*
* Using isMimeType to determine the content type avoids
* fetching the actual content data until we need it.
*/
if (p.isMimeType("text/*")) {
String s = (String)p.getContent();
if (s == null)
return false;
/*
* We invoke our superclass' (i.e., StringTerm) match method.
* Note however that StringTerm.match() is not optimized
* for substring searches in large string buffers. We really
* need to have a StringTerm subclass, say BigStringTerm,
* with its own match() method that uses a better algorithm ..
* and then subclass BodyTerm from BigStringTerm.
*/
return super.match(s);
} else if (p.isMimeType("multipart/*")) {
Multipart mp = (Multipart)p.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++)
if (matchPart(mp.getBodyPart(i)))
return true;
} else if (p.isMimeType("message/rfc822")) {
return matchPart((Part)p.getContent());
}
} catch (Exception ex) {
}
return false;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof BodyTerm))
return false;
return super.equals(obj);
}
}
@@ -0,0 +1,83 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
/**
* This class models the comparison operator. This is an abstract
* class; subclasses implement comparisons for different datatypes.
*
* @author Bill Shannon
* @author John Mani
*/
public abstract class ComparisonTerm extends SearchTerm {
public static final int LE = 1;
public static final int LT = 2;
public static final int EQ = 3;
public static final int NE = 4;
public static final int GT = 5;
public static final int GE = 6;
/**
* The comparison.
*
* @serial
*/
protected int comparison;
private static final long serialVersionUID = 1456646953666474308L;
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof ComparisonTerm))
return false;
ComparisonTerm ct = (ComparisonTerm)obj;
return ct.comparison == this.comparison;
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return comparison;
}
}
@@ -0,0 +1,126 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import java.util.Date;
/**
* This class implements comparisons for Dates
*
* @author Bill Shannon
* @author John Mani
*/
public abstract class DateTerm extends ComparisonTerm {
/**
* The date.
*
* @serial
*/
protected Date date;
private static final long serialVersionUID = 4818873430063720043L;
/**
* Constructor.
* @param comparison the comparison type
* @param date The Date to be compared against
*/
protected DateTerm(int comparison, Date date) {
this.comparison = comparison;
this.date = date;
}
/**
* Return the Date to compare with.
*/
public Date getDate() {
return new Date(date.getTime());
}
/**
* Return the type of comparison.
*/
public int getComparison() {
return comparison;
}
/**
* The date comparison method.
*
* @param d the date in the constructor is compared with this date
* @return true if the dates match, otherwise false
*/
protected boolean match(Date d) {
switch (comparison) {
case LE:
return d.before(date) || d.equals(date);
case LT:
return d.before(date);
case EQ:
return d.equals(date);
case NE:
return !d.equals(date);
case GT:
return d.after(date);
case GE:
return d.after(date) || d.equals(date);
default:
return false;
}
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof DateTerm))
return false;
DateTerm dt = (DateTerm)obj;
return dt.date.equals(this.date) && super.equals(obj);
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return date.hashCode() + super.hashCode();
}
}
@@ -0,0 +1,159 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.*;
/**
* This class implements comparisons for Message Flags.
*
* @author Bill Shannon
* @author John Mani
*/
public final class FlagTerm extends SearchTerm {
/**
* Indicates whether to test for the presence or
* absence of the specified Flag. If <code>true</code>,
* then test whether all the specified flags are present, else
* test whether all the specified flags are absent.
*
* @serial
*/
private boolean set;
/**
* Flags object containing the flags to test.
*
* @serial
*/
private Flags flags;
private static final long serialVersionUID = -142991500302030647L;
/**
* Constructor.
*
* @param flags Flags object containing the flags to check for
* @param set the flag setting to check for
*/
public FlagTerm(Flags flags, boolean set) {
this.flags = flags;
this.set = set;
}
/**
* Return the Flags to test.
*/
public Flags getFlags() {
return (Flags)flags.clone();
}
/**
* Return true if testing whether the flags are set.
*/
public boolean getTestSet() {
return set;
}
/**
* The comparison method.
*
* @param msg The flag comparison is applied to this Message
* @return true if the comparson succeeds, otherwise false.
*/
public boolean match(Message msg) {
try {
Flags f = msg.getFlags();
if (set) { // This is easy
if (f.contains(flags))
return true;
else
return false;
}
// Return true if ALL flags in the passed in Flags
// object are NOT set in this Message.
// Got to do this the hard way ...
Flags.Flag[] sf = flags.getSystemFlags();
// Check each flag in the passed in Flags object
for (int i = 0; i < sf.length; i++) {
if (f.contains(sf[i]))
// this flag IS set in this Message, get out.
return false;
}
String[] s = flags.getUserFlags();
// Check each flag in the passed in Flags object
for (int i = 0; i < s.length; i++) {
if (f.contains(s[i]))
// this flag IS set in this Message, get out.
return false;
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof FlagTerm))
return false;
FlagTerm ft = (FlagTerm)obj;
return ft.set == this.set && ft.flags.equals(this.flags);
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return set ? flags.hashCode() : ~flags.hashCode();
}
}
@@ -0,0 +1,104 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
import javax.mail.Address;
/**
* This class implements string comparisons for the From Address
* header. <p>
*
* Note that this class differs from the <code>FromTerm</code> class
* in that this class does comparisons on address strings rather than Address
* objects. The string comparisons are case-insensitive.
*
* @since JavaMail 1.1
*/
public final class FromStringTerm extends AddressStringTerm {
private static final long serialVersionUID = 5801127523826772788L;
/**
* Constructor.
*
* @param pattern the address pattern to be compared.
*/
public FromStringTerm(String pattern) {
super(pattern);
}
/**
* Check whether the address string specified in the constructor is
* a substring of the From address of this Message.
*
* @param msg The comparison is applied to this Message's From
* address.
* @return true if the match succeeds, otherwise false.
*/
public boolean match(Message msg) {
Address[] from;
try {
from = msg.getFrom();
} catch (Exception e) {
return false;
}
if (from == null)
return false;
for (int i=0; i < from.length; i++)
if (super.match(from[i]))
return true;
return false;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof FromStringTerm))
return false;
return super.equals(obj);
}
}
@@ -0,0 +1,96 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
import javax.mail.Address;
/**
* This class implements comparisons for the From Address header.
*
* @author Bill Shannon
* @author John Mani
*/
public final class FromTerm extends AddressTerm {
private static final long serialVersionUID = 5214730291502658665L;
/**
* Constructor
* @param address The Address to be compared
*/
public FromTerm(Address address) {
super(address);
}
/**
* The address comparator.
*
* @param msg The address comparison is applied to this Message
* @return true if the comparison succeeds, otherwise false
*/
public boolean match(Message msg) {
Address[] from;
try {
from = msg.getFrom();
} catch (Exception e) {
return false;
}
if (from == null)
return false;
for (int i=0; i < from.length; i++)
if (super.match(from[i]))
return true;
return false;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof FromTerm))
return false;
return super.equals(obj);
}
}
@@ -0,0 +1,124 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import java.util.Locale;
import javax.mail.Message;
/**
* This class implements comparisons for Message headers.
* The comparison is case-insensitive.
*
* @author Bill Shannon
* @author John Mani
*/
public final class HeaderTerm extends StringTerm {
/**
* The name of the header.
*
* @serial
*/
private String headerName;
private static final long serialVersionUID = 8342514650333389122L;
/**
* Constructor.
*
* @param headerName The name of the header
* @param pattern The pattern to search for
*/
public HeaderTerm(String headerName, String pattern) {
super(pattern);
this.headerName = headerName;
}
/**
* Return the name of the header to compare with.
*/
public String getHeaderName() {
return headerName;
}
/**
* The header match method.
*
* @param msg The match is applied to this Message's header
* @return true if the match succeeds, otherwise false
*/
public boolean match(Message msg) {
String[] headers;
try {
headers = msg.getHeader(headerName);
} catch (Exception e) {
return false;
}
if (headers == null)
return false;
for (int i=0; i < headers.length; i++)
if (super.match(headers[i]))
return true;
return false;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof HeaderTerm))
return false;
HeaderTerm ht = (HeaderTerm)obj;
// XXX - depends on header comparisons being case independent
return ht.headerName.equalsIgnoreCase(headerName) && super.equals(ht);
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
// XXX - depends on header comparisons being case independent
return headerName.toLowerCase(Locale.ENGLISH).hashCode() +
super.hashCode();
}
}
@@ -0,0 +1,113 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
/**
* This class implements comparisons for integers.
*
* @author Bill Shannon
* @author John Mani
*/
public abstract class IntegerComparisonTerm extends ComparisonTerm {
/**
* The number.
*
* @serial
*/
protected int number;
private static final long serialVersionUID = -6963571240154302484L;
protected IntegerComparisonTerm(int comparison, int number) {
this.comparison = comparison;
this.number = number;
}
/**
* Return the number to compare with.
*/
public int getNumber() {
return number;
}
/**
* Return the type of comparison.
*/
public int getComparison() {
return comparison;
}
protected boolean match(int i) {
switch (comparison) {
case LE:
return i <= number;
case LT:
return i < number;
case EQ:
return i == number;
case NE:
return i != number;
case GT:
return i > number;
case GE:
return i >= number;
default:
return false;
}
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof IntegerComparisonTerm))
return false;
IntegerComparisonTerm ict = (IntegerComparisonTerm)obj;
return ict.number == this.number && super.equals(obj);
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return number + super.hashCode();
}
}
@@ -0,0 +1,103 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
/**
* This term models the RFC822 "MessageId" - a message-id for
* Internet messages that is supposed to be unique per message.
* Clients can use this term to search a folder for a message given
* its MessageId. <p>
*
* The MessageId is represented as a String.
*
* @author Bill Shannon
* @author John Mani
*/
public final class MessageIDTerm extends StringTerm {
private static final long serialVersionUID = -2121096296454691963L;
/**
* Constructor.
*
* @param msgid the msgid to search for
*/
public MessageIDTerm(String msgid) {
// Note: comparison is case-insensitive
super(msgid);
}
/**
* The match method.
*
* @param msg the match is applied to this Message's
* Message-ID header
* @return true if the match succeeds, otherwise false
*/
public boolean match(Message msg) {
String[] s;
try {
s = msg.getHeader("Message-ID");
} catch (Exception e) {
return false;
}
if (s == null)
return false;
for (int i=0; i < s.length; i++)
if (super.match(s[i]))
return true;
return false;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof MessageIDTerm))
return false;
return super.equals(obj);
}
}
@@ -0,0 +1,90 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
/**
* This class implements comparisons for Message numbers.
*
* @author Bill Shannon
* @author John Mani
*/
public final class MessageNumberTerm extends IntegerComparisonTerm {
private static final long serialVersionUID = -5379625829658623812L;
/**
* Constructor.
*
* @param number the Message number
*/
public MessageNumberTerm(int number) {
super(EQ, number);
}
/**
* The match method.
*
* @param msg the Message number is matched with this Message
* @return true if the match succeeds, otherwise false
*/
public boolean match(Message msg) {
int msgno;
try {
msgno = msg.getMessageNumber();
} catch (Exception e) {
return false;
}
return super.match(msgno);
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof MessageNumberTerm))
return false;
return super.equals(obj);
}
}
@@ -0,0 +1,93 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
/**
* This class implements the logical NEGATION operator.
*
* @author Bill Shannon
* @author John Mani
*/
public final class NotTerm extends SearchTerm {
/**
* The search term to negate.
*
* @serial
*/
private SearchTerm term;
private static final long serialVersionUID = 7152293214217310216L;
public NotTerm(SearchTerm t) {
term = t;
}
/**
* Return the term to negate.
*/
public SearchTerm getTerm() {
return term;
}
/* The NOT operation */
public boolean match(Message msg) {
return !term.match(msg);
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof NotTerm))
return false;
NotTerm nt = (NotTerm)obj;
return nt.term.equals(this.term);
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return term.hashCode() << 1;
}
}
+135
View File
@@ -0,0 +1,135 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
/**
* This class implements the logical OR operator on individual SearchTerms.
*
* @author Bill Shannon
* @author John Mani
*/
public final class OrTerm extends SearchTerm {
/**
* The array of terms on which the OR operator should
* be applied.
*
* @serial
*/
private SearchTerm[] terms;
private static final long serialVersionUID = 5380534067523646936L;
/**
* Constructor that takes two operands.
*
* @param t1 first term
* @param t2 second term
*/
public OrTerm(SearchTerm t1, SearchTerm t2) {
terms = new SearchTerm[2];
terms[0] = t1;
terms[1] = t2;
}
/**
* Constructor that takes an array of SearchTerms.
*
* @param t array of search terms
*/
public OrTerm(SearchTerm[] t) {
terms = new SearchTerm[t.length];
for (int i = 0; i < t.length; i++)
terms[i] = t[i];
}
/**
* Return the search terms.
*/
public SearchTerm[] getTerms() {
return (SearchTerm[])terms.clone();
}
/**
* The OR operation. <p>
*
* The terms specified in the constructor are applied to
* the given object and the OR operator is applied to their results.
*
* @param msg The specified SearchTerms are applied to this Message
* and the OR operator is applied to their results.
* @return true if the OR succeds, otherwise false
*/
public boolean match(Message msg) {
for (int i=0; i < terms.length; i++)
if (terms[i].match(msg))
return true;
return false;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof OrTerm))
return false;
OrTerm ot = (OrTerm)obj;
if (ot.terms.length != terms.length)
return false;
for (int i=0; i < terms.length; i++)
if (!terms[i].equals(ot.terms[i]))
return false;
return true;
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
int hash = 0;
for (int i=0; i < terms.length; i++)
hash += terms[i].hashCode();
return hash;
}
}
@@ -0,0 +1,96 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import java.util.Date;
import javax.mail.Message;
/**
* This class implements comparisons for the Message Received date
*
* @author Bill Shannon
* @author John Mani
*/
public final class ReceivedDateTerm extends DateTerm {
private static final long serialVersionUID = -2756695246195503170L;
/**
* Constructor.
*
* @param comparison the Comparison type
* @param date the date to be compared
*/
public ReceivedDateTerm(int comparison, Date date) {
super(comparison, date);
}
/**
* The match method.
*
* @param msg the date comparator is applied to this Message's
* sent date
* @return true if the comparison succeeds, otherwise false
*/
public boolean match(Message msg) {
Date d;
try {
d = msg.getReceivedDate();
} catch (Exception e) {
return false;
}
if (d == null)
return false;
return super.match(d);
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof ReceivedDateTerm))
return false;
return super.equals(obj);
}
}
@@ -0,0 +1,128 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
import javax.mail.Address;
/**
* This class implements string comparisons for the Recipient Address
* headers. <p>
*
* Note that this class differs from the <code>RecipientTerm</code> class
* in that this class does comparisons on address strings rather than Address
* objects. The string comparisons are case-insensitive.
*
* @since JavaMail 1.1
*/
public final class RecipientStringTerm extends AddressStringTerm {
/**
* The recipient type.
*
* @serial
*/
private Message.RecipientType type;
private static final long serialVersionUID = -8293562089611618849L;
/**
* Constructor.
*
* @param type the recipient type
* @param pattern the address pattern to be compared.
*/
public RecipientStringTerm(Message.RecipientType type, String pattern) {
super(pattern);
this.type = type;
}
/**
* Return the type of recipient to match with.
*/
public Message.RecipientType getRecipientType() {
return type;
}
/**
* Check whether the address specified in the constructor is
* a substring of the recipient address of this Message.
*
* @param msg The comparison is applied to this Message's recipient
* address.
* @return true if the match succeeds, otherwise false.
*/
public boolean match(Message msg) {
Address[] recipients;
try {
recipients = msg.getRecipients(type);
} catch (Exception e) {
return false;
}
if (recipients == null)
return false;
for (int i=0; i < recipients.length; i++)
if (super.match(recipients[i]))
return true;
return false;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof RecipientStringTerm))
return false;
RecipientStringTerm rst = (RecipientStringTerm)obj;
return rst.type.equals(this.type) && super.equals(obj);
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return type.hashCode() + super.hashCode();
}
}
@@ -0,0 +1,122 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
import javax.mail.Address;
/**
* This class implements comparisons for the Recipient Address headers.
*
* @author Bill Shannon
* @author John Mani
*/
public final class RecipientTerm extends AddressTerm {
/**
* The recipient type.
*
* @serial
*/
private Message.RecipientType type;
private static final long serialVersionUID = 6548700653122680468L;
/**
* Constructor.
*
* @param type the recipient type
* @param address the address to match for
*/
public RecipientTerm(Message.RecipientType type, Address address) {
super(address);
this.type = type;
}
/**
* Return the type of recipient to match with.
*/
public Message.RecipientType getRecipientType() {
return type;
}
/**
* The match method.
*
* @param msg The address match is applied to this Message's recepient
* address
* @return true if the match succeeds, otherwise false
*/
public boolean match(Message msg) {
Address[] recipients;
try {
recipients = msg.getRecipients(type);
} catch (Exception e) {
return false;
}
if (recipients == null)
return false;
for (int i=0; i < recipients.length; i++)
if (super.match(recipients[i]))
return true;
return false;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof RecipientTerm))
return false;
RecipientTerm rt = (RecipientTerm)obj;
return rt.type.equals(this.type) && super.equals(obj);
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return type.hashCode() + super.hashCode();
}
}
@@ -0,0 +1,70 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.MessagingException;
/**
* The exception thrown when a Search expression could not be handled.
*
* @author John Mani
*/
public class SearchException extends MessagingException {
private static final long serialVersionUID = -7092886778226268686L;
/**
* Constructs a SearchException with no detail message.
*/
public SearchException() {
super();
}
/**
* Constructs a SearchException with the specified detail message.
* @param s the detail message
*/
public SearchException(String s) {
super(s);
}
}
@@ -0,0 +1,87 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import java.io.Serializable;
import javax.mail.Message;
/**
* Search criteria are expressed as a tree of search-terms, forming
* a parse-tree for the search expression. <p>
*
* Search-terms are represented by this class. This is an abstract
* class; subclasses implement specific match methods. <p>
*
* Search terms are serializable, which allows storing a search term
* between sessions.
*
* <strong>Warning:</strong>
* Serialized objects of this class may not be compatible with future
* JavaMail API releases. The current serialization support is
* appropriate for short term storage. <p>
*
* <strong>Warning:</strong>
* Search terms that include references to objects of type
* <code>Message.RecipientType</code> will not be deserialized
* correctly on JDK 1.1 systems. While these objects will be deserialized
* without throwing any exceptions, the resulting objects violate the
* <i>type-safe enum</i> contract of the <code>Message.RecipientType</code>
* class. Proper deserialization of these objects depends on support
* for the <code>readReplace</code> method, added in JDK 1.2.
*
* @author Bill Shannon
* @author John Mani
*/
public abstract class SearchTerm implements Serializable {
private static final long serialVersionUID = -6652358452205992789L;
/**
* This method applies a specific match criterion to the given
* message and returns the result.
*
* @param msg The match criterion is applied on this message
* @return true, it the match succeeds, false if the match fails
*/
public abstract boolean match(Message msg);
}
@@ -0,0 +1,96 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import java.util.Date;
import javax.mail.Message;
/**
* This class implements comparisons for the Message SentDate.
*
* @author Bill Shannon
* @author John Mani
*/
public final class SentDateTerm extends DateTerm {
private static final long serialVersionUID = 5647755030530907263L;
/**
* Constructor.
*
* @param comparison the Comparison type
* @param date the date to be compared
*/
public SentDateTerm(int comparison, Date date) {
super(comparison, date);
}
/**
* The match method.
*
* @param msg the date comparator is applied to this Message's
* sent date
* @return true if the comparison succeeds, otherwise false
*/
public boolean match(Message msg) {
Date d;
try {
d = msg.getSentDate();
} catch (Exception e) {
return false;
}
if (d == null)
return false;
return super.match(d);
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof SentDateTerm))
return false;
return super.equals(obj);
}
}
@@ -0,0 +1,94 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
import javax.mail.Message;
/**
* This class implements comparisons for Message sizes.
*
* @author Bill Shannon
* @author John Mani
*/
public final class SizeTerm extends IntegerComparisonTerm {
private static final long serialVersionUID = -2556219451005103709L;
/**
* Constructor.
*
* @param comparison the Comparison type
* @param size the size
*/
public SizeTerm(int comparison, int size) {
super(comparison, size);
}
/**
* The match method.
*
* @param msg the size comparator is applied to this Message's size
* @return true if the size is equal, otherwise false
*/
public boolean match(Message msg) {
int size;
try {
size = msg.getSize();
} catch (Exception e) {
return false;
}
if (size == -1)
return false;
return super.match(size);
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof SizeTerm))
return false;
return super.equals(obj);
}
}
@@ -0,0 +1,123 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.mail.search;
/**
* This class implements the match method for Strings. The current
* implementation provides only for substring matching. We
* could add comparisons (like strcmp ...).
*
* @author Bill Shannon
* @author John Mani
*/
public abstract class StringTerm extends SearchTerm {
/**
* The pattern.
*
* @serial
*/
protected String pattern;
/**
* Ignore case when comparing?
*
* @serial
*/
protected boolean ignoreCase;
private static final long serialVersionUID = 1274042129007696269L;
protected StringTerm(String pattern) {
this.pattern = pattern;
ignoreCase = true;
}
protected StringTerm(String pattern, boolean ignoreCase) {
this.pattern = pattern;
this.ignoreCase = ignoreCase;
}
/**
* Return the string to match with.
*/
public String getPattern() {
return pattern;
}
/**
* Return true if we should ignore case when matching.
*/
public boolean getIgnoreCase() {
return ignoreCase;
}
protected boolean match(String s) {
int len = s.length() - pattern.length();
for (int i=0; i <= len; i++) {
if (s.regionMatches(ignoreCase, i,
pattern, 0, pattern.length()))
return true;
}
return false;
}
/**
* Equality comparison.
*/
public boolean equals(Object obj) {
if (!(obj instanceof StringTerm))
return false;
StringTerm st = (StringTerm)obj;
if (ignoreCase)
return st.pattern.equalsIgnoreCase(this.pattern) &&
st.ignoreCase == this.ignoreCase;
else
return st.pattern.equals(this.pattern) &&
st.ignoreCase == this.ignoreCase;
}
/**
* Compute a hashCode for this object.
*/
public int hashCode() {
return ignoreCase ? pattern.hashCode() : ~pattern.hashCode();
}
}

Some files were not shown because too many files have changed in this diff Show More