first commit

This commit is contained in:
MaddoScientisto 2026-03-14 20:04:39 +01:00
commit 4d332ef662
27586 changed files with 3281783 additions and 0 deletions

View file

@ -0,0 +1,13 @@
package javax.mail;
import java.io.Serializable;
public abstract class Address implements Serializable {
private static final long serialVersionUID = -5822459626751992278L;
public abstract String getType();
public abstract String toString();
public abstract boolean equals(Object paramObject);
}

View file

@ -0,0 +1,15 @@
package javax.mail;
public class AuthenticationFailedException extends MessagingException {
private static final long serialVersionUID = 492080754054436511L;
public AuthenticationFailedException() {}
public AuthenticationFailedException(String message) {
super(message);
}
public AuthenticationFailedException(String message, Exception e) {
super(message, e);
}
}

View file

@ -0,0 +1,48 @@
package javax.mail;
import java.net.InetAddress;
public abstract class Authenticator {
private InetAddress requestingSite;
private int requestingPort;
private String requestingProtocol;
private String requestingPrompt;
private String requestingUserName;
final synchronized PasswordAuthentication requestPasswordAuthentication(InetAddress addr, int port, String protocol, String prompt, String defaultUserName) {
this.requestingSite = addr;
this.requestingPort = port;
this.requestingProtocol = protocol;
this.requestingPrompt = prompt;
this.requestingUserName = defaultUserName;
return getPasswordAuthentication();
}
protected final InetAddress getRequestingSite() {
return this.requestingSite;
}
protected final int getRequestingPort() {
return this.requestingPort;
}
protected final String getRequestingProtocol() {
return this.requestingProtocol;
}
protected final String getRequestingPrompt() {
return this.requestingPrompt;
}
protected final String getDefaultUserName() {
return this.requestingUserName;
}
protected PasswordAuthentication getPasswordAuthentication() {
return null;
}
}

View file

@ -0,0 +1,13 @@
package javax.mail;
public abstract class BodyPart implements Part {
protected Multipart parent;
public Multipart getParent() {
return this.parent;
}
void setParent(Multipart parent) {
this.parent = parent;
}
}

View file

@ -0,0 +1,5 @@
package javax.mail;
public interface EncodingAware {
String getEncoding();
}

View file

@ -0,0 +1,102 @@
package javax.mail;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import javax.mail.event.MailEvent;
class EventQueue implements Runnable {
private volatile BlockingQueue<QueueElement> q;
private Executor executor;
private static WeakHashMap<ClassLoader, EventQueue> appq;
static class TerminatorEvent extends MailEvent {
private static final long serialVersionUID = -2481895000841664111L;
TerminatorEvent() {
super(new Object());
}
public void dispatch(Object listener) {
Thread.currentThread().interrupt();
}
}
static class QueueElement {
MailEvent event = null;
Vector vector = null;
QueueElement(MailEvent event, Vector vector) {
this.event = event;
this.vector = vector;
}
}
EventQueue(Executor ex) {
this.executor = ex;
}
synchronized void enqueue(MailEvent event, Vector vector) {
if (this.q == null) {
this.q = new LinkedBlockingQueue<QueueElement>();
if (this.executor != null) {
this.executor.execute(this);
} else {
Thread qThread = new Thread(this, "JavaMail-EventQueue");
qThread.setDaemon(true);
qThread.start();
}
}
this.q.add(new QueueElement(event, vector));
}
synchronized void terminateQueue() {
if (this.q != null) {
Vector dummyListeners = new Vector();
dummyListeners.setSize(1);
this.q.add(new QueueElement(new TerminatorEvent(), dummyListeners));
this.q = null;
}
}
static synchronized EventQueue getApplicationEventQueue(Executor ex) {
ClassLoader cl = Session.getContextClassLoader();
if (appq == null)
appq = new WeakHashMap<ClassLoader, EventQueue>();
EventQueue q = appq.get(cl);
if (q == null) {
q = new EventQueue(ex);
appq.put(cl, q);
}
return q;
}
public void run() {
BlockingQueue<QueueElement> bq = this.q;
if (bq == null)
return;
try {
while (true) {
QueueElement qe = bq.take();
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)
return;
}
}
qe = null;
e = null;
v = null;
}
} catch (InterruptedException e) {}
}
}

View file

@ -0,0 +1,70 @@
package javax.mail;
import java.util.Vector;
public class FetchProfile {
private Vector specials;
private Vector headers;
public static class Item {
public static final Item ENVELOPE = new Item("ENVELOPE");
public static final Item CONTENT_INFO = new Item("CONTENT_INFO");
public static final Item SIZE = new Item("SIZE");
public static final Item FLAGS = new Item("FLAGS");
private String name;
protected Item(String name) {
this.name = name;
}
public String toString() {
return getClass().getName() + "[" + this.name + "]";
}
}
public FetchProfile() {
this.specials = null;
this.headers = null;
}
public void add(Item item) {
if (this.specials == null)
this.specials = new Vector();
this.specials.addElement(item);
}
public void add(String headerName) {
if (this.headers == null)
this.headers = new Vector();
this.headers.addElement(headerName);
}
public boolean contains(Item item) {
return (this.specials != null && this.specials.contains(item));
}
public boolean contains(String headerName) {
return (this.headers != null && this.headers.contains(headerName));
}
public Item[] getItems() {
if (this.specials == null)
return new Item[0];
Item[] s = new Item[this.specials.size()];
this.specials.copyInto(s);
return s;
}
public String[] getHeaderNames() {
if (this.headers == null)
return new String[0];
String[] s = new String[this.headers.size()];
this.headers.copyInto(s);
return s;
}
}

View file

@ -0,0 +1,209 @@
package javax.mail;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Vector;
public class Flags implements Cloneable, Serializable {
private int system_flags = 0;
private Hashtable user_flags = null;
private static final int ANSWERED_BIT = 1;
private static final int DELETED_BIT = 2;
private static final int DRAFT_BIT = 4;
private static final int FLAGGED_BIT = 8;
private static final int RECENT_BIT = 16;
private static final int SEEN_BIT = 32;
private static final int USER_BIT = -2147483648;
private static final long serialVersionUID = 6243590407214169028L;
public Flags() {}
public static final class Flag {
public static final Flag ANSWERED = new Flag(1);
public static final Flag DELETED = new Flag(2);
public static final Flag DRAFT = new Flag(4);
public static final Flag FLAGGED = new Flag(8);
public static final Flag RECENT = new Flag(16);
public static final Flag SEEN = new Flag(32);
public static final Flag USER = new Flag(Integer.MIN_VALUE);
private int bit;
private Flag(int bit) {
this.bit = bit;
}
}
public Flags(Flags flags) {
this.system_flags = flags.system_flags;
if (flags.user_flags != null)
this.user_flags = (Hashtable)flags.user_flags.clone();
}
public Flags(Flag flag) {
this.system_flags |= flag.bit;
}
public Flags(String flag) {
this.user_flags = new Hashtable(1);
this.user_flags.put(flag.toLowerCase(Locale.ENGLISH), flag);
}
public void add(Flag flag) {
this.system_flags |= flag.bit;
}
public void add(String flag) {
if (this.user_flags == null)
this.user_flags = new Hashtable(1);
this.user_flags.put(flag.toLowerCase(Locale.ENGLISH), flag);
}
public void add(Flags f) {
this.system_flags |= f.system_flags;
if (f.user_flags != null) {
if (this.user_flags == null)
this.user_flags = new Hashtable(1);
Enumeration<String> e = f.user_flags.keys();
while (e.hasMoreElements()) {
String s = e.nextElement();
this.user_flags.put(s, f.user_flags.get(s));
}
}
}
public void remove(Flag flag) {
this.system_flags &= flag.bit ^ 0xFFFFFFFF;
}
public void remove(String flag) {
if (this.user_flags != null)
this.user_flags.remove(flag.toLowerCase(Locale.ENGLISH));
}
public void remove(Flags f) {
this.system_flags &= f.system_flags ^ 0xFFFFFFFF;
if (f.user_flags != null) {
if (this.user_flags == null)
return;
Enumeration e = f.user_flags.keys();
while (e.hasMoreElements())
this.user_flags.remove(e.nextElement());
}
}
public boolean contains(Flag flag) {
return ((this.system_flags & flag.bit) != 0);
}
public boolean contains(String flag) {
if (this.user_flags == null)
return false;
return this.user_flags.containsKey(flag.toLowerCase(Locale.ENGLISH));
}
public boolean contains(Flags f) {
if ((f.system_flags & this.system_flags) != f.system_flags)
return false;
if (f.user_flags != null) {
if (this.user_flags == null)
return false;
Enumeration e = f.user_flags.keys();
while (e.hasMoreElements()) {
if (!this.user_flags.containsKey(e.nextElement()))
return false;
}
}
return true;
}
public boolean equals(Object obj) {
if (!(obj instanceof Flags))
return false;
Flags f = (Flags)obj;
if (f.system_flags != this.system_flags)
return false;
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;
}
public int hashCode() {
int hash = this.system_flags;
if (this.user_flags != null) {
Enumeration<String> e = this.user_flags.keys();
while (e.hasMoreElements())
hash += e.nextElement().hashCode();
}
return hash;
}
public Flag[] getSystemFlags() {
Vector<Flag> v = new Vector();
if ((this.system_flags & 0x1) != 0)
v.addElement(Flag.ANSWERED);
if ((this.system_flags & 0x2) != 0)
v.addElement(Flag.DELETED);
if ((this.system_flags & 0x4) != 0)
v.addElement(Flag.DRAFT);
if ((this.system_flags & 0x8) != 0)
v.addElement(Flag.FLAGGED);
if ((this.system_flags & 0x10) != 0)
v.addElement(Flag.RECENT);
if ((this.system_flags & 0x20) != 0)
v.addElement(Flag.SEEN);
if ((this.system_flags & Integer.MIN_VALUE) != 0)
v.addElement(Flag.USER);
Flag[] f = new Flag[v.size()];
v.copyInto(f);
return f;
}
public String[] getUserFlags() {
Vector v = new Vector();
if (this.user_flags != null) {
Enumeration e = this.user_flags.elements();
while (e.hasMoreElements())
v.addElement(e.nextElement());
}
String[] f = new String[v.size()];
v.copyInto(f);
return f;
}
public Object clone() {
Flags f = null;
try {
f = (Flags)super.clone();
} catch (CloneNotSupportedException e) {}
if (this.user_flags != null)
f.user_flags = (Hashtable)this.user_flags.clone();
return f;
}
}

View file

@ -0,0 +1,362 @@
package javax.mail;
import java.util.Vector;
import java.util.concurrent.Executor;
import javax.mail.event.ConnectionEvent;
import javax.mail.event.ConnectionListener;
import javax.mail.event.FolderEvent;
import javax.mail.event.FolderListener;
import javax.mail.event.MailEvent;
import javax.mail.event.MessageChangedEvent;
import javax.mail.event.MessageChangedListener;
import javax.mail.event.MessageCountEvent;
import javax.mail.event.MessageCountListener;
import javax.mail.search.SearchTerm;
public abstract class Folder {
protected Store store;
protected int mode = -1;
private final EventQueue q;
public static final int HOLDS_MESSAGES = 1;
public static final int HOLDS_FOLDERS = 2;
public static final int READ_ONLY = 1;
public static final int READ_WRITE = 2;
protected Folder(Store store) {
this.store = store;
Session session = store.getSession();
String scope = session.getProperties().getProperty("mail.event.scope", "folder");
Executor executor = (Executor)
session.getProperties().get("mail.event.executor");
if (scope.equalsIgnoreCase("application")) {
this.q = EventQueue.getApplicationEventQueue(executor);
} else if (scope.equalsIgnoreCase("session")) {
this.q = session.getEventQueue();
} else if (scope.equalsIgnoreCase("store")) {
this.q = store.getEventQueue();
} else {
this.q = new EventQueue(executor);
}
}
public abstract String getName();
public abstract String getFullName();
public URLName getURLName() throws MessagingException {
URLName storeURL = getStore().getURLName();
String fullname = getFullName();
StringBuffer encodedName = new StringBuffer();
if (fullname != null)
encodedName.append(fullname);
return new URLName(storeURL.getProtocol(), storeURL.getHost(),
storeURL.getPort(), encodedName.toString(),
storeURL.getUsername(), null);
}
public Store getStore() {
return this.store;
}
public abstract Folder getParent() throws MessagingException;
public abstract boolean exists() throws MessagingException;
public abstract Folder[] list(String paramString) throws MessagingException;
public Folder[] listSubscribed(String pattern) throws MessagingException {
return list(pattern);
}
public Folder[] list() throws MessagingException {
return list("%");
}
public Folder[] listSubscribed() throws MessagingException {
return listSubscribed("%");
}
public abstract char getSeparator() throws MessagingException;
public abstract int getType() throws MessagingException;
public abstract boolean create(int paramInt) throws MessagingException;
public boolean isSubscribed() {
return true;
}
public void setSubscribed(boolean subscribe) throws MessagingException {
throw new MethodNotSupportedException();
}
public abstract boolean hasNewMessages() throws MessagingException;
public abstract Folder getFolder(String paramString) throws MessagingException;
public abstract boolean delete(boolean paramBoolean) throws MessagingException;
public abstract boolean renameTo(Folder paramFolder) throws MessagingException;
public abstract void open(int paramInt) throws MessagingException;
public abstract void close(boolean paramBoolean) throws MessagingException;
public abstract boolean isOpen();
public synchronized int getMode() {
if (!isOpen())
throw new IllegalStateException("Folder not open");
return this.mode;
}
public abstract Flags getPermanentFlags();
public abstract int getMessageCount() throws MessagingException;
public synchronized int getNewMessageCount() throws MessagingException {
if (!isOpen())
return -1;
int newmsgs = 0;
int total = getMessageCount();
for (int i = 1; i <= total; i++) {
try {
if (getMessage(i).isSet(Flags.Flag.RECENT))
newmsgs++;
} catch (MessageRemovedException me) {}
}
return newmsgs;
}
public synchronized int getUnreadMessageCount() throws MessagingException {
if (!isOpen())
return -1;
int unread = 0;
int total = getMessageCount();
for (int i = 1; i <= total; i++) {
try {
if (!getMessage(i).isSet(Flags.Flag.SEEN))
unread++;
} catch (MessageRemovedException me) {}
}
return unread;
}
public synchronized int getDeletedMessageCount() throws MessagingException {
if (!isOpen())
return -1;
int deleted = 0;
int total = getMessageCount();
for (int i = 1; i <= total; i++) {
try {
if (getMessage(i).isSet(Flags.Flag.DELETED))
deleted++;
} catch (MessageRemovedException me) {}
}
return deleted;
}
public abstract Message getMessage(int paramInt) throws MessagingException;
public synchronized Message[] getMessages(int start, int end) throws MessagingException {
Message[] msgs = new Message[end - start + 1];
for (int i = start; i <= end; i++)
msgs[i - start] = getMessage(i);
return msgs;
}
public synchronized Message[] getMessages(int[] msgnums) throws MessagingException {
int len = msgnums.length;
Message[] msgs = new Message[len];
for (int i = 0; i < len; i++)
msgs[i] = getMessage(msgnums[i]);
return msgs;
}
public synchronized Message[] getMessages() throws MessagingException {
if (!isOpen())
throw new IllegalStateException("Folder not open");
int total = getMessageCount();
Message[] msgs = new Message[total];
for (int i = 1; i <= total; i++)
msgs[i - 1] = getMessage(i);
return msgs;
}
public abstract void appendMessages(Message[] paramArrayOfMessage) throws MessagingException;
public void fetch(Message[] msgs, FetchProfile fp) throws MessagingException {}
public synchronized void setFlags(Message[] msgs, Flags flag, boolean value) throws MessagingException {
for (int i = 0; i < msgs.length; i++) {
try {
msgs[i].setFlags(flag, value);
} catch (MessageRemovedException e) {}
}
}
public synchronized void setFlags(int start, int end, Flags flag, boolean value) throws MessagingException {
for (int i = start; i <= end; i++) {
try {
Message msg = getMessage(i);
msg.setFlags(flag, value);
} catch (MessageRemovedException e) {}
}
}
public synchronized void setFlags(int[] msgnums, Flags flag, boolean value) throws MessagingException {
for (int i = 0; i < msgnums.length; i++) {
try {
Message msg = getMessage(msgnums[i]);
msg.setFlags(flag, value);
} catch (MessageRemovedException e) {}
}
}
public void copyMessages(Message[] msgs, Folder folder) throws MessagingException {
if (!folder.exists())
throw new FolderNotFoundException(
folder.getFullName() + " does not exist", folder);
folder.appendMessages(msgs);
}
public abstract Message[] expunge() throws MessagingException;
public Message[] search(SearchTerm term) throws MessagingException {
return search(term, getMessages());
}
public Message[] search(SearchTerm term, Message[] msgs) throws MessagingException {
Vector<Message> matchedMsgs = new Vector();
for (int i = 0; i < msgs.length; i++) {
try {
if (msgs[i].match(term))
matchedMsgs.addElement(msgs[i]);
} catch (MessageRemovedException e) {}
}
Message[] m = new Message[matchedMsgs.size()];
matchedMsgs.copyInto(m);
return m;
}
private volatile Vector connectionListeners = null;
public synchronized void addConnectionListener(ConnectionListener l) {
if (this.connectionListeners == null)
this.connectionListeners = new Vector();
this.connectionListeners.addElement(l);
}
public synchronized void removeConnectionListener(ConnectionListener l) {
if (this.connectionListeners != null)
this.connectionListeners.removeElement(l);
}
protected void notifyConnectionListeners(int type) {
if (this.connectionListeners != null) {
ConnectionEvent e = new ConnectionEvent(this, type);
queueEvent(e, this.connectionListeners);
}
if (type == 3)
this.q.terminateQueue();
}
private volatile Vector folderListeners = null;
public synchronized void addFolderListener(FolderListener l) {
if (this.folderListeners == null)
this.folderListeners = new Vector();
this.folderListeners.addElement(l);
}
public synchronized void removeFolderListener(FolderListener l) {
if (this.folderListeners != null)
this.folderListeners.removeElement(l);
}
protected void notifyFolderListeners(int type) {
if (this.folderListeners != null) {
FolderEvent e = new FolderEvent(this, this, type);
queueEvent(e, this.folderListeners);
}
this.store.notifyFolderListeners(type, this);
}
protected void notifyFolderRenamedListeners(Folder folder) {
if (this.folderListeners != null) {
FolderEvent e = new FolderEvent(this, this, folder, 3);
queueEvent(e, this.folderListeners);
}
this.store.notifyFolderRenamedListeners(this, folder);
}
private volatile Vector messageCountListeners = null;
public synchronized void addMessageCountListener(MessageCountListener l) {
if (this.messageCountListeners == null)
this.messageCountListeners = new Vector();
this.messageCountListeners.addElement(l);
}
public synchronized void removeMessageCountListener(MessageCountListener l) {
if (this.messageCountListeners != null)
this.messageCountListeners.removeElement(l);
}
protected void notifyMessageAddedListeners(Message[] msgs) {
if (this.messageCountListeners == null)
return;
MessageCountEvent e = new MessageCountEvent(this, 1, false, msgs);
queueEvent(e, this.messageCountListeners);
}
protected void notifyMessageRemovedListeners(boolean removed, Message[] msgs) {
if (this.messageCountListeners == null)
return;
MessageCountEvent e = new MessageCountEvent(this, 2, removed, msgs);
queueEvent(e, this.messageCountListeners);
}
private volatile Vector messageChangedListeners = null;
public synchronized void addMessageChangedListener(MessageChangedListener l) {
if (this.messageChangedListeners == null)
this.messageChangedListeners = new Vector();
this.messageChangedListeners.addElement(l);
}
public synchronized void removeMessageChangedListener(MessageChangedListener l) {
if (this.messageChangedListeners != null)
this.messageChangedListeners.removeElement(l);
}
protected void notifyMessageChangedListeners(int type, Message msg) {
if (this.messageChangedListeners == null)
return;
MessageChangedEvent e = new MessageChangedEvent(this, type, msg);
queueEvent(e, this.messageChangedListeners);
}
private void queueEvent(MailEvent event, Vector vector) {
Vector v = (Vector)vector.clone();
this.q.enqueue(event, v);
}
protected void finalize() throws Throwable {
super.finalize();
this.q.terminateQueue();
}
public String toString() {
String s = getFullName();
if (s != null)
return s;
return super.toString();
}
}

View file

@ -0,0 +1,25 @@
package javax.mail;
public class FolderClosedException extends MessagingException {
private transient Folder folder;
private static final long serialVersionUID = 1687879213433302315L;
public FolderClosedException(Folder folder) {
this(folder, null);
}
public FolderClosedException(Folder folder, String message) {
super(message);
this.folder = folder;
}
public FolderClosedException(Folder folder, String message, Exception e) {
super(message, e);
this.folder = folder;
}
public Folder getFolder() {
return this.folder;
}
}

View file

@ -0,0 +1,32 @@
package javax.mail;
public class FolderNotFoundException extends MessagingException {
private transient Folder folder;
private static final long serialVersionUID = 472612108891249403L;
public FolderNotFoundException() {}
public FolderNotFoundException(Folder folder) {
this.folder = folder;
}
public FolderNotFoundException(Folder folder, String s) {
super(s);
this.folder = folder;
}
public FolderNotFoundException(Folder folder, String s, Exception e) {
super(s, e);
this.folder = folder;
}
public FolderNotFoundException(String s, Folder folder) {
super(s);
this.folder = folder;
}
public Folder getFolder() {
return this.folder;
}
}

View file

@ -0,0 +1,20 @@
package javax.mail;
public class Header {
protected String name;
protected String value;
public Header(String name, String value) {
this.name = name;
this.value = value;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
}

View file

@ -0,0 +1,15 @@
package javax.mail;
public class IllegalWriteException extends MessagingException {
private static final long serialVersionUID = 3974370223328268013L;
public IllegalWriteException() {}
public IllegalWriteException(String s) {
super(s);
}
public IllegalWriteException(String s, Exception e) {
super(s, e);
}
}

View file

@ -0,0 +1,28 @@
package javax.mail;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MailSessionDefinition {
String description() default "";
String name();
String storeProtocol() default "";
String transportProtocol() default "";
String host() default "";
String user() default "";
String password() default "";
String from() default "";
String[] properties() default {};
}

View file

@ -0,0 +1,12 @@
package javax.mail;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MailSessionDefinitions {
MailSessionDefinition[] value();
}

View file

@ -0,0 +1,170 @@
package javax.mail;
import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Date;
import javax.mail.search.SearchTerm;
public abstract class Message implements Part {
protected int msgnum = 0;
protected boolean expunged = false;
protected Folder folder = null;
protected Session session = null;
protected Message() {}
protected Message(Folder folder, int msgnum) {
this.folder = folder;
this.msgnum = msgnum;
this.session = folder.store.session;
}
protected Message(Session session) {
this.session = session;
}
public Session getSession() {
return this.session;
}
public abstract Address[] getFrom() throws MessagingException;
public abstract void setFrom() throws MessagingException;
public abstract void setFrom(Address paramAddress) throws MessagingException;
public abstract void addFrom(Address[] paramArrayOfAddress) throws MessagingException;
public abstract Address[] getRecipients(RecipientType paramRecipientType) throws MessagingException;
public static class RecipientType implements Serializable {
public static final RecipientType TO = new RecipientType("To");
public static final RecipientType CC = new RecipientType("Cc");
public static final RecipientType BCC = new RecipientType("Bcc");
protected String type;
private static final long serialVersionUID = -7479791750606340008L;
protected RecipientType(String type) {
this.type = type;
}
protected Object readResolve() throws ObjectStreamException {
if (this.type.equals("To"))
return TO;
if (this.type.equals("Cc"))
return CC;
if (this.type.equals("Bcc"))
return BCC;
throw new InvalidObjectException("Attempt to resolve unknown RecipientType: " + this.type);
}
public String toString() {
return this.type;
}
}
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;
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);
return addresses;
}
public abstract void setRecipients(RecipientType paramRecipientType, Address[] paramArrayOfAddress) throws MessagingException;
public void setRecipient(RecipientType type, Address address) throws MessagingException {
Address[] a = new Address[1];
a[0] = address;
setRecipients(type, a);
}
public abstract void addRecipients(RecipientType paramRecipientType, Address[] paramArrayOfAddress) throws MessagingException;
public void addRecipient(RecipientType type, Address address) throws MessagingException {
Address[] a = new Address[1];
a[0] = address;
addRecipients(type, a);
}
public Address[] getReplyTo() throws MessagingException {
return getFrom();
}
public void setReplyTo(Address[] addresses) throws MessagingException {
throw new MethodNotSupportedException("setReplyTo not supported");
}
public abstract String getSubject() throws MessagingException;
public abstract void setSubject(String paramString) throws MessagingException;
public abstract Date getSentDate() throws MessagingException;
public abstract void setSentDate(Date paramDate) throws MessagingException;
public abstract Date getReceivedDate() throws MessagingException;
public abstract Flags getFlags() throws MessagingException;
public boolean isSet(Flags.Flag flag) throws MessagingException {
return getFlags().contains(flag);
}
public abstract void setFlags(Flags paramFlags, boolean paramBoolean) throws MessagingException;
public void setFlag(Flags.Flag flag, boolean set) throws MessagingException {
Flags f = new Flags(flag);
setFlags(f, set);
}
public int getMessageNumber() {
return this.msgnum;
}
protected void setMessageNumber(int msgnum) {
this.msgnum = msgnum;
}
public Folder getFolder() {
return this.folder;
}
public boolean isExpunged() {
return this.expunged;
}
protected void setExpunged(boolean expunged) {
this.expunged = expunged;
}
public abstract Message reply(boolean paramBoolean) throws MessagingException;
public abstract void saveChanges() throws MessagingException;
public boolean match(SearchTerm term) throws MessagingException {
return term.match(this);
}
}

View file

@ -0,0 +1,5 @@
package javax.mail;
public interface MessageAware {
MessageContext getMessageContext();
}

View file

@ -0,0 +1,39 @@
package javax.mail;
public class MessageContext {
private Part part;
public MessageContext(Part part) {
this.part = part;
}
public Part getPart() {
return this.part;
}
public Message getMessage() {
try {
return getMessage(this.part);
} catch (MessagingException ex) {
return null;
}
}
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)
return null;
p = mp.getParent();
}
return null;
}
public Session getSession() {
Message msg = getMessage();
return (msg != null) ? msg.getSession() : null;
}
}

View file

@ -0,0 +1,15 @@
package javax.mail;
public class MessageRemovedException extends MessagingException {
private static final long serialVersionUID = 1951292550679528690L;
public MessageRemovedException() {}
public MessageRemovedException(String s) {
super(s);
}
public MessageRemovedException(String s, Exception e) {
super(s, e);
}
}

View file

@ -0,0 +1,65 @@
package javax.mail;
public class MessagingException extends Exception {
private Exception next;
private static final long serialVersionUID = -7569192289819959253L;
public MessagingException() {
initCause(null);
}
public MessagingException(String s) {
super(s);
initCause(null);
}
public MessagingException(String s, Exception e) {
super(s);
this.next = e;
initCause(null);
}
public synchronized Exception getNextException() {
return this.next;
}
public synchronized Throwable getCause() {
return this.next;
}
public synchronized boolean setNextException(Exception ex) {
Exception theEnd = this;
while (theEnd instanceof MessagingException && ((MessagingException)theEnd).next != null)
theEnd = ((MessagingException)theEnd).next;
if (theEnd instanceof MessagingException) {
((MessagingException)theEnd).next = ex;
return true;
}
return false;
}
public synchronized String toString() {
String s = super.toString();
Exception n = this.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;
continue;
}
sb.append(n.toString());
n = null;
}
return sb.toString();
}
private final String superToString() {
return super.toString();
}
}

View file

@ -0,0 +1,15 @@
package javax.mail;
public class MethodNotSupportedException extends MessagingException {
private static final long serialVersionUID = -3757386618726131322L;
public MethodNotSupportedException() {}
public MethodNotSupportedException(String s) {
super(s);
}
public MethodNotSupportedException(String s, Exception e) {
super(s, e);
}
}

View file

@ -0,0 +1,76 @@
package javax.mail;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Vector;
public abstract class Multipart {
protected Vector parts = new Vector();
protected String contentType = "multipart/mixed";
protected Part parent;
protected synchronized void setMultipartDataSource(MultipartDataSource mp) throws MessagingException {
this.contentType = mp.getContentType();
int count = mp.getCount();
for (int i = 0; i < count; i++)
addBodyPart(mp.getBodyPart(i));
}
public synchronized String getContentType() {
return this.contentType;
}
public synchronized int getCount() throws MessagingException {
if (this.parts == null)
return 0;
return this.parts.size();
}
public synchronized BodyPart getBodyPart(int index) throws MessagingException {
if (this.parts == null)
throw new IndexOutOfBoundsException("No such BodyPart");
return this.parts.elementAt(index);
}
public synchronized boolean removeBodyPart(BodyPart part) throws MessagingException {
if (this.parts == null)
throw new MessagingException("No such body part");
boolean ret = this.parts.removeElement(part);
part.setParent(null);
return ret;
}
public synchronized void removeBodyPart(int index) throws MessagingException {
if (this.parts == null)
throw new IndexOutOfBoundsException("No such BodyPart");
BodyPart part = this.parts.elementAt(index);
this.parts.removeElementAt(index);
part.setParent(null);
}
public synchronized void addBodyPart(BodyPart part) throws MessagingException {
if (this.parts == null)
this.parts = new Vector();
this.parts.addElement(part);
part.setParent(this);
}
public synchronized void addBodyPart(BodyPart part, int index) throws MessagingException {
if (this.parts == null)
this.parts = new Vector();
this.parts.insertElementAt(part, index);
part.setParent(this);
}
public abstract void writeTo(OutputStream paramOutputStream) throws IOException, MessagingException;
public synchronized Part getParent() {
return this.parent;
}
public synchronized void setParent(Part parent) {
this.parent = parent;
}
}

View file

@ -0,0 +1,9 @@
package javax.mail;
import javax.activation.DataSource;
public interface MultipartDataSource extends DataSource {
int getCount();
BodyPart getBodyPart(int paramInt) throws MessagingException;
}

View file

@ -0,0 +1,15 @@
package javax.mail;
public class NoSuchProviderException extends MessagingException {
private static final long serialVersionUID = 8058319293154708827L;
public NoSuchProviderException() {}
public NoSuchProviderException(String message) {
super(message);
}
public NoSuchProviderException(String message, Exception e) {
super(message, e);
}
}

View file

@ -0,0 +1,63 @@
package javax.mail;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import javax.activation.DataHandler;
public interface Part {
public static final String ATTACHMENT = "attachment";
public static final String INLINE = "inline";
int getSize() throws MessagingException;
int getLineCount() throws MessagingException;
String getContentType() throws MessagingException;
boolean isMimeType(String paramString) throws MessagingException;
String getDisposition() throws MessagingException;
void setDisposition(String paramString) throws MessagingException;
String getDescription() throws MessagingException;
void setDescription(String paramString) throws MessagingException;
String getFileName() throws MessagingException;
void setFileName(String paramString) throws MessagingException;
InputStream getInputStream() throws IOException, MessagingException;
DataHandler getDataHandler() throws MessagingException;
Object getContent() throws IOException, MessagingException;
void setDataHandler(DataHandler paramDataHandler) throws MessagingException;
void setContent(Object paramObject, String paramString) throws MessagingException;
void setText(String paramString) throws MessagingException;
void setContent(Multipart paramMultipart) throws MessagingException;
void writeTo(OutputStream paramOutputStream) throws IOException, MessagingException;
String[] getHeader(String paramString) throws MessagingException;
void setHeader(String paramString1, String paramString2) throws MessagingException;
void addHeader(String paramString1, String paramString2) throws MessagingException;
void removeHeader(String paramString) throws MessagingException;
Enumeration getAllHeaders() throws MessagingException;
Enumeration getMatchingHeaders(String[] paramArrayOfString) throws MessagingException;
Enumeration getNonMatchingHeaders(String[] paramArrayOfString) throws MessagingException;
}

View file

@ -0,0 +1,20 @@
package javax.mail;
public final class PasswordAuthentication {
private final String userName;
private final String password;
public PasswordAuthentication(String userName, String password) {
this.userName = userName;
this.password = password;
}
public String getUserName() {
return this.userName;
}
public String getPassword() {
return this.password;
}
}

View file

@ -0,0 +1,67 @@
package javax.mail;
public class Provider {
private Type type;
private String protocol;
private String className;
private String vendor;
private String version;
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 this.type;
}
}
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;
}
public Type getType() {
return this.type;
}
public String getProtocol() {
return this.protocol;
}
public String getClassName() {
return this.className;
}
public String getVendor() {
return this.vendor;
}
public String getVersion() {
return this.version;
}
public String toString() {
String s = "javax.mail.Provider[" + this.type + "," + this.protocol + "," + this.className;
if (this.vendor != null)
s = s + "," + this.vendor;
if (this.version != null)
s = s + "," + this.version;
s = s + "]";
return s;
}
}

View file

@ -0,0 +1,43 @@
package javax.mail;
public class Quota {
public String quotaRoot;
public Resource[] resources;
public static class Resource {
public String name;
public long usage;
public long limit;
public Resource(String name, long usage, long limit) {
this.name = name;
this.usage = usage;
this.limit = limit;
}
}
public Quota(String quotaRoot) {
this.quotaRoot = quotaRoot;
}
public void setResourceLimit(String name, long limit) {
if (this.resources == null) {
this.resources = new Resource[1];
this.resources[0] = new Resource(name, 0L, limit);
return;
}
for (int i = 0; i < this.resources.length; i++) {
if ((this.resources[i]).name.equalsIgnoreCase(name)) {
(this.resources[i]).limit = limit;
return;
}
}
Resource[] ra = new Resource[this.resources.length + 1];
System.arraycopy(this.resources, 0, ra, 0, this.resources.length);
ra[ra.length - 1] = new Resource(name, 0L, limit);
this.resources = ra;
}
}

View file

@ -0,0 +1,7 @@
package javax.mail;
public interface QuotaAwareStore {
Quota[] getQuota(String paramString) throws MessagingException;
void setQuota(Quota paramQuota) throws MessagingException;
}

View file

@ -0,0 +1,25 @@
package javax.mail;
public class ReadOnlyFolderException extends MessagingException {
private transient Folder folder;
private static final long serialVersionUID = 5711829372799039325L;
public ReadOnlyFolderException(Folder folder) {
this(folder, null);
}
public ReadOnlyFolderException(Folder folder, String message) {
super(message);
this.folder = folder;
}
public ReadOnlyFolderException(Folder folder, String message, Exception e) {
super(message, e);
this.folder = folder;
}
public Folder getFolder() {
return this.folder;
}
}

View file

@ -0,0 +1,40 @@
package javax.mail;
public class SendFailedException extends MessagingException {
protected transient Address[] invalid;
protected transient Address[] validSent;
protected transient Address[] validUnsent;
private static final long serialVersionUID = -6457531621682372913L;
public SendFailedException() {}
public SendFailedException(String s) {
super(s);
}
public SendFailedException(String s, Exception e) {
super(s, e);
}
public SendFailedException(String msg, Exception ex, Address[] validSent, Address[] validUnsent, Address[] invalid) {
super(msg, ex);
this.validSent = validSent;
this.validUnsent = validUnsent;
this.invalid = invalid;
}
public Address[] getValidSentAddresses() {
return this.validSent;
}
public Address[] getValidUnsentAddresses() {
return this.validUnsent;
}
public Address[] getInvalidAddresses() {
return this.invalid;
}
}

View file

@ -0,0 +1,237 @@
package javax.mail;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Vector;
import java.util.concurrent.Executor;
import javax.mail.event.ConnectionEvent;
import javax.mail.event.ConnectionListener;
import javax.mail.event.MailEvent;
public abstract class Service {
protected Session session;
protected URLName url = null;
protected boolean debug = false;
private boolean connected = false;
private final Vector connectionListeners = new Vector();
private final EventQueue q;
protected Service(Session session, URLName urlname) {
this.session = session;
this.debug = session.getDebug();
this.url = urlname;
String protocol = null;
String host = null;
int port = -1;
String user = null;
String password = null;
String file = null;
if (this.url != null) {
protocol = this.url.getProtocol();
host = this.url.getHost();
port = this.url.getPort();
user = this.url.getUsername();
password = this.url.getPassword();
file = this.url.getFile();
}
if (protocol != null) {
if (host == null)
host = session.getProperty("mail." + protocol + ".host");
if (user == null)
user = session.getProperty("mail." + protocol + ".user");
}
if (host == null)
host = session.getProperty("mail.host");
if (user == null)
user = session.getProperty("mail.user");
if (user == null)
try {
user = System.getProperty("user.name");
} catch (SecurityException e) {}
this.url = new URLName(protocol, host, port, file, user, password);
String scope = session.getProperties().getProperty("mail.event.scope", "folder");
Executor executor = (Executor)
session.getProperties().get("mail.event.executor");
if (scope.equalsIgnoreCase("application")) {
this.q = EventQueue.getApplicationEventQueue(executor);
} else if (scope.equalsIgnoreCase("session")) {
this.q = session.getEventQueue();
} else {
this.q = new EventQueue(executor);
}
}
public void connect() throws MessagingException {
connect(null, null, null);
}
public void connect(String host, String user, String password) throws MessagingException {
connect(host, -1, user, password);
}
public void connect(String user, String password) throws MessagingException {
connect(null, user, password);
}
public synchronized void connect(String host, int port, String user, String password) throws MessagingException {
if (isConnected())
throw new IllegalStateException("already connected");
boolean connected = false;
boolean save = false;
String protocol = null;
String file = null;
if (this.url != null) {
protocol = this.url.getProtocol();
if (host == null)
host = this.url.getHost();
if (port == -1)
port = this.url.getPort();
if (user == null) {
user = this.url.getUsername();
if (password == null)
password = this.url.getPassword();
} else if (password == null && user.equals(this.url.getUsername())) {
password = this.url.getPassword();
}
file = this.url.getFile();
}
if (protocol != null) {
if (host == null)
host = this.session.getProperty("mail." + protocol + ".host");
if (user == null)
user = this.session.getProperty("mail." + protocol + ".user");
}
if (host == null)
host = this.session.getProperty("mail.host");
if (user == null)
user = this.session.getProperty("mail.user");
if (user == null)
try {
user = System.getProperty("user.name");
} catch (SecurityException e) {}
if (password == null && this.url != null) {
setURLName(new URLName(protocol, host, port, file, user, null));
PasswordAuthentication pw = this.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;
}
}
AuthenticationFailedException authEx = null;
try {
connected = protocolConnect(host, port, user, password);
} catch (AuthenticationFailedException ex) {
authEx = ex;
}
if (!connected) {
InetAddress addr;
try {
addr = InetAddress.getByName(host);
} catch (UnknownHostException e) {
addr = null;
}
PasswordAuthentication pw = this.session.requestPasswordAuthentication(addr, port, protocol, null, user);
if (pw != null) {
user = pw.getUserName();
password = pw.getPassword();
connected = protocolConnect(host, port, user, password);
}
}
if (!connected) {
if (authEx != null)
throw authEx;
if (user == null)
throw new AuthenticationFailedException("failed to connect, no user name specified?");
if (password == null)
throw new AuthenticationFailedException("failed to connect, no password specified?");
throw new AuthenticationFailedException("failed to connect");
}
setURLName(new URLName(protocol, host, port, file, user, password));
if (save)
this.session.setPasswordAuthentication(getURLName(), new PasswordAuthentication(user, password));
setConnected(true);
notifyConnectionListeners(1);
}
protected boolean protocolConnect(String host, int port, String user, String password) throws MessagingException {
return false;
}
public synchronized boolean isConnected() {
return this.connected;
}
protected synchronized void setConnected(boolean connected) {
this.connected = connected;
}
public synchronized void close() throws MessagingException {
setConnected(false);
notifyConnectionListeners(3);
}
public synchronized URLName getURLName() {
if (this.url != null && (this.url.getPassword() != null || this.url.getFile() != null))
return new URLName(this.url.getProtocol(), this.url.getHost(),
this.url.getPort(), null,
this.url.getUsername(), null);
return this.url;
}
protected synchronized void setURLName(URLName url) {
this.url = url;
}
public void addConnectionListener(ConnectionListener l) {
this.connectionListeners.addElement(l);
}
public void removeConnectionListener(ConnectionListener l) {
this.connectionListeners.removeElement(l);
}
protected void notifyConnectionListeners(int type) {
if (this.connectionListeners.size() > 0) {
ConnectionEvent e = new ConnectionEvent(this, type);
queueEvent(e, this.connectionListeners);
}
if (type == 3)
this.q.terminateQueue();
}
public String toString() {
URLName url = getURLName();
if (url != null)
return url.toString();
return super.toString();
}
protected void queueEvent(MailEvent event, Vector vector) {
Vector v = (Vector)vector.clone();
this.q.enqueue(event, v);
}
protected void finalize() throws Throwable {
super.finalize();
this.q.terminateQueue();
}
Session getSession() {
return this.session;
}
EventQueue getEventQueue() {
return this.q;
}
}

View file

@ -0,0 +1,579 @@
package javax.mail;
import com.sun.mail.util.LineInputStream;
import com.sun.mail.util.MailLogger;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.net.InetAddress;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.concurrent.Executor;
import java.util.logging.Level;
public final class Session {
private final Properties props;
private final Authenticator authenticator;
private final Hashtable authTable;
private boolean debug;
private PrintStream out;
private MailLogger logger;
private final Vector providers;
private final Hashtable providersByProtocol;
private final Hashtable providersByClassName;
private final Properties addressMap;
private final EventQueue q;
private static Session defaultSession = null;
private Session(Properties props, Authenticator authenticator) {
Class<?> cl;
this.authTable = new Hashtable();
this.debug = false;
this.providers = new Vector();
this.providersByProtocol = new Hashtable();
this.providersByClassName = new Hashtable();
this.addressMap = new Properties();
this.props = props;
this.authenticator = authenticator;
if (Boolean.valueOf(props.getProperty("mail.debug")))
this.debug = true;
initLogger();
this.logger.log(Level.CONFIG, "JavaMail version {0}", "1.5.4");
if (authenticator != null) {
cl = authenticator.getClass();
} else {
cl = getClass();
}
loadProviders(cl);
loadAddressMap(cl);
this.q = new EventQueue((Executor)props.get("mail.event.executor"));
}
private final synchronized void initLogger() {
this.logger = new MailLogger(getClass(), "DEBUG", this.debug, getDebugOut());
}
public static Session getInstance(Properties props, Authenticator authenticator) {
return new Session(props, authenticator);
}
public static Session getInstance(Properties props) {
return new Session(props, null);
}
public static synchronized Session getDefaultInstance(Properties props, Authenticator authenticator) {
if (defaultSession == null) {
SecurityManager security = System.getSecurityManager();
if (security != null)
security.checkSetFactory();
defaultSession = new Session(props, authenticator);
} else if (defaultSession.authenticator != authenticator) {
if (defaultSession.authenticator == null || authenticator == null ||
defaultSession.authenticator.getClass().getClassLoader() !=
authenticator.getClass().getClassLoader())
throw new SecurityException("Access to default session denied");
}
return defaultSession;
}
public static Session getDefaultInstance(Properties props) {
return getDefaultInstance(props, null);
}
public synchronized void setDebug(boolean debug) {
this.debug = debug;
initLogger();
this.logger.log(Level.CONFIG, "setDebug: JavaMail version {0}", "1.5.4");
}
public synchronized boolean getDebug() {
return this.debug;
}
public synchronized void setDebugOut(PrintStream out) {
this.out = out;
initLogger();
}
public synchronized PrintStream getDebugOut() {
if (this.out == null)
return System.out;
return this.out;
}
public synchronized Provider[] getProviders() {
Provider[] _providers = new Provider[this.providers.size()];
this.providers.copyInto(_providers);
return _providers;
}
public synchronized Provider getProvider(String protocol) throws NoSuchProviderException {
if (protocol == null || protocol.length() <= 0)
throw new NoSuchProviderException("Invalid protocol: null");
Provider _provider = null;
String _className = this.props.getProperty("mail." + protocol + ".class");
if (_className != null) {
if (this.logger.isLoggable(Level.FINE))
this.logger.fine("mail." + protocol + ".class property exists and points to " + _className);
_provider = (Provider)this.providersByClassName.get(_className);
}
if (_provider != null)
return _provider;
_provider = (Provider)this.providersByProtocol.get(protocol);
if (_provider == null)
throw new NoSuchProviderException("No provider for " + protocol);
if (this.logger.isLoggable(Level.FINE))
this.logger.fine("getProvider() returning " + _provider.toString());
return _provider;
}
public synchronized void setProvider(Provider provider) throws NoSuchProviderException {
if (provider == null)
throw new NoSuchProviderException("Can't set null provider");
this.providersByProtocol.put(provider.getProtocol(), provider);
this.props.put("mail." + provider.getProtocol() + ".class",
provider.getClassName());
}
public Store getStore() throws NoSuchProviderException {
return getStore(getProperty("mail.store.protocol"));
}
public Store getStore(String protocol) throws NoSuchProviderException {
return getStore(new URLName(protocol, null, -1, null, null, null));
}
public Store getStore(URLName url) throws NoSuchProviderException {
String protocol = url.getProtocol();
Provider p = getProvider(protocol);
return getStore(p, url);
}
public Store getStore(Provider provider) throws NoSuchProviderException {
return getStore(provider, null);
}
private Store getStore(Provider provider, URLName url) throws NoSuchProviderException {
if (provider == null || provider.getType() != Provider.Type.STORE)
throw new NoSuchProviderException("invalid provider");
return getService(provider, url, Store.class);
}
public Folder getFolder(URLName url) throws MessagingException {
Store store = getStore(url);
store.connect();
return store.getFolder(url);
}
public Transport getTransport() throws NoSuchProviderException {
String prot = getProperty("mail.transport.protocol");
if (prot != null)
return getTransport(prot);
prot = (String)this.addressMap.get("rfc822");
if (prot != null)
return getTransport(prot);
return getTransport("smtp");
}
public Transport getTransport(String protocol) throws NoSuchProviderException {
return getTransport(new URLName(protocol, null, -1, null, null, null));
}
public Transport getTransport(URLName url) throws NoSuchProviderException {
String protocol = url.getProtocol();
Provider p = getProvider(protocol);
return getTransport(p, url);
}
public Transport getTransport(Provider provider) throws NoSuchProviderException {
return getTransport(provider, null);
}
public Transport getTransport(Address address) throws NoSuchProviderException {
String transportProtocol = getProperty("mail.transport.protocol." + address.getType());
if (transportProtocol != null)
return getTransport(transportProtocol);
transportProtocol = (String)this.addressMap.get(address.getType());
if (transportProtocol != null)
return getTransport(transportProtocol);
throw new NoSuchProviderException("No provider for Address type: " +
address.getType());
}
private Transport getTransport(Provider provider, URLName url) throws NoSuchProviderException {
if (provider == null || provider.getType() != Provider.Type.TRANSPORT)
throw new NoSuchProviderException("invalid provider");
return getService(provider, url, Transport.class);
}
private <T extends Service> T getService(Provider provider, URLName url, Class<T> type) throws NoSuchProviderException {
ClassLoader cl;
if (provider == null)
throw new NoSuchProviderException("null");
if (url == null)
url = new URLName(provider.getProtocol(), null, -1, null, null, null);
Object service = null;
if (this.authenticator != null) {
cl = this.authenticator.getClass().getClassLoader();
} else {
cl = getClass().getClassLoader();
}
Class<?> serviceClass = null;
try {
ClassLoader ccl = getContextClassLoader();
if (ccl != null)
try {
serviceClass = Class.forName(provider.getClassName(), false, ccl);
} catch (ClassNotFoundException e) {}
if (serviceClass == null || !type.isAssignableFrom(serviceClass))
serviceClass = Class.forName(provider.getClassName(), false, cl);
if (!type.isAssignableFrom(serviceClass))
throw new ClassCastException(
type.getName() + " " + serviceClass.getName());
} catch (Exception ex1) {
try {
serviceClass = Class.forName(provider.getClassName());
if (!type.isAssignableFrom(serviceClass))
throw new ClassCastException(
type.getName() + " " + serviceClass.getName());
} catch (Exception ex) {
this.logger.log(Level.FINE, "Exception loading provider", (Throwable)ex);
throw new NoSuchProviderException(provider.getProtocol());
}
}
try {
Class[] c = { Session.class, URLName.class };
Constructor<?> cons = serviceClass.getConstructor(c);
Object[] o = { this, url };
service = cons.newInstance(o);
} catch (Exception ex) {
this.logger.log(Level.FINE, "Exception loading provider", (Throwable)ex);
throw new NoSuchProviderException(provider.getProtocol());
}
return type.cast(service);
}
public void setPasswordAuthentication(URLName url, PasswordAuthentication pw) {
if (pw == null) {
this.authTable.remove(url);
} else {
this.authTable.put(url, pw);
}
}
public PasswordAuthentication getPasswordAuthentication(URLName url) {
return (PasswordAuthentication)this.authTable.get(url);
}
public PasswordAuthentication requestPasswordAuthentication(InetAddress addr, int port, String protocol, String prompt, String defaultUserName) {
if (this.authenticator != null)
return this.authenticator.requestPasswordAuthentication(addr, port, protocol, prompt, defaultUserName);
return null;
}
public Properties getProperties() {
return this.props;
}
public String getProperty(String name) {
return this.props.getProperty(name);
}
private void loadProviders(Class cl) {
StreamLoader loader = new StreamLoader() {
public void load(InputStream is) throws IOException {
Session.this.loadProvidersFromStream(is);
}
};
try {
String res = System.getProperty("java.home") + File.separator + "lib" + File.separator + "javamail.providers";
loadFile(res, loader);
} catch (SecurityException sex) {
this.logger.log(Level.CONFIG, "can't get java.home", (Throwable)sex);
}
loadAllResources("META-INF/javamail.providers", cl, loader);
loadResource("/META-INF/javamail.default.providers", cl, loader);
if (this.providers.size() == 0) {
this.logger.config("failed to load any providers, using defaults");
addProvider(new Provider(Provider.Type.STORE, "imap", "com.sun.mail.imap.IMAPStore", "Oracle", "1.5.4"));
addProvider(new Provider(Provider.Type.STORE, "imaps", "com.sun.mail.imap.IMAPSSLStore", "Oracle", "1.5.4"));
addProvider(new Provider(Provider.Type.STORE, "pop3", "com.sun.mail.pop3.POP3Store", "Oracle", "1.5.4"));
addProvider(new Provider(Provider.Type.STORE, "pop3s", "com.sun.mail.pop3.POP3SSLStore", "Oracle", "1.5.4"));
addProvider(new Provider(Provider.Type.TRANSPORT, "smtp", "com.sun.mail.smtp.SMTPTransport", "Oracle", "1.5.4"));
addProvider(new Provider(Provider.Type.TRANSPORT, "smtps", "com.sun.mail.smtp.SMTPSSLTransport", "Oracle", "1.5.4"));
}
if (this.logger.isLoggable(Level.CONFIG)) {
this.logger.config("Tables of loaded providers");
this.logger.config("Providers Listed By Class Name: " +
this.providersByClassName.toString());
this.logger.config("Providers Listed By Protocol: " +
this.providersByProtocol.toString());
}
}
private void loadProvidersFromStream(InputStream is) throws IOException {
if (is != null) {
LineInputStream lis = new LineInputStream(is);
String currLine;
while ((currLine = lis.readLine()) != null) {
if (currLine.startsWith("#"))
continue;
Provider.Type type = null;
String protocol = null, className = null;
String vendor = null, version = null;
StringTokenizer tuples = new StringTokenizer(currLine, ";");
while (tuples.hasMoreTokens()) {
String currTuple = tuples.nextToken().trim();
int sep = currTuple.indexOf("=");
if (currTuple.startsWith("protocol=")) {
protocol = currTuple.substring(sep + 1);
continue;
}
if (currTuple.startsWith("type=")) {
String strType = currTuple.substring(sep + 1);
if (strType.equalsIgnoreCase("store")) {
type = Provider.Type.STORE;
continue;
}
if (strType.equalsIgnoreCase("transport"))
type = Provider.Type.TRANSPORT;
continue;
}
if (currTuple.startsWith("class=")) {
className = currTuple.substring(sep + 1);
continue;
}
if (currTuple.startsWith("vendor=")) {
vendor = currTuple.substring(sep + 1);
continue;
}
if (currTuple.startsWith("version="))
version = currTuple.substring(sep + 1);
}
if (type == null || protocol == null || className == null ||
protocol.length() <= 0 || className.length() <= 0) {
this.logger.log(Level.CONFIG, "Bad provider entry: {0}", currLine);
continue;
}
Provider provider = new Provider(type, protocol, className, vendor, version);
addProvider(provider);
}
}
}
public synchronized void addProvider(Provider provider) {
this.providers.addElement(provider);
this.providersByClassName.put(provider.getClassName(), provider);
if (!this.providersByProtocol.containsKey(provider.getProtocol()))
this.providersByProtocol.put(provider.getProtocol(), provider);
}
private void loadAddressMap(Class cl) {
StreamLoader loader = new StreamLoader() {
public void load(InputStream is) throws IOException {
Session.this.addressMap.load(is);
}
};
loadResource("/META-INF/javamail.default.address.map", cl, loader);
loadAllResources("META-INF/javamail.address.map", cl, loader);
try {
String res = System.getProperty("java.home") + File.separator + "lib" + File.separator + "javamail.address.map";
loadFile(res, loader);
} catch (SecurityException sex) {
this.logger.log(Level.CONFIG, "can't get java.home", (Throwable)sex);
}
if (this.addressMap.isEmpty()) {
this.logger.config("failed to load address map, using defaults");
this.addressMap.put("rfc822", "smtp");
}
}
public synchronized void setProtocolForAddress(String addresstype, String protocol) {
if (protocol == null) {
this.addressMap.remove(addresstype);
} else {
this.addressMap.put(addresstype, protocol);
}
}
private void loadFile(String name, StreamLoader loader) {
InputStream clis = null;
try {
clis = new BufferedInputStream(new FileInputStream(name));
loader.load(clis);
this.logger.log(Level.CONFIG, "successfully loaded file: {0}", name);
} catch (FileNotFoundException e) {
} catch (IOException e) {
if (this.logger.isLoggable(Level.CONFIG))
this.logger.log(Level.CONFIG, "not loading file: " + name, (Throwable)e);
} catch (SecurityException sex) {
if (this.logger.isLoggable(Level.CONFIG))
this.logger.log(Level.CONFIG, "not loading file: " + name, (Throwable)sex);
} finally {
try {
if (clis != null)
clis.close();
} catch (IOException e) {}
}
}
private void loadResource(String name, Class cl, StreamLoader loader) {
InputStream clis = null;
try {
clis = getResourceAsStream(cl, name);
if (clis != null) {
loader.load(clis);
this.logger.log(Level.CONFIG, "successfully loaded resource: {0}", name);
}
} catch (IOException e) {
this.logger.log(Level.CONFIG, "Exception loading resource", (Throwable)e);
} catch (SecurityException sex) {
this.logger.log(Level.CONFIG, "Exception loading resource", (Throwable)sex);
} finally {
try {
if (clis != null)
clis.close();
} catch (IOException e) {}
}
}
private void loadAllResources(String name, Class cl, StreamLoader loader) {
boolean anyLoaded = false;
try {
URL[] urls;
ClassLoader cld = null;
cld = getContextClassLoader();
if (cld == null)
cld = cl.getClassLoader();
if (cld != null) {
urls = getResources(cld, name);
} else {
urls = getSystemResources(name);
}
if (urls != null)
for (int i = 0; i < urls.length; i++) {
URL url = urls[i];
InputStream clis = null;
this.logger.log(Level.CONFIG, "URL {0}", url);
}
} catch (Exception ex) {
this.logger.log(Level.CONFIG, "Exception loading resource", (Throwable)ex);
}
if (!anyLoaded)
loadResource("/" + name, cl, loader);
}
static ClassLoader getContextClassLoader() {
return AccessController.<ClassLoader>doPrivileged(new PrivilegedAction() {
public Object run() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (SecurityException e) {}
return cl;
}
});
}
private static InputStream getResourceAsStream(final Class c, final String name) throws IOException {
try {
return AccessController.<InputStream>doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws IOException {
return c.getResourceAsStream(name);
}
});
} catch (PrivilegedActionException e) {
throw (IOException)e.getException();
}
}
private static URL[] getResources(final ClassLoader cl, final String name) {
return AccessController.<URL[]>doPrivileged(new PrivilegedAction() {
public Object run() {
URL[] ret = null;
try {
Vector<URL> v = new Vector();
Enumeration<URL> e = cl.getResources(name);
while (e != null && e.hasMoreElements()) {
URL url = e.nextElement();
if (url != null)
v.addElement(url);
}
if (v.size() > 0) {
ret = new URL[v.size()];
v.copyInto(ret);
}
} catch (IOException e) {
} catch (SecurityException e) {}
return ret;
}
});
}
private static URL[] getSystemResources(final String name) {
return AccessController.<URL[]>doPrivileged(new PrivilegedAction() {
public Object run() {
URL[] ret = null;
try {
Vector<URL> v = new Vector();
Enumeration<URL> e = ClassLoader.getSystemResources(name);
while (e != null && e.hasMoreElements()) {
URL url = e.nextElement();
if (url != null)
v.addElement(url);
}
if (v.size() > 0) {
ret = new URL[v.size()];
v.copyInto(ret);
}
} catch (IOException e) {
} catch (SecurityException e) {}
return ret;
}
});
}
private static InputStream openStream(final URL url) throws IOException {
try {
return AccessController.<InputStream>doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws IOException {
return url.openStream();
}
});
} catch (PrivilegedActionException e) {
throw (IOException)e.getException();
}
}
EventQueue getEventQueue() {
return this.q;
}
}

View file

@ -0,0 +1,78 @@
package javax.mail;
import java.util.Vector;
import javax.mail.event.FolderEvent;
import javax.mail.event.FolderListener;
import javax.mail.event.StoreEvent;
import javax.mail.event.StoreListener;
public abstract class Store extends Service {
protected Store(Session session, URLName urlname) {
super(session, urlname);
}
public abstract Folder getDefaultFolder() throws MessagingException;
public abstract Folder getFolder(String paramString) throws MessagingException;
public abstract Folder getFolder(URLName paramURLName) throws MessagingException;
public Folder[] getPersonalNamespaces() throws MessagingException {
return new Folder[] { getDefaultFolder() };
}
public Folder[] getUserNamespaces(String user) throws MessagingException {
return new Folder[0];
}
public Folder[] getSharedNamespaces() throws MessagingException {
return new Folder[0];
}
private volatile Vector storeListeners = null;
public synchronized void addStoreListener(StoreListener l) {
if (this.storeListeners == null)
this.storeListeners = new Vector();
this.storeListeners.addElement(l);
}
public synchronized void removeStoreListener(StoreListener l) {
if (this.storeListeners != null)
this.storeListeners.removeElement(l);
}
protected void notifyStoreListeners(int type, String message) {
if (this.storeListeners == null)
return;
StoreEvent e = new StoreEvent(this, type, message);
queueEvent(e, this.storeListeners);
}
private volatile Vector folderListeners = null;
public synchronized void addFolderListener(FolderListener l) {
if (this.folderListeners == null)
this.folderListeners = new Vector();
this.folderListeners.addElement(l);
}
public synchronized void removeFolderListener(FolderListener l) {
if (this.folderListeners != null)
this.folderListeners.removeElement(l);
}
protected void notifyFolderListeners(int type, Folder folder) {
if (this.folderListeners == null)
return;
FolderEvent e = new FolderEvent(this, folder, type);
queueEvent(e, this.folderListeners);
}
protected void notifyFolderRenamedListeners(Folder oldF, Folder newF) {
if (this.folderListeners == null)
return;
FolderEvent e = new FolderEvent(this, oldF, newF, 3);
queueEvent(e, this.folderListeners);
}
}

View file

@ -0,0 +1,25 @@
package javax.mail;
public class StoreClosedException extends MessagingException {
private transient Store store;
private static final long serialVersionUID = -3145392336120082655L;
public StoreClosedException(Store store) {
this(store, null);
}
public StoreClosedException(Store store, String message) {
super(message);
this.store = store;
}
public StoreClosedException(Store store, String message, Exception e) {
super(message, e);
this.store = store;
}
public Store getStore() {
return this.store;
}
}

View file

@ -0,0 +1,8 @@
package javax.mail;
import java.io.IOException;
import java.io.InputStream;
interface StreamLoader {
void load(InputStream paramInputStream) throws IOException;
}

View file

@ -0,0 +1,137 @@
package javax.mail;
import java.util.Vector;
import javax.mail.event.TransportEvent;
import javax.mail.event.TransportListener;
public abstract class Transport extends Service {
public Transport(Session session, URLName urlname) {
super(session, urlname);
}
public static void send(Message msg) throws MessagingException {
msg.saveChanges();
send0(msg, msg.getAllRecipients(), null, null);
}
public static void send(Message msg, Address[] addresses) throws MessagingException {
msg.saveChanges();
send0(msg, addresses, null, null);
}
public static void send(Message msg, String user, String password) throws MessagingException {
msg.saveChanges();
send0(msg, msg.getAllRecipients(), user, password);
}
public static void send(Message msg, Address[] addresses, String user, String password) throws MessagingException {
msg.saveChanges();
send0(msg, addresses, user, password);
}
private static void send0(Message msg, Address[] addresses, String user, String password) throws MessagingException {
assert false : "Decompilation failed at line #209 -> offsets [0]";
assert false : "Decompilation failed at line #210 -> offsets [9]";
assert false : "Decompilation failed at line #216 -> offsets [19]";
assert false : "Decompilation failed at line #219 -> offsets [28]";
assert false : "Decompilation failed at line #220 -> offsets [37]";
assert false : "Decompilation failed at line #221 -> offsets [46]";
assert false : "Decompilation failed at line #223 -> offsets [55, 142]";
assert false : "Decompilation failed at line #225 -> offsets [65]";
assert false : "Decompilation failed at line #226 -> offsets [80]";
assert false : "Decompilation failed at line #227 -> offsets [97]";
assert false : "Decompilation failed at line #228 -> offsets [106]";
assert false : "Decompilation failed at line #230 -> offsets [109]";
assert false : "Decompilation failed at line #231 -> offsets [118]";
assert false : "Decompilation failed at line #232 -> offsets [127]";
assert false : "Decompilation failed at line #236 -> offsets [148]";
assert false : "Decompilation failed at line #237 -> offsets [155]";
assert false : "Decompilation failed at line #238 -> offsets [160]";
assert false : "Decompilation failed at line #240 -> offsets [170]";
assert false : "Decompilation failed at line #241 -> offsets [184]";
assert false : "Decompilation failed at line #247 -> offsets [193]";
assert false : "Decompilation failed at line #248 -> offsets [199]";
assert false : "Decompilation failed at line #250 -> offsets [209]";
assert false : "Decompilation failed at line #251 -> offsets [213]";
assert false : "Decompilation failed at line #253 -> offsets [223]";
assert false : "Decompilation failed at line #254 -> offsets [228]";
assert false : "Decompilation failed at line #255 -> offsets [235]";
assert false : "Decompilation failed at line #256 -> offsets [241]";
assert false : "Decompilation failed at line #257 -> offsets [238]";
assert false : "Decompilation failed at line #258 -> offsets [258]";
assert false : "Decompilation failed at line #265 -> offsets [259]";
assert false : "Decompilation failed at line #266 -> offsets [262]";
assert false : "Decompilation failed at line #268 -> offsets [265]";
assert false : "Decompilation failed at line #269 -> offsets [272]";
assert false : "Decompilation failed at line #270 -> offsets [282]";
assert false : "Decompilation failed at line #271 -> offsets [294]";
assert false : "Decompilation failed at line #272 -> offsets [304]";
assert false : "Decompilation failed at line #275 -> offsets [311]";
assert false : "Decompilation failed at line #278 -> offsets [326, 347]";
assert false : "Decompilation failed at line #279 -> offsets [337]";
assert false : "Decompilation failed at line #280 -> offsets [353]";
assert false : "Decompilation failed at line #283 -> offsets [356]";
assert false : "Decompilation failed at line #284 -> offsets [361]";
assert false : "Decompilation failed at line #285 -> offsets [369, 375]";
assert false : "Decompilation failed at line #286 -> offsets [377]";
assert false : "Decompilation failed at line #288 -> offsets [380]";
assert false : "Decompilation failed at line #289 -> offsets [385]";
assert false : "Decompilation failed at line #291 -> offsets [392]";
assert false : "Decompilation failed at line #294 -> offsets [400]";
assert false : "Decompilation failed at line #295 -> offsets [407]";
assert false : "Decompilation failed at line #296 -> offsets [412, 433]";
assert false : "Decompilation failed at line #297 -> offsets [423]";
assert false : "Decompilation failed at line #300 -> offsets [439]";
assert false : "Decompilation failed at line #301 -> offsets [446]";
assert false : "Decompilation failed at line #302 -> offsets [451, 472]";
assert false : "Decompilation failed at line #303 -> offsets [462]";
assert false : "Decompilation failed at line #306 -> offsets [478]";
assert false : "Decompilation failed at line #307 -> offsets [485]";
assert false : "Decompilation failed at line #308 -> offsets [490, 511]";
assert false : "Decompilation failed at line #309 -> offsets [501]";
assert false : "Decompilation failed at line #310 -> offsets [517, 523]";
assert false : "Decompilation failed at line #311 -> offsets [525]";
assert false : "Decompilation failed at line #313 -> offsets [528]";
assert false : "Decompilation failed at line #314 -> offsets [533]";
assert false : "Decompilation failed at line #316 -> offsets [540]";
assert false : "Decompilation failed at line #317 -> offsets [548]";
assert false : "Decompilation failed at line #318 -> offsets [554]";
assert false : "Decompilation failed at line #319 -> offsets [372, 520, 551]";
assert false : "Decompilation failed at line #320 -> offsets [571]";
assert false : "Decompilation failed at line #323 -> offsets [574]";
assert false : "Decompilation failed at line #324 -> offsets [595]";
assert false : "Decompilation failed at line #327 -> offsets [604]";
assert false : "Decompilation failed at line #328 -> offsets [612]";
assert false : "Decompilation failed at line #329 -> offsets [622]";
assert false : "Decompilation failed at line #331 -> offsets [629]";
assert false : "Decompilation failed at line #332 -> offsets [637]";
assert false : "Decompilation failed at line #333 -> offsets [647]";
assert false : "Decompilation failed at line #335 -> offsets [654]";
assert false : "Decompilation failed at line #336 -> offsets [662]";
assert false : "Decompilation failed at line #337 -> offsets [672]";
assert false : "Decompilation failed at line #339 -> offsets [679]";
assert false : "Decompilation failed at line #342 -> offsets [697]";
}
private volatile Vector transportListeners = null;
public abstract void sendMessage(Message paramMessage, Address[] paramArrayOfAddress) throws MessagingException;
public synchronized void addTransportListener(TransportListener l) {
if (this.transportListeners == null)
this.transportListeners = new Vector();
this.transportListeners.addElement(l);
}
public synchronized void removeTransportListener(TransportListener l) {
if (this.transportListeners != null)
this.transportListeners.removeElement(l);
}
protected void notifyTransportListeners(int type, Address[] validSent, Address[] validUnsent, Address[] invalid, Message msg) {
if (this.transportListeners == null)
return;
TransportEvent e = new TransportEvent(this, type, validSent, validUnsent, invalid, msg);
queueEvent(e, this.transportListeners);
}
}

View file

@ -0,0 +1,23 @@
package javax.mail;
public interface UIDFolder {
public static final long LASTUID = -1L;
long getUIDValidity() throws MessagingException;
Message getMessageByUID(long paramLong) throws MessagingException;
Message[] getMessagesByUID(long paramLong1, long paramLong2) throws MessagingException;
Message[] getMessagesByUID(long[] paramArrayOflong) throws MessagingException;
long getUID(Message paramMessage) throws MessagingException;
public static class FetchProfileItem extends FetchProfile.Item {
protected FetchProfileItem(String name) {
super(name);
}
public static final FetchProfileItem UID = new FetchProfileItem("UID");
}
}

View file

@ -0,0 +1,377 @@
package javax.mail;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.BitSet;
import java.util.Locale;
public class URLName {
protected String fullURL;
private String protocol;
private String username;
private String password;
private String host;
private InetAddress hostAddress;
private boolean hostAddressKnown = false;
private int port = -1;
private String file;
private String ref;
private int hashCode = 0;
private static boolean doEncode = true;
static {
try {
doEncode = !Boolean.getBoolean("mail.URLName.dontencode");
} catch (Exception e) {}
}
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;
}
public URLName(URL url) {
this(url.toString());
}
public URLName(String url) {
parseString(url);
}
public String toString() {
if (this.fullURL == null) {
StringBuffer tempURL = new StringBuffer();
if (this.protocol != null) {
tempURL.append(this.protocol);
tempURL.append(":");
}
if (this.username != null || this.host != null) {
tempURL.append("//");
if (this.username != null) {
tempURL.append(this.username);
if (this.password != null) {
tempURL.append(":");
tempURL.append(this.password);
}
tempURL.append("@");
}
if (this.host != null)
tempURL.append(this.host);
if (this.port != -1) {
tempURL.append(":");
tempURL.append(Integer.toString(this.port));
}
if (this.file != null)
tempURL.append("/");
}
if (this.file != null)
tempURL.append(this.file);
if (this.ref != null) {
tempURL.append("#");
tempURL.append(this.ref);
}
this.fullURL = tempURL.toString();
}
return this.fullURL;
}
protected void parseString(String url) {
this.protocol = this.file = this.ref = this.host = this.username = this.password = null;
this.port = -1;
int len = url.length();
int protocolEnd = url.indexOf(':');
if (protocolEnd != -1)
this.protocol = url.substring(0, protocolEnd);
if (url.regionMatches(protocolEnd + 1, "//", 0, 2)) {
int portindex;
String fullhost = null;
int fileStart = url.indexOf('/', protocolEnd + 3);
if (fileStart != -1) {
fullhost = url.substring(protocolEnd + 3, fileStart);
if (fileStart + 1 < len) {
this.file = url.substring(fileStart + 1);
} else {
this.file = "";
}
} else {
fullhost = url.substring(protocolEnd + 3);
}
int i = fullhost.indexOf('@');
if (i != -1) {
String fulluserpass = fullhost.substring(0, i);
fullhost = fullhost.substring(i + 1);
int passindex = fulluserpass.indexOf(':');
if (passindex != -1) {
this.username = fulluserpass.substring(0, passindex);
this.password = fulluserpass.substring(passindex + 1);
} else {
this.username = fulluserpass;
}
}
if (fullhost.length() > 0 && fullhost.charAt(0) == '[') {
portindex = fullhost.indexOf(':', fullhost.indexOf(']'));
} else {
portindex = fullhost.indexOf(':');
}
if (portindex != -1) {
String portstring = fullhost.substring(portindex + 1);
if (portstring.length() > 0)
try {
this.port = Integer.parseInt(portstring);
} catch (NumberFormatException nfex) {
this.port = -1;
}
this.host = fullhost.substring(0, portindex);
} else {
this.host = fullhost;
}
} else if (protocolEnd + 1 < len) {
this.file = url.substring(protocolEnd + 1);
}
int refStart;
if (this.file != null && (refStart = this.file.indexOf('#')) != -1) {
this.ref = this.file.substring(refStart + 1);
this.file = this.file.substring(0, refStart);
}
}
public int getPort() {
return this.port;
}
public String getProtocol() {
return this.protocol;
}
public String getFile() {
return this.file;
}
public String getRef() {
return this.ref;
}
public String getHost() {
return this.host;
}
public String getUsername() {
return doEncode ? decode(this.username) : this.username;
}
public String getPassword() {
return doEncode ? decode(this.password) : this.password;
}
public URL getURL() throws MalformedURLException {
return new URL(getProtocol(), getHost(), getPort(), getFile());
}
public boolean equals(Object obj) {
if (!(obj instanceof URLName))
return false;
URLName u2 = (URLName)obj;
if (this.protocol != u2.protocol && (this.protocol == null ||
!this.protocol.equals(u2.protocol)))
return false;
InetAddress a1 = getHostAddress(), a2 = u2.getHostAddress();
if (a1 != null && a2 != null) {
if (!a1.equals(a2))
return false;
} else if (this.host != null && u2.host != null) {
if (!this.host.equalsIgnoreCase(u2.host))
return false;
} else if (this.host != u2.host) {
return false;
}
if (this.username != u2.username && (this.username == null ||
!this.username.equals(u2.username)))
return false;
String f1 = (this.file == null) ? "" : this.file;
String f2 = (u2.file == null) ? "" : u2.file;
if (!f1.equals(f2))
return false;
if (this.port != u2.port)
return false;
return true;
}
public int hashCode() {
if (this.hashCode != 0)
return this.hashCode;
if (this.protocol != null)
this.hashCode += this.protocol.hashCode();
InetAddress addr = getHostAddress();
if (addr != null) {
this.hashCode += addr.hashCode();
} else if (this.host != null) {
this.hashCode += this.host.toLowerCase(Locale.ENGLISH).hashCode();
}
if (this.username != null)
this.hashCode += this.username.hashCode();
if (this.file != null)
this.hashCode += this.file.hashCode();
this.hashCode += this.port;
return this.hashCode;
}
private synchronized InetAddress getHostAddress() {
if (this.hostAddressKnown)
return this.hostAddress;
if (this.host == null)
return null;
try {
this.hostAddress = InetAddress.getByName(this.host);
} catch (UnknownHostException ex) {
this.hostAddress = null;
}
this.hostAddressKnown = true;
return this.hostAddress;
}
static BitSet dontNeedEncoding = new BitSet(256);
static final int caseDiff = 32;
static {
for (int k = 97; k <= 122; k++)
dontNeedEncoding.set(k);
for (int j = 65; j <= 90; j++)
dontNeedEncoding.set(j);
for (int i = 48; i <= 57; i++)
dontNeedEncoding.set(i);
dontNeedEncoding.set(32);
dontNeedEncoding.set(45);
dontNeedEncoding.set(95);
dontNeedEncoding.set(46);
dontNeedEncoding.set(42);
}
static String encode(String s) {
if (s == null)
return null;
for (int i = 0; i < s.length(); i++) {
int c = s.charAt(i);
if (c == 32 || !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 = s.charAt(i);
if (dontNeedEncoding.get(c)) {
if (c == 32)
c = 43;
out.append((char)c);
} else {
try {
writer.write(c);
writer.flush();
} catch (IOException e) {
buf.reset();
}
byte[] ba = buf.toByteArray();
for (int j = 0; j < ba.length; j++) {
out.append('%');
char ch = Character.forDigit(ba[j] >> 4 & 0xF, 16);
if (Character.isLetter(ch))
ch = (char)(ch - 32);
out.append(ch);
ch = Character.forDigit(ba[j] & 0xF, 16);
if (Character.isLetter(ch))
ch = (char)(ch - 32);
out.append(ch);
}
buf.reset();
}
}
return out.toString();
}
static String decode(String s) {
if (s == null)
return null;
if (indexOfAny(s, "+%") == -1)
return s;
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;
}
}
String result = sb.toString();
try {
byte[] inputBytes = result.getBytes("8859_1");
result = new String(inputBytes);
} catch (UnsupportedEncodingException e) {}
return result;
}
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;
}
}
}

View file

@ -0,0 +1,5 @@
package javax.mail;
class Version {
public static final String version = "1.5.4";
}

View file

@ -0,0 +1,9 @@
package javax.mail.event;
public abstract class ConnectionAdapter implements ConnectionListener {
public void opened(ConnectionEvent e) {}
public void disconnected(ConnectionEvent e) {}
public void closed(ConnectionEvent e) {}
}

View file

@ -0,0 +1,32 @@
package javax.mail.event;
public class ConnectionEvent extends MailEvent {
public static final int OPENED = 1;
public static final int DISCONNECTED = 2;
public static final int CLOSED = 3;
protected int type;
private static final long serialVersionUID = -1855480171284792957L;
public ConnectionEvent(Object source, int type) {
super(source);
this.type = type;
}
public int getType() {
return this.type;
}
public void dispatch(Object listener) {
if (this.type == 1) {
((ConnectionListener)listener).opened(this);
} else if (this.type == 2) {
((ConnectionListener)listener).disconnected(this);
} else if (this.type == 3) {
((ConnectionListener)listener).closed(this);
}
}
}

View file

@ -0,0 +1,11 @@
package javax.mail.event;
import java.util.EventListener;
public interface ConnectionListener extends EventListener {
void opened(ConnectionEvent paramConnectionEvent);
void disconnected(ConnectionEvent paramConnectionEvent);
void closed(ConnectionEvent paramConnectionEvent);
}

View file

@ -0,0 +1,9 @@
package javax.mail.event;
public abstract class FolderAdapter implements FolderListener {
public void folderCreated(FolderEvent e) {}
public void folderRenamed(FolderEvent e) {}
public void folderDeleted(FolderEvent e) {}
}

View file

@ -0,0 +1,52 @@
package javax.mail.event;
import javax.mail.Folder;
public class FolderEvent extends MailEvent {
public static final int CREATED = 1;
public static final int DELETED = 2;
public static final int RENAMED = 3;
protected int type;
protected transient Folder folder;
protected transient Folder newFolder;
private static final long serialVersionUID = 5278131310563694307L;
public FolderEvent(Object source, Folder folder, int type) {
this(source, folder, folder, type);
}
public FolderEvent(Object source, Folder oldFolder, Folder newFolder, int type) {
super(source);
this.folder = oldFolder;
this.newFolder = newFolder;
this.type = type;
}
public int getType() {
return this.type;
}
public Folder getFolder() {
return this.folder;
}
public Folder getNewFolder() {
return this.newFolder;
}
public void dispatch(Object listener) {
if (this.type == 1) {
((FolderListener)listener).folderCreated(this);
} else if (this.type == 2) {
((FolderListener)listener).folderDeleted(this);
} else if (this.type == 3) {
((FolderListener)listener).folderRenamed(this);
}
}
}

View file

@ -0,0 +1,11 @@
package javax.mail.event;
import java.util.EventListener;
public interface FolderListener extends EventListener {
void folderCreated(FolderEvent paramFolderEvent);
void folderDeleted(FolderEvent paramFolderEvent);
void folderRenamed(FolderEvent paramFolderEvent);
}

View file

@ -0,0 +1,13 @@
package javax.mail.event;
import java.util.EventObject;
public abstract class MailEvent extends EventObject {
private static final long serialVersionUID = 1846275636325456631L;
public MailEvent(Object source) {
super(source);
}
public abstract void dispatch(Object paramObject);
}

View file

@ -0,0 +1,33 @@
package javax.mail.event;
import javax.mail.Message;
public class MessageChangedEvent extends MailEvent {
public static final int FLAGS_CHANGED = 1;
public static final int ENVELOPE_CHANGED = 2;
protected int type;
protected transient Message msg;
private static final long serialVersionUID = -4974972972105535108L;
public MessageChangedEvent(Object source, int type, Message msg) {
super(source);
this.msg = msg;
this.type = type;
}
public int getMessageChangeType() {
return this.type;
}
public Message getMessage() {
return this.msg;
}
public void dispatch(Object listener) {
((MessageChangedListener)listener).messageChanged(this);
}
}

View file

@ -0,0 +1,7 @@
package javax.mail.event;
import java.util.EventListener;
public interface MessageChangedListener extends EventListener {
void messageChanged(MessageChangedEvent paramMessageChangedEvent);
}

View file

@ -0,0 +1,7 @@
package javax.mail.event;
public abstract class MessageCountAdapter implements MessageCountListener {
public void messagesAdded(MessageCountEvent e) {}
public void messagesRemoved(MessageCountEvent e) {}
}

View file

@ -0,0 +1,45 @@
package javax.mail.event;
import javax.mail.Folder;
import javax.mail.Message;
public class MessageCountEvent extends MailEvent {
public static final int ADDED = 1;
public static final int REMOVED = 2;
protected int type;
protected boolean removed;
protected transient Message[] msgs;
private static final long serialVersionUID = -7447022340837897369L;
public MessageCountEvent(Folder folder, int type, boolean removed, Message[] msgs) {
super(folder);
this.type = type;
this.removed = removed;
this.msgs = msgs;
}
public int getType() {
return this.type;
}
public boolean isRemoved() {
return this.removed;
}
public Message[] getMessages() {
return this.msgs;
}
public void dispatch(Object listener) {
if (this.type == 1) {
((MessageCountListener)listener).messagesAdded(this);
} else {
((MessageCountListener)listener).messagesRemoved(this);
}
}
}

View file

@ -0,0 +1,9 @@
package javax.mail.event;
import java.util.EventListener;
public interface MessageCountListener extends EventListener {
void messagesAdded(MessageCountEvent paramMessageCountEvent);
void messagesRemoved(MessageCountEvent paramMessageCountEvent);
}

View file

@ -0,0 +1,33 @@
package javax.mail.event;
import javax.mail.Store;
public class StoreEvent extends MailEvent {
public static final int ALERT = 1;
public static final int NOTICE = 2;
protected int type;
protected String message;
private static final long serialVersionUID = 1938704919992515330L;
public StoreEvent(Store store, int type, String message) {
super(store);
this.type = type;
this.message = message;
}
public int getMessageType() {
return this.type;
}
public String getMessage() {
return this.message;
}
public void dispatch(Object listener) {
((StoreListener)listener).notification(this);
}
}

View file

@ -0,0 +1,7 @@
package javax.mail.event;
import java.util.EventListener;
public interface StoreListener extends EventListener {
void notification(StoreEvent paramStoreEvent);
}

View file

@ -0,0 +1,9 @@
package javax.mail.event;
public abstract class TransportAdapter implements TransportListener {
public void messageDelivered(TransportEvent e) {}
public void messageNotDelivered(TransportEvent e) {}
public void messagePartiallyDelivered(TransportEvent e) {}
}

View file

@ -0,0 +1,64 @@
package javax.mail.event;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Transport;
public class TransportEvent extends MailEvent {
public static final int MESSAGE_DELIVERED = 1;
public static final int MESSAGE_NOT_DELIVERED = 2;
public static final int MESSAGE_PARTIALLY_DELIVERED = 3;
protected int type;
protected transient Address[] validSent;
protected transient Address[] validUnsent;
protected transient Address[] invalid;
protected transient Message msg;
private static final long serialVersionUID = -4729852364684273073L;
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;
}
public int getType() {
return this.type;
}
public Address[] getValidSentAddresses() {
return this.validSent;
}
public Address[] getValidUnsentAddresses() {
return this.validUnsent;
}
public Address[] getInvalidAddresses() {
return this.invalid;
}
public Message getMessage() {
return this.msg;
}
public void dispatch(Object listener) {
if (this.type == 1) {
((TransportListener)listener).messageDelivered(this);
} else if (this.type == 2) {
((TransportListener)listener).messageNotDelivered(this);
} else {
((TransportListener)listener).messagePartiallyDelivered(this);
}
}
}

View file

@ -0,0 +1,11 @@
package javax.mail.event;
import java.util.EventListener;
public interface TransportListener extends EventListener {
void messageDelivered(TransportEvent paramTransportEvent);
void messageNotDelivered(TransportEvent paramTransportEvent);
void messagePartiallyDelivered(TransportEvent paramTransportEvent);
}

View file

@ -0,0 +1,44 @@
package javax.mail.internet;
public class AddressException extends ParseException {
protected String ref = null;
protected int pos = -1;
private static final long serialVersionUID = 9134583443539323120L;
public AddressException() {}
public AddressException(String s) {
super(s);
}
public AddressException(String s, String ref) {
super(s);
this.ref = ref;
}
public AddressException(String s, String ref, int pos) {
super(s);
this.ref = ref;
this.pos = pos;
}
public String getRef() {
return this.ref;
}
public int getPos() {
return this.pos;
}
public String toString() {
String s = super.toString();
if (this.ref == null)
return s;
s = s + " in string ``" + this.ref + "''";
if (this.pos < 0)
return s;
return s + " at position " + this.pos;
}
}

View file

@ -0,0 +1,80 @@
package javax.mail.internet;
import java.io.EOFException;
import java.io.IOException;
import java.io.OutputStream;
class AsciiOutputStream extends OutputStream {
private boolean breakOnNonAscii;
private int ascii = 0, non_ascii = 0;
private int linelen = 0;
private boolean longLine = false;
private boolean badEOL = false;
private boolean checkEOL = false;
private int lastb = 0;
private int ret = 0;
public AsciiOutputStream(boolean breakOnNonAscii, boolean encodeEolStrict) {
this.breakOnNonAscii = breakOnNonAscii;
this.checkEOL = (encodeEolStrict && breakOnNonAscii);
}
public void write(int b) throws IOException {
check(b);
}
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
public void write(byte[] b, int off, int len) throws IOException {
len += off;
for (int i = off; i < len; i++)
check(b[i]);
}
private final void check(int b) throws IOException {
b &= 0xFF;
if (this.checkEOL && ((this.lastb == 13 && b != 10) || (this.lastb != 13 && b == 10)))
this.badEOL = true;
if (b == 13 || b == 10) {
this.linelen = 0;
} else {
this.linelen++;
if (this.linelen > 998)
this.longLine = true;
}
if (MimeUtility.nonascii(b)) {
this.non_ascii++;
if (this.breakOnNonAscii) {
this.ret = 3;
throw new EOFException();
}
} else {
this.ascii++;
}
this.lastb = b;
}
public int getAscii() {
if (this.ret != 0)
return this.ret;
if (this.badEOL)
return 3;
if (this.non_ascii == 0) {
if (this.longLine)
return 2;
return 1;
}
if (this.ascii > this.non_ascii)
return 2;
return 3;
}
}

View file

@ -0,0 +1,64 @@
package javax.mail.internet;
public class ContentDisposition {
private String disposition;
private ParameterList list;
public ContentDisposition() {}
public ContentDisposition(String disposition, ParameterList list) {
this.disposition = disposition;
this.list = list;
}
public ContentDisposition(String s) throws ParseException {
HeaderTokenizer h = new HeaderTokenizer(s, "()<>@,;:\\\"\t []/?=");
HeaderTokenizer.Token tk = h.next();
if (tk.getType() != -1)
throw new ParseException("Expected disposition, got " +
tk.getValue());
this.disposition = tk.getValue();
String rem = h.getRemainder();
if (rem != null)
this.list = new ParameterList(rem);
}
public String getDisposition() {
return this.disposition;
}
public String getParameter(String name) {
if (this.list == null)
return null;
return this.list.get(name);
}
public ParameterList getParameterList() {
return this.list;
}
public void setDisposition(String disposition) {
this.disposition = disposition;
}
public void setParameter(String name, String value) {
if (this.list == null)
this.list = new ParameterList();
this.list.set(name, value);
}
public void setParameterList(ParameterList list) {
this.list = list;
}
public String toString() {
if (this.disposition == null)
return "";
if (this.list == null)
return this.disposition;
StringBuffer sb = new StringBuffer(this.disposition);
sb.append(this.list.toString(sb.length() + 21));
return sb.toString();
}
}

View file

@ -0,0 +1,113 @@
package javax.mail.internet;
public class ContentType {
private String primaryType;
private String subType;
private ParameterList list;
public ContentType() {}
public ContentType(String primaryType, String subType, ParameterList list) {
this.primaryType = primaryType;
this.subType = subType;
this.list = list;
}
public ContentType(String s) throws ParseException {
HeaderTokenizer h = new HeaderTokenizer(s, "()<>@,;:\\\"\t []/?=");
HeaderTokenizer.Token tk = h.next();
if (tk.getType() != -1)
throw new ParseException("In Content-Type string <" + s + ">" + ", expected MIME type, got " +
tk.getValue());
this.primaryType = tk.getValue();
tk = h.next();
if ((char)tk.getType() != '/')
throw new ParseException("In Content-Type string <" + s + ">" + ", expected '/', got " +
tk.getValue());
tk = h.next();
if (tk.getType() != -1)
throw new ParseException("In Content-Type string <" + s + ">" + ", expected MIME subtype, got " +
tk.getValue());
this.subType = tk.getValue();
String rem = h.getRemainder();
if (rem != null)
this.list = new ParameterList(rem);
}
public String getPrimaryType() {
return this.primaryType;
}
public String getSubType() {
return this.subType;
}
public String getBaseType() {
if (this.primaryType == null || this.subType == null)
return "";
return this.primaryType + '/' + this.subType;
}
public String getParameter(String name) {
if (this.list == null)
return null;
return this.list.get(name);
}
public ParameterList getParameterList() {
return this.list;
}
public void setPrimaryType(String primaryType) {
this.primaryType = primaryType;
}
public void setSubType(String subType) {
this.subType = subType;
}
public void setParameter(String name, String value) {
if (this.list == null)
this.list = new ParameterList();
this.list.set(name, value);
}
public void setParameterList(ParameterList list) {
this.list = list;
}
public String toString() {
if (this.primaryType == null || this.subType == null)
return "";
StringBuffer sb = new StringBuffer();
sb.append(this.primaryType).append('/').append(this.subType);
if (this.list != null)
sb.append(this.list.toString(sb.length() + 14));
return sb.toString();
}
public boolean match(ContentType cType) {
if ((this.primaryType != null || cType.getPrimaryType() != null) && (this.primaryType == null ||
!this.primaryType.equalsIgnoreCase(cType.getPrimaryType())))
return false;
String sType = cType.getSubType();
if ((this.subType != null && this.subType.startsWith("*")) || (sType != null &&
sType.startsWith("*")))
return true;
return ((this.subType == null && sType == null) || (this.subType != null &&
this.subType.equalsIgnoreCase(sType)));
}
public boolean match(String s) {
try {
return match(new ContentType(s));
} catch (ParseException pex) {
return false;
}
}
}

View file

@ -0,0 +1,243 @@
package javax.mail.internet;
public class HeaderTokenizer {
private String string;
private boolean skipComments;
private String delimiters;
private int currentPos;
private int maxPos;
private int nextPos;
private int peekPos;
public static final String RFC822 = "()<>@,;:\\\"\t .[]";
public static final String MIME = "()<>@,;:\\\"\t []/?=";
public static class Token {
private int type;
private String value;
public static final int ATOM = -1;
public static final int QUOTEDSTRING = -2;
public static final int COMMENT = -3;
public static final int EOF = -4;
public Token(int type, String value) {
this.type = type;
this.value = value;
}
public int getType() {
return this.type;
}
public String getValue() {
return this.value;
}
}
private static final Token EOFToken = new Token(-4, null);
public HeaderTokenizer(String header, String delimiters, boolean skipComments) {
this.string = (header == null) ? "" : header;
this.skipComments = skipComments;
this.delimiters = delimiters;
this.currentPos = this.nextPos = this.peekPos = 0;
this.maxPos = this.string.length();
}
public HeaderTokenizer(String header, String delimiters) {
this(header, delimiters, true);
}
public HeaderTokenizer(String header) {
this(header, "()<>@,;:\\\"\t .[]");
}
public Token next() throws ParseException {
return next('\000', false);
}
public Token next(char endOfAtom) throws ParseException {
return next(endOfAtom, false);
}
public Token next(char endOfAtom, boolean keepEscapes) throws ParseException {
this.currentPos = this.nextPos;
Token tk = getNext(endOfAtom, keepEscapes);
this.nextPos = this.peekPos = this.currentPos;
return tk;
}
public Token peek() throws ParseException {
this.currentPos = this.peekPos;
Token tk = getNext('\000', false);
this.peekPos = this.currentPos;
return tk;
}
public String getRemainder() {
if (this.nextPos >= this.string.length())
return null;
return this.string.substring(this.nextPos);
}
private Token getNext(char endOfAtom, boolean keepEscapes) throws ParseException {
if (this.currentPos >= this.maxPos)
return EOFToken;
if (skipWhiteSpace() == -4)
return EOFToken;
boolean filter = false;
char c = this.string.charAt(this.currentPos);
while (c == '(') {
int i = ++this.currentPos, nesting = 1;
for (; nesting > 0 && this.currentPos < this.maxPos;
this.currentPos++) {
c = this.string.charAt(this.currentPos);
if (c == '\\') {
this.currentPos++;
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 (!this.skipComments) {
String s;
if (filter) {
s = filterToken(this.string, i, this.currentPos - 1, keepEscapes);
} else {
s = this.string.substring(i, this.currentPos - 1);
}
return new Token(-3, s);
}
if (skipWhiteSpace() == -4)
return EOFToken;
c = this.string.charAt(this.currentPos);
}
if (c == '"') {
this.currentPos++;
return collectString('"', keepEscapes);
}
if (c < ' ' || c >= '\u007F' || this.delimiters.indexOf(c) >= 0) {
if (endOfAtom > '\000' && c != endOfAtom)
return collectString(endOfAtom, keepEscapes);
this.currentPos++;
char[] ch = new char[1];
ch[0] = c;
return new Token(c, new String(ch));
}
int start;
for (start = this.currentPos; this.currentPos < this.maxPos; this.currentPos++) {
c = this.string.charAt(this.currentPos);
if (c < ' ' || c >= '\u007F' || c == '(' || c == ' ' || c == '"' ||
this.delimiters.indexOf(c) >= 0) {
if (endOfAtom > '\000' && c != endOfAtom) {
this.currentPos = start;
return collectString(endOfAtom, keepEscapes);
}
break;
}
}
return new Token(-1, this.string.substring(start, this.currentPos));
}
private Token collectString(char eos, boolean keepEscapes) throws ParseException {
boolean filter = false;
int start;
for (start = this.currentPos; this.currentPos < this.maxPos; this.currentPos++) {
char c = this.string.charAt(this.currentPos);
if (c == '\\') {
this.currentPos++;
filter = true;
} else if (c == '\r') {
filter = true;
} else if (c == eos) {
String str;
this.currentPos++;
if (filter) {
str = filterToken(this.string, start, this.currentPos - 1, keepEscapes);
} else {
str = this.string.substring(start, this.currentPos - 1);
}
if (c != '"') {
str = trimWhiteSpace(str);
this.currentPos--;
}
return new Token(-2, str);
}
}
if (eos == '"')
throw new ParseException("Unbalanced quoted string");
if (filter) {
s = filterToken(this.string, start, this.currentPos, keepEscapes);
} else {
s = this.string.substring(start, this.currentPos);
}
String s = trimWhiteSpace(s);
return new Token(-2, s);
}
private int skipWhiteSpace() {
for (; this.currentPos < this.maxPos; this.currentPos++) {
char c;
if ((c = this.string.charAt(this.currentPos)) != ' ' && c != '\t' && c != '\r' && c != '\n')
return this.currentPos;
}
return -4;
}
private static String trimWhiteSpace(String s) {
char c;
int i;
for (i = s.length() - 1; i >= 0 && ((
c = s.charAt(i)) == ' ' || c == '\t' || c == '\r' || c == '\n'); i--);
if (i <= 0)
return "";
return s.substring(0, i + 1);
}
private static String filterToken(String s, int start, int end, boolean keepEscapes) {
StringBuffer sb = new StringBuffer();
boolean gotEscape = false;
boolean gotCR = false;
for (int i = start; i < end; i++) {
char c = s.charAt(i);
if (c == '\n' && gotCR) {
gotCR = false;
} else {
gotCR = false;
if (!gotEscape) {
if (c == '\\') {
gotEscape = true;
} else if (c == '\r') {
gotCR = true;
} else {
sb.append(c);
}
} else {
if (keepEscapes)
sb.append('\\');
sb.append(c);
gotEscape = false;
}
}
}
return sb.toString();
}
}

View file

@ -0,0 +1,782 @@
package javax.mail.internet;
import com.sun.mail.util.PropUtil;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;
import javax.mail.Address;
import javax.mail.Session;
public class InternetAddress extends Address implements Cloneable {
protected String address;
protected String personal;
protected String encodedPersonal;
private static final long serialVersionUID = -7507595530758302903L;
private static final boolean ignoreBogusGroupName = PropUtil.getBooleanSystemProperty("mail.mime.address.ignorebogusgroupname", true);
public InternetAddress() {}
public InternetAddress(String address) throws AddressException {
InternetAddress[] a = parse(address, true);
if (a.length != 1)
throw new AddressException("Illegal address", address);
this.address = (a[0]).address;
this.personal = (a[0]).personal;
this.encodedPersonal = (a[0]).encodedPersonal;
}
public InternetAddress(String address, boolean strict) throws AddressException {
this(address);
if (strict)
if (isGroup()) {
getGroup(true);
} else {
checkAddress(this.address, true, true);
}
}
public InternetAddress(String address, String personal) throws UnsupportedEncodingException {
this(address, personal, null);
}
public InternetAddress(String address, String personal, String charset) throws UnsupportedEncodingException {
this.address = address;
setPersonal(personal, charset);
}
public Object clone() {
InternetAddress a = null;
try {
a = (InternetAddress)super.clone();
} catch (CloneNotSupportedException e) {}
return a;
}
public String getType() {
return "rfc822";
}
public void setAddress(String address) {
this.address = address;
}
public void setPersonal(String name, String charset) throws UnsupportedEncodingException {
this.personal = name;
if (name != null) {
this.encodedPersonal = MimeUtility.encodeWord(name, charset, null);
} else {
this.encodedPersonal = null;
}
}
public void setPersonal(String name) throws UnsupportedEncodingException {
this.personal = name;
if (name != null) {
this.encodedPersonal = MimeUtility.encodeWord(name);
} else {
this.encodedPersonal = null;
}
}
public String getAddress() {
return this.address;
}
public String getPersonal() {
if (this.personal != null)
return this.personal;
if (this.encodedPersonal != null)
try {
this.personal = MimeUtility.decodeText(this.encodedPersonal);
return this.personal;
} catch (Exception ex) {
return this.encodedPersonal;
}
return null;
}
public String toString() {
String a = (this.address == null) ? "" : this.address;
if (this.encodedPersonal == null && this.personal != null)
try {
this.encodedPersonal = MimeUtility.encodeWord(this.personal);
} catch (UnsupportedEncodingException e) {}
if (this.encodedPersonal != null)
return quotePhrase(this.encodedPersonal) + " <" + a + ">";
if (isGroup() || isSimple())
return a;
return "<" + a + ">";
}
public String toUnicodeString() {
String p = getPersonal();
if (p != null)
return quotePhrase(p) + " <" + this.address + ">";
if (isGroup() || isSimple())
return this.address;
return "<" + this.address + ">";
}
private static final String rfc822phrase = "()<>@,;:\\\"\t .[]"
.replace(' ', '\000').replace('\t', '\000');
private static final String specialsNoDotNoAt = "()<>,;:\\\"[]";
private static final String specialsNoDot = "()<>,;:\\\"[]@";
private static String quotePhrase(String phrase) {
int len = phrase.length();
boolean needQuoting = false;
for (int i = 0; i < len; i++) {
char c = phrase.charAt(i);
if (c == '"' || c == '\\') {
StringBuffer sb = new StringBuffer(len + 3);
sb.append('"');
for (int j = 0; j < len; j++) {
char cc = phrase.charAt(j);
if (cc == '"' || cc == '\\')
sb.append('\\');
sb.append(cc);
}
sb.append('"');
return sb.toString();
}
if ((c < ' ' && c != '\r' && c != '\n' && c != '\t') || c >= '\u007F' ||
rfc822phrase.indexOf(c) >= 0)
needQuoting = true;
}
if (needQuoting) {
StringBuffer sb = new StringBuffer(len + 2);
sb.append('"').append(phrase).append('"');
return sb.toString();
}
return phrase;
}
private static String unquote(String s) {
if (s.startsWith("\"") && s.endsWith("\"") && s.length() > 1) {
s = s.substring(1, s.length() - 1);
if (s.indexOf('\\') >= 0) {
StringBuffer sb = new StringBuffer(s.length());
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '\\' && i < s.length() - 1)
c = s.charAt(++i);
sb.append(c);
}
s = sb.toString();
}
}
return s;
}
public boolean equals(Object a) {
if (!(a instanceof InternetAddress))
return false;
String s = ((InternetAddress)a).getAddress();
if (s == this.address)
return true;
if (this.address != null && this.address.equalsIgnoreCase(s))
return true;
return false;
}
public int hashCode() {
if (this.address == null)
return 0;
return this.address.toLowerCase(Locale.ENGLISH).hashCode();
}
public static String toString(Address[] addresses) {
return toString(addresses, 0);
}
public static String toString(Address[] addresses, int used) {
if (addresses == null || addresses.length == 0)
return null;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < addresses.length; i++) {
if (i != 0) {
sb.append(", ");
used += 2;
}
String s = addresses[i].toString();
int len = lengthOfFirstSegment(s);
if (used + len > 76) {
sb.append("\r\n\t");
used = 8;
}
sb.append(s);
used = lengthOfLastSegment(s, used);
}
return sb.toString();
}
private static int lengthOfFirstSegment(String s) {
int pos;
if ((pos = s.indexOf("\r\n")) != -1)
return pos;
return s.length();
}
private static int lengthOfLastSegment(String s, int used) {
int pos;
if ((pos = s.lastIndexOf("\r\n")) != -1)
return s.length() - pos - 2;
return s.length() + used;
}
public static InternetAddress getLocalAddress(Session session) {
try {
return _getLocalAddress(session);
} catch (SecurityException e) {
} catch (AddressException e) {
} catch (UnknownHostException e) {}
return null;
}
static InternetAddress _getLocalAddress(Session session) throws SecurityException, AddressException, UnknownHostException {
String user = null, host = null, address = null;
if (session == null) {
user = System.getProperty("user.name");
host = getLocalHostName();
} else {
address = session.getProperty("mail.from");
if (address == null) {
user = session.getProperty("mail.user");
if (user == null || user.length() == 0)
user = session.getProperty("user.name");
if (user == null || user.length() == 0)
user = System.getProperty("user.name");
host = session.getProperty("mail.host");
if (host == null || host.length() == 0)
host = getLocalHostName();
}
}
if (address == null && user != null && user.length() != 0 && host != null &&
host.length() != 0)
address = MimeUtility.quote(user.trim(), "()<>,;:\\\"[]@\t ") + "@" + host;
if (address == null)
return null;
return new InternetAddress(address);
}
private static String getLocalHostName() throws UnknownHostException {
String host = null;
InetAddress me = InetAddress.getLocalHost();
if (me != null) {
host = me.getHostName();
if (host != null && host.length() > 0 && isInetAddressLiteral(host))
host = '[' + host + ']';
}
return host;
}
private static boolean isInetAddressLiteral(String addr) {
boolean sawHex = false, sawColon = false;
for (int i = 0; i < addr.length(); i++) {
char c = addr.charAt(i);
if (c < '0' || c > '9')
if (c != '.')
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
sawHex = true;
} else if (c == ':') {
sawColon = true;
} else {
return false;
}
}
return (!sawHex || sawColon);
}
public static InternetAddress[] parse(String addresslist) throws AddressException {
return parse(addresslist, true);
}
public static InternetAddress[] parse(String addresslist, boolean strict) throws AddressException {
return parse(addresslist, strict, false);
}
public static InternetAddress[] parseHeader(String addresslist, boolean strict) throws AddressException {
return parse(MimeUtility.unfold(addresslist), strict, true);
}
private static InternetAddress[] parse(String s, boolean strict, boolean parseHdr) throws AddressException {
int start_personal = -1, end_personal = -1;
int length = s.length();
boolean ignoreErrors = (parseHdr && !strict);
boolean in_group = false;
boolean route_addr = false;
boolean rfc822 = false;
List<InternetAddress> v = new ArrayList();
int start, end, index;
for (start = end = -1, index = 0; index < length; index++) {
int nesting, pindex, rindex;
boolean inquote;
int qindex, lindex;
String addr, pers;
char c = s.charAt(index);
switch (c) {
case '(':
rfc822 = true;
if (start >= 0 && end == -1)
end = index;
pindex = index;
index++;
for (nesting = 1; index < length && nesting > 0;
index++) {
c = s.charAt(index);
switch (c) {
case '\\':
index++;
break;
case '(':
nesting++;
break;
case ')':
nesting--;
break;
}
}
if (nesting > 0) {
if (!ignoreErrors)
throw new AddressException("Missing ')'", s, index);
index = pindex + 1;
break;
}
index--;
if (start_personal == -1)
start_personal = pindex + 1;
if (end_personal == -1)
end_personal = index;
break;
case ')':
if (!ignoreErrors)
throw new AddressException("Missing '('", s, index);
if (start == -1)
start = index;
break;
case '<':
rfc822 = true;
if (route_addr) {
if (!ignoreErrors)
throw new AddressException("Extra route-addr", s, index);
if (start == -1) {
route_addr = false;
rfc822 = false;
start = end = -1;
break;
}
if (!in_group) {
if (end == -1)
end = index;
String str = s.substring(start, end).trim();
InternetAddress ma = new InternetAddress();
ma.setAddress(str);
if (start_personal >= 0)
ma.encodedPersonal = unquote(
s.substring(start_personal, end_personal)
.trim());
v.add(ma);
route_addr = false;
rfc822 = false;
start = end = -1;
start_personal = end_personal = -1;
}
}
rindex = index;
inquote = false;
for (; ++index < length; index++) {
c = s.charAt(index);
switch (c) {
case '\\':
index++;
break;
case '"':
inquote = !inquote;
break;
case '>':
if (inquote)
break;
break;
}
}
if (inquote) {
if (!ignoreErrors)
throw new AddressException("Missing '\"'", s, index);
for (index = rindex + 1; index < length; index++) {
c = s.charAt(index);
if (c == '\\') {
index++;
} else if (c == '>') {
break;
}
}
}
if (index >= length) {
if (!ignoreErrors)
throw new AddressException("Missing '>'", s, index);
index = rindex + 1;
if (start == -1)
start = rindex;
break;
}
if (!in_group) {
if (start >= 0) {
start_personal = start;
end_personal = rindex;
}
start = rindex + 1;
}
route_addr = true;
end = index;
break;
case '>':
if (!ignoreErrors)
throw new AddressException("Missing '<'", s, index);
if (start == -1)
start = index;
break;
case '"':
qindex = index;
rfc822 = true;
if (start == -1)
start = index;
for (; ++index < length; index++) {
c = s.charAt(index);
switch (c) {
case '\\':
index++;
break;
case '"':
break;
}
}
if (index >= length) {
if (!ignoreErrors)
throw new AddressException("Missing '\"'", s, index);
index = qindex + 1;
}
break;
case '[':
rfc822 = true;
lindex = index;
for (; ++index < length; index++) {
c = s.charAt(index);
switch (c) {
case '\\':
index++;
break;
case ']':
break;
}
}
if (index >= length) {
if (!ignoreErrors)
throw new AddressException("Missing ']'", s, index);
index = lindex + 1;
}
break;
case ';':
if (start == -1) {
route_addr = false;
rfc822 = false;
start = end = -1;
break;
}
if (in_group) {
in_group = false;
if (parseHdr && !strict && index + 1 < length &&
s.charAt(index + 1) == '@')
break;
InternetAddress ma = new InternetAddress();
end = index + 1;
ma.setAddress(s.substring(start, end).trim());
v.add(ma);
route_addr = false;
rfc822 = false;
start = end = -1;
start_personal = end_personal = -1;
break;
}
if (!ignoreErrors)
throw new AddressException("Illegal semicolon, not in group", s, index);
case ',':
if (start == -1) {
route_addr = false;
rfc822 = false;
start = end = -1;
break;
}
if (in_group) {
route_addr = false;
break;
}
if (end == -1)
end = index;
addr = s.substring(start, end).trim();
pers = null;
if (rfc822 && start_personal >= 0) {
pers = unquote(
s.substring(start_personal, end_personal).trim());
if (pers.trim().length() == 0)
pers = null;
}
if (parseHdr && !strict && pers != null &&
pers.indexOf('@') >= 0 &&
addr.indexOf('@') < 0 && addr.indexOf('!') < 0) {
String tmp = addr;
addr = pers;
pers = tmp;
}
if (rfc822 || strict || parseHdr) {
if (!ignoreErrors)
checkAddress(addr, route_addr, false);
InternetAddress ma = new InternetAddress();
ma.setAddress(addr);
if (pers != null)
ma.encodedPersonal = pers;
v.add(ma);
} else {
StringTokenizer st = new StringTokenizer(addr);
while (st.hasMoreTokens()) {
String str = st.nextToken();
checkAddress(str, false, false);
InternetAddress ma = new InternetAddress();
ma.setAddress(str);
v.add(ma);
}
}
route_addr = false;
rfc822 = false;
start = end = -1;
start_personal = end_personal = -1;
break;
case ':':
rfc822 = true;
if (in_group &&
!ignoreErrors)
throw new AddressException("Nested group", s, index);
if (start == -1)
start = index;
if (parseHdr && !strict) {
if (index + 1 < length) {
String addressSpecials = ")>[]:@\\,.";
char nc = s.charAt(index + 1);
if (addressSpecials.indexOf(nc) >= 0) {
if (nc != '@')
break;
for (int i = index + 2; i < length; i++) {
nc = s.charAt(i);
if (nc == ';')
break;
if (addressSpecials.indexOf(nc) >= 0)
break;
}
if (nc == ';')
break;
}
}
String gname = s.substring(start, index);
if (ignoreBogusGroupName && (
gname.equalsIgnoreCase("mailto") ||
gname.equalsIgnoreCase("From") ||
gname.equalsIgnoreCase("To") ||
gname.equalsIgnoreCase("Cc") ||
gname.equalsIgnoreCase("Subject") ||
gname.equalsIgnoreCase("Re"))) {
start = -1;
} else {
in_group = true;
}
break;
}
in_group = true;
break;
case '\t':
case '\n':
case '\r':
case ' ':
break;
default:
if (start == -1)
start = index;
break;
}
}
if (start >= 0) {
if (end == -1)
end = length;
String addr = s.substring(start, end).trim();
String pers = null;
if (rfc822 && start_personal >= 0) {
pers = unquote(
s.substring(start_personal, end_personal).trim());
if (pers.trim().length() == 0)
pers = null;
}
if (parseHdr && !strict && pers != null &&
pers.indexOf('@') >= 0 &&
addr.indexOf('@') < 0 && addr.indexOf('!') < 0) {
String tmp = addr;
addr = pers;
pers = tmp;
}
if (rfc822 || strict || parseHdr) {
if (!ignoreErrors)
checkAddress(addr, route_addr, false);
InternetAddress ma = new InternetAddress();
ma.setAddress(addr);
if (pers != null)
ma.encodedPersonal = pers;
v.add(ma);
} else {
StringTokenizer st = new StringTokenizer(addr);
while (st.hasMoreTokens()) {
String str = st.nextToken();
checkAddress(str, false, false);
InternetAddress ma = new InternetAddress();
ma.setAddress(str);
v.add(ma);
}
}
}
InternetAddress[] a = new InternetAddress[v.size()];
v.<InternetAddress>toArray(a);
return a;
}
public void validate() throws AddressException {
if (isGroup()) {
getGroup(true);
} else {
checkAddress(getAddress(), true, true);
}
}
private static void checkAddress(String addr, boolean routeAddr, boolean validate) throws AddressException {
int start = 0;
if (addr == null)
throw new AddressException("Address is null");
int len = addr.length();
if (len == 0)
throw new AddressException("Empty address", addr);
if (routeAddr && addr.charAt(0) == '@') {
int j;
for (start = 0; (j = indexOfAny(addr, ",:", start)) >= 0;
start = j + 1) {
if (addr.charAt(start) != '@')
throw new AddressException("Illegal route-addr", addr);
if (addr.charAt(j) == ':') {
start = j + 1;
break;
}
}
}
char c = Character.MAX_VALUE;
char lastc = Character.MAX_VALUE;
boolean inquote = false;
int i;
for (i = start; i < len; i++) {
lastc = c;
c = addr.charAt(i);
if (c != '\\' && lastc != '\\')
if (c == '"') {
if (inquote) {
if (validate && i + 1 < len && addr.charAt(i + 1) != '@')
throw new AddressException("Quote not at end of local address", addr);
inquote = false;
} else {
if (validate && i != 0)
throw new AddressException("Quote not at start of local address", addr);
inquote = true;
}
} else if (!inquote) {
if (c == '@') {
if (i == 0)
throw new AddressException("Missing local name", addr);
break;
}
if (c <= ' ' || c >= '\u007F')
throw new AddressException("Local address contains control or whitespace", addr);
if ("()<>,;:\\\"[]@".indexOf(c) >= 0)
throw new AddressException("Local address contains illegal character", addr);
}
}
if (inquote)
throw new AddressException("Unterminated quote", addr);
if (c != '@') {
if (validate)
throw new AddressException("Missing final '@domain'", addr);
return;
}
start = i + 1;
if (start >= len)
throw new AddressException("Missing domain", addr);
if (addr.charAt(start) == '.')
throw new AddressException("Domain starts with dot", addr);
for (i = start; i < len; i++) {
c = addr.charAt(i);
if (c == '[')
return;
if (c <= ' ' || c >= '\u007F')
throw new AddressException("Domain contains control or whitespace", addr);
if (!Character.isLetterOrDigit(c) && c != '-' && c != '.')
throw new AddressException("Domain contains illegal character", addr);
if (c == '.' && lastc == '.')
throw new AddressException("Domain contains dot-dot", addr);
lastc = c;
}
if (lastc == '.')
throw new AddressException("Domain ends with dot", addr);
}
private boolean isSimple() {
return (this.address == null || indexOfAny(this.address, "()<>,;:\\\"[]") < 0);
}
public boolean isGroup() {
return (this.address != null &&
this.address.endsWith(";") && this.address.indexOf(':') > 0);
}
public InternetAddress[] getGroup(boolean strict) throws AddressException {
String addr = getAddress();
if (addr == null)
return null;
if (!addr.endsWith(";"))
return null;
int ix = addr.indexOf(':');
if (ix < 0)
return null;
String list = addr.substring(ix + 1, addr.length() - 1);
return parseHeader(list, strict);
}
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;
}
}
}

View file

@ -0,0 +1,308 @@
package javax.mail.internet;
import com.sun.mail.util.LineInputStream;
import com.sun.mail.util.PropUtil;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import javax.mail.Header;
import javax.mail.MessagingException;
public class InternetHeaders {
private static final boolean ignoreWhitespaceLines = PropUtil.getBooleanSystemProperty("mail.mime.ignorewhitespacelines", false);
protected List headers;
protected static final class InternetHeader extends Header {
String line;
public InternetHeader(String l) {
super("", "");
int i = l.indexOf(':');
if (i < 0) {
this.name = l.trim();
} else {
this.name = l.substring(0, i).trim();
}
this.line = l;
}
public InternetHeader(String n, String v) {
super(n, "");
if (v != null) {
this.line = n + ": " + v;
} else {
this.line = null;
}
}
public String getValue() {
int i = this.line.indexOf(':');
if (i < 0)
return this.line;
int j;
for (j = i + 1; j < this.line.length(); j++) {
char c = this.line.charAt(j);
if (c != ' ' && c != '\t' && c != '\r' && c != '\n')
break;
}
return this.line.substring(j);
}
}
static class MatchEnum implements Enumeration {
private Iterator e;
private String[] names;
private boolean match;
private boolean want_line;
private InternetHeaders.InternetHeader next_header;
MatchEnum(List v, String[] n, boolean m, boolean l) {
this.e = v.iterator();
this.names = n;
this.match = m;
this.want_line = l;
this.next_header = null;
}
public boolean hasMoreElements() {
if (this.next_header == null)
this.next_header = nextMatch();
return (this.next_header != null);
}
public Object nextElement() {
if (this.next_header == null)
this.next_header = nextMatch();
if (this.next_header == null)
throw new NoSuchElementException("No more headers");
InternetHeaders.InternetHeader h = this.next_header;
this.next_header = null;
if (this.want_line)
return h.line;
return new Header(h.getName(), h.getValue());
}
private InternetHeaders.InternetHeader nextMatch() {
label23: while (this.e.hasNext()) {
InternetHeaders.InternetHeader h = this.e.next();
if (h.line == null)
continue;
if (this.names == null)
return this.match ? null : h;
for (int i = 0; i < this.names.length; i++) {
if (this.names[i].equalsIgnoreCase(h.getName())) {
if (this.match)
return h;
continue label23;
}
}
if (!this.match)
return h;
}
return null;
}
}
public InternetHeaders() {
this.headers = new ArrayList(40);
this.headers.add(new InternetHeader("Return-Path", null));
this.headers.add(new InternetHeader("Received", null));
this.headers.add(new InternetHeader("Resent-Date", null));
this.headers.add(new InternetHeader("Resent-From", null));
this.headers.add(new InternetHeader("Resent-Sender", null));
this.headers.add(new InternetHeader("Resent-To", null));
this.headers.add(new InternetHeader("Resent-Cc", null));
this.headers.add(new InternetHeader("Resent-Bcc", null));
this.headers.add(new InternetHeader("Resent-Message-Id", null));
this.headers.add(new InternetHeader("Date", null));
this.headers.add(new InternetHeader("From", null));
this.headers.add(new InternetHeader("Sender", null));
this.headers.add(new InternetHeader("Reply-To", null));
this.headers.add(new InternetHeader("To", null));
this.headers.add(new InternetHeader("Cc", null));
this.headers.add(new InternetHeader("Bcc", null));
this.headers.add(new InternetHeader("Message-Id", null));
this.headers.add(new InternetHeader("In-Reply-To", null));
this.headers.add(new InternetHeader("References", null));
this.headers.add(new InternetHeader("Subject", null));
this.headers.add(new InternetHeader("Comments", null));
this.headers.add(new InternetHeader("Keywords", null));
this.headers.add(new InternetHeader("Errors-To", null));
this.headers.add(new InternetHeader("MIME-Version", null));
this.headers.add(new InternetHeader("Content-Type", null));
this.headers.add(new InternetHeader("Content-Transfer-Encoding", null));
this.headers.add(new InternetHeader("Content-MD5", null));
this.headers.add(new InternetHeader(":", null));
this.headers.add(new InternetHeader("Content-Length", null));
this.headers.add(new InternetHeader("Status", null));
}
public InternetHeaders(InputStream is) throws MessagingException {
this.headers = new ArrayList(40);
load(is);
}
public void load(InputStream is) throws MessagingException {
LineInputStream lis = new LineInputStream(is);
String prevline = null;
StringBuffer lineBuffer = new StringBuffer();
try {
String line;
do {
line = lis.readLine();
if (line != null && (
line.startsWith(" ") || line.startsWith("\t"))) {
if (prevline != null) {
lineBuffer.append(prevline);
prevline = null;
}
lineBuffer.append("\r\n");
lineBuffer.append(line);
} else {
if (prevline != null) {
addHeaderLine(prevline);
} else if (lineBuffer.length() > 0) {
addHeaderLine(lineBuffer.toString());
lineBuffer.setLength(0);
}
prevline = line;
}
} while (line != null && !isEmpty(line));
} catch (IOException ioex) {
throw new MessagingException("Error in input stream", ioex);
}
}
private static final boolean isEmpty(String line) {
return (line.length() == 0 || (ignoreWhitespaceLines &&
line.trim().length() == 0));
}
public String[] getHeader(String name) {
Iterator<InternetHeader> e = this.headers.iterator();
List<String> v = new ArrayList();
while (e.hasNext()) {
InternetHeader h = e.next();
if (name.equalsIgnoreCase(h.getName()) && h.line != null)
v.add(h.getValue());
}
if (v.size() == 0)
return null;
String[] r = new String[v.size()];
r = v.<String>toArray(r);
return r;
}
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();
}
public void setHeader(String name, String value) {
boolean found = false;
for (int i = 0; i < this.headers.size(); i++) {
InternetHeader h = this.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;
} else {
h.line = name + ": " + value;
}
found = true;
} else {
this.headers.remove(i);
i--;
}
}
if (!found)
addHeader(name, value);
}
public void addHeader(String name, String value) {
int pos = this.headers.size();
boolean addReverse = (
name.equalsIgnoreCase("Received") ||
name.equalsIgnoreCase("Return-Path"));
if (addReverse)
pos = 0;
for (int i = this.headers.size() - 1; i >= 0; i--) {
InternetHeader h = this.headers.get(i);
if (name.equalsIgnoreCase(h.getName()))
if (addReverse) {
pos = i;
} else {
this.headers.add(i + 1, new InternetHeader(name, value));
return;
}
if (!addReverse && h.getName().equals(":"))
pos = i;
}
this.headers.add(pos, new InternetHeader(name, value));
}
public void removeHeader(String name) {
for (int i = 0; i < this.headers.size(); i++) {
InternetHeader h = this.headers.get(i);
if (name.equalsIgnoreCase(h.getName()))
h.line = null;
}
}
public Enumeration getAllHeaders() {
return new MatchEnum(this.headers, null, false, false);
}
public Enumeration getMatchingHeaders(String[] names) {
return new MatchEnum(this.headers, names, true, false);
}
public Enumeration getNonMatchingHeaders(String[] names) {
return new MatchEnum(this.headers, names, false, false);
}
public void addHeaderLine(String line) {
try {
char c = line.charAt(0);
if (c == ' ' || c == '\t') {
InternetHeader h = this.headers.get(this.headers.size() - 1);
h.line += "\r\n" + line;
} else {
this.headers.add(new InternetHeader(line));
}
} catch (StringIndexOutOfBoundsException e) {
return;
} catch (NoSuchElementException e) {}
}
public Enumeration getAllHeaderLines() {
return getNonMatchingHeaderLines(null);
}
public Enumeration getMatchingHeaderLines(String[] names) {
return new MatchEnum(this.headers, names, true, true);
}
public Enumeration getNonMatchingHeaderLines(String[] names) {
return new MatchEnum(this.headers, names, false, true);
}
}

View file

@ -0,0 +1,125 @@
package javax.mail.internet;
import com.sun.mail.util.MailLogger;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.logging.Level;
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);
}
public StringBuffer format(Date date, StringBuffer dateStrBuf, FieldPosition fieldPosition) {
int start = dateStrBuf.length();
super.format(date, dateStrBuf, fieldPosition);
int pos = 0;
for (pos = start + 25; dateStrBuf.charAt(pos) != 'X'; pos++);
this.calendar.clear();
this.calendar.setTime(date);
int offset = this.calendar.get(15) +
this.calendar.get(16);
if (offset < 0) {
dateStrBuf.setCharAt(pos++, '-');
offset = -offset;
} else {
dateStrBuf.setCharAt(pos++, '+');
}
int rawOffsetInMins = offset / 60 / 1000;
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));
return dateStrBuf;
}
public Date parse(String text, ParsePosition pos) {
return parseDate(text.toCharArray(), pos, isLenient());
}
static boolean debug = false;
private static MailLogger logger = new MailLogger(MailDateFormat.class, "DEBUG", debug, System.out);
private static 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());
p.skipUntilNumber();
day = p.parseNumber();
if (!p.skipIfChar('-'))
p.skipWhiteSpace();
month = p.parseMonth();
if (!p.skipIfChar('-'))
p.skipWhiteSpace();
year = p.parseNumber();
if (year < 50) {
year += 2000;
} else if (year < 100) {
year += 1900;
}
p.skipWhiteSpace();
hours = p.parseNumber();
p.skipChar(':');
minutes = p.parseNumber();
if (p.skipIfChar(':'))
seconds = p.parseNumber();
try {
p.skipWhiteSpace();
offset = p.parseTimeZone();
} catch (java.text.ParseException pe) {
if (logger.isLoggable(Level.FINE))
logger.log(Level.FINE, "No timezone? : '" + new String(orig) + "'", (Throwable)pe);
}
pos.setIndex(p.getIndex());
Date d = ourUTC(year, month, day, hours, minutes, seconds, offset, lenient);
return d;
} catch (Exception e) {
if (logger.isLoggable(Level.FINE))
logger.log(Level.FINE, "Bad date: '" + new String(orig) + "'", (Throwable)e);
pos.setIndex(1);
return null;
}
}
private static final Calendar cal = new GregorianCalendar(
TimeZone.getTimeZone("GMT"));
private static synchronized Date ourUTC(int year, int mon, int mday, int hour, int min, int sec, int tzoffset, boolean lenient) {
cal.clear();
cal.setLenient(lenient);
cal.set(1, year);
cal.set(2, mon);
cal.set(5, mday);
cal.set(11, hour);
cal.set(12, min);
cal.add(12, tzoffset);
cal.set(13, sec);
return cal.getTime();
}
public void setCalendar(Calendar newCalendar) {
throw new RuntimeException("Method setCalendar() shouldn't be called");
}
public void setNumberFormat(NumberFormat newNumberFormat) {
throw new RuntimeException("Method setNumberFormat() shouldn't be called");
}
}

View file

@ -0,0 +1,336 @@
package javax.mail.internet;
class MailDateParser {
int index = 0;
char[] orig = null;
public MailDateParser(char[] orig, int index) {
this.orig = orig;
this.index = index;
}
public void skipUntilNumber() throws java.text.ParseException {
try {
while (true) {
switch (this.orig[this.index]) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return;
}
this.index++;
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new java.text.ParseException("No Number Found", this.index);
}
}
public void skipWhiteSpace() {
int len = this.orig.length;
while (this.index < len) {
switch (this.orig[this.index]) {
case '\t':
case '\n':
case '\r':
case ' ':
this.index++;
continue;
}
return;
}
}
public int peekChar() throws java.text.ParseException {
if (this.index < this.orig.length)
return this.orig[this.index];
throw new java.text.ParseException("No more characters", this.index);
}
public void skipChar(char c) throws java.text.ParseException {
if (this.index < this.orig.length) {
if (this.orig[this.index] == c) {
this.index++;
} else {
throw new java.text.ParseException("Wrong char", this.index);
}
} else {
throw new java.text.ParseException("No more characters", this.index);
}
}
public boolean skipIfChar(char c) throws java.text.ParseException {
if (this.index < this.orig.length) {
if (this.orig[this.index] == c) {
this.index++;
return true;
}
return false;
}
throw new java.text.ParseException("No more characters", this.index);
}
public int parseNumber() throws java.text.ParseException {
int length = this.orig.length;
boolean gotNum = false;
int result = 0;
while (this.index < length) {
switch (this.orig[this.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;
throw new java.text.ParseException("No Number found", this.index);
}
this.index++;
}
if (gotNum)
return result;
throw new java.text.ParseException("No Number found", this.index);
}
public int parseMonth() throws java.text.ParseException {
try {
char curr;
switch (this.orig[this.index++]) {
case 'J':
case 'j':
switch (this.orig[this.index++]) {
case 'A':
case 'a':
curr = this.orig[this.index++];
if (curr == 'N' || curr == 'n')
return 0;
break;
case 'U':
case 'u':
curr = this.orig[this.index++];
if (curr == 'N' || curr == 'n')
return 5;
if (curr == 'L' || curr == 'l')
return 6;
break;
}
break;
case 'F':
case 'f':
curr = this.orig[this.index++];
if (curr == 'E' || curr == 'e') {
curr = this.orig[this.index++];
if (curr == 'B' || curr == 'b')
return 1;
}
break;
case 'M':
case 'm':
curr = this.orig[this.index++];
if (curr == 'A' || curr == 'a') {
curr = this.orig[this.index++];
if (curr == 'R' || curr == 'r')
return 2;
if (curr == 'Y' || curr == 'y')
return 4;
}
break;
case 'A':
case 'a':
curr = this.orig[this.index++];
if (curr == 'P' || curr == 'p') {
curr = this.orig[this.index++];
if (curr == 'R' || curr == 'r')
return 3;
break;
}
if (curr == 'U' || curr == 'u') {
curr = this.orig[this.index++];
if (curr == 'G' || curr == 'g')
return 7;
}
break;
case 'S':
case 's':
curr = this.orig[this.index++];
if (curr == 'E' || curr == 'e') {
curr = this.orig[this.index++];
if (curr == 'P' || curr == 'p')
return 8;
}
break;
case 'O':
case 'o':
curr = this.orig[this.index++];
if (curr == 'C' || curr == 'c') {
curr = this.orig[this.index++];
if (curr == 'T' || curr == 't')
return 9;
}
break;
case 'N':
case 'n':
curr = this.orig[this.index++];
if (curr == 'O' || curr == 'o') {
curr = this.orig[this.index++];
if (curr == 'V' || curr == 'v')
return 10;
}
break;
case 'D':
case 'd':
curr = this.orig[this.index++];
if (curr == 'E' || curr == 'e') {
curr = this.orig[this.index++];
if (curr == 'C' || curr == 'c')
return 11;
}
break;
}
} catch (ArrayIndexOutOfBoundsException e) {}
throw new java.text.ParseException("Bad Month", this.index);
}
public int parseTimeZone() throws java.text.ParseException {
if (this.index >= this.orig.length)
throw new java.text.ParseException("No more characters", this.index);
char test = this.orig[this.index];
if (test == '+' || test == '-')
return parseNumericTimeZone();
return parseAlphaTimeZone();
}
public int parseNumericTimeZone() throws java.text.ParseException {
boolean switchSign = false;
char first = this.orig[this.index++];
if (first == '+') {
switchSign = true;
} else if (first != '-') {
throw new java.text.ParseException("Bad Numeric TimeZone", this.index);
}
int oindex = this.index;
int tz = parseNumber();
if (tz >= 2400)
throw new java.text.ParseException("Numeric TimeZone out of range", oindex);
int offset = tz / 100 * 60 + tz % 100;
if (switchSign)
return -offset;
return offset;
}
public int parseAlphaTimeZone() throws java.text.ParseException {
int result = 0;
boolean foundCommon = false;
try {
char curr;
switch (this.orig[this.index++]) {
case 'U':
case 'u':
curr = this.orig[this.index++];
if (curr == 'T' || curr == 't') {
result = 0;
break;
}
throw new java.text.ParseException("Bad Alpha TimeZone", this.index);
case 'G':
case 'g':
curr = this.orig[this.index++];
if (curr == 'M' || curr == 'm') {
curr = this.orig[this.index++];
if (curr == 'T' || curr == 't') {
result = 0;
break;
}
}
throw new java.text.ParseException("Bad Alpha TimeZone", this.index);
case 'E':
case 'e':
result = 300;
foundCommon = true;
break;
case 'C':
case 'c':
result = 360;
foundCommon = true;
break;
case 'M':
case 'm':
result = 420;
foundCommon = true;
break;
case 'P':
case 'p':
result = 480;
foundCommon = true;
break;
default:
throw new java.text.ParseException("Bad Alpha TimeZone", this.index);
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new java.text.ParseException("Bad Alpha TimeZone", this.index);
}
if (foundCommon) {
char curr = this.orig[this.index++];
if (curr == 'S' || curr == 's') {
curr = this.orig[this.index++];
if (curr != 'T' && curr != 't')
throw new java.text.ParseException("Bad Alpha TimeZone", this.index);
} else if (curr == 'D' || curr == 'd') {
curr = this.orig[this.index++];
if (curr == 'T' || curr != 't') {
result -= 60;
} else {
throw new java.text.ParseException("Bad Alpha TimeZone", this.index);
}
}
}
return result;
}
int getIndex() {
return this.index;
}
}

View file

@ -0,0 +1,739 @@
package javax.mail.internet;
import com.sun.mail.util.ASCIIUtility;
import com.sun.mail.util.FolderClosedIOException;
import com.sun.mail.util.LineOutputStream;
import com.sun.mail.util.MessageRemovedIOException;
import com.sun.mail.util.MimeUtil;
import com.sun.mail.util.PropUtil;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Vector;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.EncodingAware;
import javax.mail.FolderClosedException;
import javax.mail.MessageRemovedException;
import javax.mail.MessagingException;
import javax.mail.Multipart;
public class MimeBodyPart extends BodyPart implements MimePart {
private static final boolean setDefaultTextCharset = PropUtil.getBooleanSystemProperty("mail.mime.setdefaulttextcharset", true);
private static final boolean setContentTypeFileName = PropUtil.getBooleanSystemProperty("mail.mime.setcontenttypefilename", true);
private static final boolean encodeFileName = PropUtil.getBooleanSystemProperty("mail.mime.encodefilename", false);
private static final boolean decodeFileName = PropUtil.getBooleanSystemProperty("mail.mime.decodefilename", false);
private static final boolean ignoreMultipartEncoding = PropUtil.getBooleanSystemProperty("mail.mime.ignoremultipartencoding", true);
static final boolean cacheMultipart = PropUtil.getBooleanSystemProperty("mail.mime.cachemultipart", true);
protected DataHandler dh;
protected byte[] content;
protected InputStream contentStream;
protected InternetHeaders headers;
protected Object cachedContent;
public MimeBodyPart() {
this.headers = new InternetHeaders();
}
public MimeBodyPart(InputStream is) throws MessagingException {
if (!(is instanceof ByteArrayInputStream) && !(is instanceof BufferedInputStream) && !(is instanceof SharedInputStream))
is = new BufferedInputStream(is);
this.headers = new InternetHeaders(is);
if (is instanceof SharedInputStream) {
SharedInputStream sis = (SharedInputStream)is;
this.contentStream = sis.newStream(sis.getPosition(), -1L);
} else {
try {
this.content = ASCIIUtility.getBytes(is);
} catch (IOException ioex) {
throw new MessagingException("Error reading input stream", ioex);
}
}
}
public MimeBodyPart(InternetHeaders headers, byte[] content) throws MessagingException {
this.headers = headers;
this.content = content;
}
public int getSize() throws MessagingException {
if (this.content != null)
return this.content.length;
if (this.contentStream != null)
try {
int size = this.contentStream.available();
if (size > 0)
return size;
} catch (IOException e) {}
return -1;
}
public int getLineCount() throws MessagingException {
return -1;
}
public String getContentType() throws MessagingException {
String s = getHeader("Content-Type", null);
s = MimeUtil.cleanContentType(this, s);
if (s == null)
s = "text/plain";
return s;
}
public boolean isMimeType(String mimeType) throws MessagingException {
return isMimeType(this, mimeType);
}
public String getDisposition() throws MessagingException {
return getDisposition(this);
}
public void setDisposition(String disposition) throws MessagingException {
setDisposition(this, disposition);
}
public String getEncoding() throws MessagingException {
return getEncoding(this);
}
public String getContentID() throws MessagingException {
return getHeader("Content-Id", null);
}
public void setContentID(String cid) throws MessagingException {
if (cid == null) {
removeHeader("Content-ID");
} else {
setHeader("Content-ID", cid);
}
}
public String getContentMD5() throws MessagingException {
return getHeader("Content-MD5", null);
}
public void setContentMD5(String md5) throws MessagingException {
setHeader("Content-MD5", md5);
}
public String[] getContentLanguage() throws MessagingException {
return getContentLanguage(this);
}
public void setContentLanguage(String[] languages) throws MessagingException {
setContentLanguage(this, languages);
}
public String getDescription() throws MessagingException {
return getDescription(this);
}
public void setDescription(String description) throws MessagingException {
setDescription(description, null);
}
public void setDescription(String description, String charset) throws MessagingException {
setDescription(this, description, charset);
}
public String getFileName() throws MessagingException {
return getFileName(this);
}
public void setFileName(String filename) throws MessagingException {
setFileName(this, filename);
}
public InputStream getInputStream() throws IOException, MessagingException {
return getDataHandler().getInputStream();
}
protected InputStream getContentStream() throws MessagingException {
if (this.contentStream != null)
return ((SharedInputStream)this.contentStream).newStream(0L, -1L);
if (this.content != null)
return new ByteArrayInputStream(this.content);
throw new MessagingException("No MimeBodyPart content");
}
public InputStream getRawInputStream() throws MessagingException {
return getContentStream();
}
public DataHandler getDataHandler() throws MessagingException {
if (this.dh == null)
this.dh = new MimePartDataHandler(this);
return this.dh;
}
public Object getContent() throws IOException, MessagingException {
Object c;
if (this.cachedContent != null)
return this.cachedContent;
try {
c = getDataHandler().getContent();
} catch (FolderClosedIOException fex) {
throw new FolderClosedException(fex.getFolder(), fex.getMessage());
} catch (MessageRemovedIOException mex) {
throw new MessageRemovedException(mex.getMessage());
}
if (cacheMultipart && (c instanceof Multipart || c instanceof javax.mail.Message) && (this.content != null || this.contentStream != null)) {
this.cachedContent = c;
if (c instanceof MimeMultipart)
((MimeMultipart)c).parse();
}
return c;
}
public void setDataHandler(DataHandler dh) throws MessagingException {
this.dh = dh;
this.cachedContent = null;
invalidateContentHeaders(this);
}
public void setContent(Object o, String type) throws MessagingException {
if (o instanceof Multipart) {
setContent((Multipart)o);
} else {
setDataHandler(new DataHandler(o, type));
}
}
public void setText(String text) throws MessagingException {
setText(text, null);
}
public void setText(String text, String charset) throws MessagingException {
setText(this, text, charset, "plain");
}
public void setText(String text, String charset, String subtype) throws MessagingException {
setText(this, text, charset, subtype);
}
public void setContent(Multipart mp) throws MessagingException {
setDataHandler(new DataHandler(mp, mp.getContentType()));
mp.setParent(this);
}
public void attachFile(File file) throws IOException, MessagingException {
FileDataSource fds = new FileDataSource(file);
setDataHandler(new DataHandler((DataSource)fds));
setFileName(fds.getName());
setDisposition("attachment");
}
public void attachFile(String file) throws IOException, MessagingException {
File f = new File(file);
attachFile(f);
}
public void attachFile(File file, String contentType, String encoding) throws IOException, MessagingException {
EncodedFileDataSource encodedFileDataSource = new EncodedFileDataSource(file, contentType, encoding);
setDataHandler(new DataHandler((DataSource)encodedFileDataSource));
setFileName(encodedFileDataSource.getName());
setDisposition("attachment");
}
public void attachFile(String file, String contentType, String encoding) throws IOException, MessagingException {
attachFile(new File(file), contentType, encoding);
}
private static class EncodedFileDataSource extends FileDataSource implements EncodingAware {
private String contentType;
private String encoding;
public EncodedFileDataSource(File file, String contentType, String encoding) {
super(file);
this.contentType = contentType;
this.encoding = encoding;
}
public String getContentType() {
return (this.contentType != null) ? this.contentType : super.getContentType();
}
public String getEncoding() {
return this.encoding;
}
}
public void saveFile(File file) throws IOException, MessagingException {
OutputStream out = null;
InputStream in = null;
try {
out = new BufferedOutputStream(new FileOutputStream(file));
in = getInputStream();
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {}
try {
if (out != null)
out.close();
} catch (IOException e) {}
}
}
public void saveFile(String file) throws IOException, MessagingException {
File f = new File(file);
saveFile(f);
}
public void writeTo(OutputStream os) throws IOException, MessagingException {
writeTo(this, os, null);
}
public String[] getHeader(String name) throws MessagingException {
return this.headers.getHeader(name);
}
public String getHeader(String name, String delimiter) throws MessagingException {
return this.headers.getHeader(name, delimiter);
}
public void setHeader(String name, String value) throws MessagingException {
this.headers.setHeader(name, value);
}
public void addHeader(String name, String value) throws MessagingException {
this.headers.addHeader(name, value);
}
public void removeHeader(String name) throws MessagingException {
this.headers.removeHeader(name);
}
public Enumeration getAllHeaders() throws MessagingException {
return this.headers.getAllHeaders();
}
public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
return this.headers.getMatchingHeaders(names);
}
public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
return this.headers.getNonMatchingHeaders(names);
}
public void addHeaderLine(String line) throws MessagingException {
this.headers.addHeaderLine(line);
}
public Enumeration getAllHeaderLines() throws MessagingException {
return this.headers.getAllHeaderLines();
}
public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
return this.headers.getMatchingHeaderLines(names);
}
public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
return this.headers.getNonMatchingHeaderLines(names);
}
protected void updateHeaders() throws MessagingException {
updateHeaders(this);
if (this.cachedContent != null) {
this.dh = new DataHandler(this.cachedContent, getContentType());
this.cachedContent = null;
this.content = null;
if (this.contentStream != null)
try {
this.contentStream.close();
} catch (IOException e) {}
this.contentStream = null;
}
}
static boolean isMimeType(MimePart part, String mimeType) throws MessagingException {
try {
ContentType ct = new ContentType(part.getContentType());
return ct.match(mimeType);
} catch (ParseException ex) {
return part.getContentType().equalsIgnoreCase(mimeType);
}
}
static void setText(MimePart part, String text, String charset, String subtype) throws MessagingException {
if (charset == null)
if (MimeUtility.checkAscii(text) != 1) {
charset = MimeUtility.getDefaultMIMECharset();
} else {
charset = "us-ascii";
}
part.setContent(text, "text/" + subtype + "; charset=" +
MimeUtility.quote(charset, "()<>@,;:\\\"\t []/?="));
}
static String getDisposition(MimePart part) throws MessagingException {
String s = part.getHeader("Content-Disposition", null);
if (s == null)
return null;
ContentDisposition cd = new ContentDisposition(s);
return cd.getDisposition();
}
static void setDisposition(MimePart part, String disposition) throws MessagingException {
if (disposition == null) {
part.removeHeader("Content-Disposition");
} else {
String s = part.getHeader("Content-Disposition", null);
if (s != null) {
ContentDisposition cd = new ContentDisposition(s);
cd.setDisposition(disposition);
disposition = cd.toString();
}
part.setHeader("Content-Disposition", disposition);
}
}
static String getDescription(MimePart part) throws MessagingException {
String rawvalue = part.getHeader("Content-Description", null);
if (rawvalue == null)
return null;
try {
return MimeUtility.decodeText(MimeUtility.unfold(rawvalue));
} catch (UnsupportedEncodingException ex) {
return rawvalue;
}
}
static void setDescription(MimePart part, String description, String charset) throws MessagingException {
if (description == null) {
part.removeHeader("Content-Description");
return;
}
try {
part.setHeader("Content-Description", MimeUtility.fold(21,
MimeUtility.encodeText(description, charset, null)));
} catch (UnsupportedEncodingException uex) {
throw new MessagingException("Encoding error", uex);
}
}
static String getFileName(MimePart part) throws MessagingException {
String filename = null;
String s = part.getHeader("Content-Disposition", null);
if (s != null) {
ContentDisposition cd = new ContentDisposition(s);
filename = cd.getParameter("filename");
}
if (filename == null) {
s = part.getHeader("Content-Type", null);
s = MimeUtil.cleanContentType(part, s);
if (s != null)
try {
ContentType ct = new ContentType(s);
filename = ct.getParameter("name");
} catch (ParseException e) {}
}
if (decodeFileName && filename != null)
try {
filename = MimeUtility.decodeText(filename);
} catch (UnsupportedEncodingException ex) {
throw new MessagingException("Can't decode filename", ex);
}
return filename;
}
static void setFileName(MimePart part, String name) throws MessagingException {
if (encodeFileName && name != null)
try {
name = MimeUtility.encodeText(name);
} catch (UnsupportedEncodingException ex) {
throw new MessagingException("Can't encode filename", ex);
}
String s = part.getHeader("Content-Disposition", null);
ContentDisposition cd = new ContentDisposition((s == null) ? "attachment" : s);
String charset = MimeUtility.getDefaultMIMECharset();
ParameterList p = cd.getParameterList();
if (p == null) {
p = new ParameterList();
cd.setParameterList(p);
}
p.set("filename", name, charset);
part.setHeader("Content-Disposition", cd.toString());
if (setContentTypeFileName) {
s = part.getHeader("Content-Type", null);
s = MimeUtil.cleanContentType(part, s);
if (s != null)
try {
ContentType cType = new ContentType(s);
p = cType.getParameterList();
if (p == null) {
p = new ParameterList();
cType.setParameterList(p);
}
p.set("name", name, charset);
part.setHeader("Content-Type", cType.toString());
} catch (ParseException e) {}
}
}
static String[] getContentLanguage(MimePart part) throws MessagingException {
String s = part.getHeader("Content-Language", null);
if (s == null)
return null;
HeaderTokenizer h = new HeaderTokenizer(s, "()<>@,;:\\\"\t []/?=");
Vector<String> v = new Vector();
while (true) {
HeaderTokenizer.Token tk = h.next();
int tkType = tk.getType();
if (tkType == -4)
break;
if (tkType == -1)
v.addElement(tk.getValue());
}
if (v.size() == 0)
return null;
String[] language = new String[v.size()];
v.copyInto(language);
return language;
}
static void setContentLanguage(MimePart part, String[] languages) throws MessagingException {
StringBuffer sb = new StringBuffer(languages[0]);
int len = "Content-Language".length() + 2 + languages[0].length();
for (int i = 1; i < languages.length; i++) {
sb.append(',');
len++;
if (len > 76) {
sb.append("\r\n\t");
len = 8;
}
sb.append(languages[i]);
len += languages[i].length();
}
part.setHeader("Content-Language", sb.toString());
}
static String getEncoding(MimePart part) throws MessagingException {
String s = part.getHeader("Content-Transfer-Encoding", null);
if (s == null)
return null;
s = s.trim();
if (s.equalsIgnoreCase("7bit") || s.equalsIgnoreCase("8bit") ||
s.equalsIgnoreCase("quoted-printable") ||
s.equalsIgnoreCase("binary") ||
s.equalsIgnoreCase("base64"))
return s;
HeaderTokenizer h = new HeaderTokenizer(s, "()<>@,;:\\\"\t []/?=");
while (true) {
HeaderTokenizer.Token tk = h.next();
int tkType = tk.getType();
if (tkType == -4)
break;
if (tkType == -1)
return tk.getValue();
}
return s;
}
static void setEncoding(MimePart part, String encoding) throws MessagingException {
part.setHeader("Content-Transfer-Encoding", encoding);
}
static String restrictEncoding(MimePart part, String encoding) throws MessagingException {
if (!ignoreMultipartEncoding || encoding == null)
return encoding;
if (encoding.equalsIgnoreCase("7bit") ||
encoding.equalsIgnoreCase("8bit") ||
encoding.equalsIgnoreCase("binary"))
return encoding;
String type = part.getContentType();
if (type == null)
return encoding;
try {
ContentType cType = new ContentType(type);
if (cType.match("multipart/*"))
return null;
if (cType.match("message/*") &&
!PropUtil.getBooleanSystemProperty("mail.mime.allowencodedmessages", false))
return null;
} catch (ParseException e) {}
return encoding;
}
static void updateHeaders(MimePart part) throws MessagingException {
DataHandler dh = part.getDataHandler();
if (dh == null)
return;
try {
String type = dh.getContentType();
boolean composite = false;
boolean needCTHeader = (part.getHeader("Content-Type") == null);
ContentType cType = new ContentType(type);
if (cType.match("multipart/*")) {
Object o;
composite = true;
if (part instanceof MimeBodyPart) {
MimeBodyPart mbp = (MimeBodyPart)part;
o = (mbp.cachedContent != null) ? mbp.cachedContent : dh.getContent();
} else if (part instanceof MimeMessage) {
MimeMessage msg = (MimeMessage)part;
o = (msg.cachedContent != null) ? msg.cachedContent : dh.getContent();
} else {
o = dh.getContent();
}
if (o instanceof MimeMultipart) {
((MimeMultipart)o).updateHeaders();
} else {
throw new MessagingException("MIME part of type \"" + type + "\" contains object of type " +
o.getClass().getName() + " instead of MimeMultipart");
}
} else if (cType.match("message/rfc822")) {
composite = true;
}
if (dh instanceof MimePartDataHandler) {
MimePartDataHandler mdh = (MimePartDataHandler)dh;
MimePart mpart = mdh.getPart();
if (mpart != part) {
if (needCTHeader)
part.setHeader("Content-Type", mpart.getContentType());
String enc = mpart.getEncoding();
if (enc != null) {
setEncoding(part, enc);
return;
}
} else {
return;
}
}
if (!composite) {
if (part.getHeader("Content-Transfer-Encoding") == null)
setEncoding(part, MimeUtility.getEncoding(dh));
if (needCTHeader && setDefaultTextCharset &&
cType.match("text/*") &&
cType.getParameter("charset") == null) {
String charset;
String enc = part.getEncoding();
if (enc != null && enc.equalsIgnoreCase("7bit")) {
charset = "us-ascii";
} else {
charset = MimeUtility.getDefaultMIMECharset();
}
cType.setParameter("charset", charset);
type = cType.toString();
}
}
if (needCTHeader) {
if (setContentTypeFileName) {
String s = part.getHeader("Content-Disposition", null);
if (s != null) {
ContentDisposition cd = new ContentDisposition(s);
String filename = cd.getParameter("filename");
if (filename != null) {
ParameterList p = cType.getParameterList();
if (p == null) {
p = new ParameterList();
cType.setParameterList(p);
}
p.set("name", filename,
MimeUtility.getDefaultMIMECharset());
type = cType.toString();
}
}
}
part.setHeader("Content-Type", type);
}
} catch (IOException ex) {
throw new MessagingException("IOException updating headers", ex);
}
}
static void invalidateContentHeaders(MimePart part) throws MessagingException {
part.removeHeader("Content-Type");
part.removeHeader("Content-Transfer-Encoding");
}
static void writeTo(MimePart part, OutputStream os, String[] ignoreList) throws IOException, MessagingException {
LineOutputStream los = null;
if (os instanceof LineOutputStream) {
los = (LineOutputStream)os;
} else {
los = new LineOutputStream(os);
}
Enumeration<String> hdrLines = part.getNonMatchingHeaderLines(ignoreList);
while (hdrLines.hasMoreElements())
los.writeln(hdrLines.nextElement());
los.writeln();
InputStream is = null;
byte[] buf = null;
try {
DataHandler dh = part.getDataHandler();
if (dh instanceof MimePartDataHandler) {
MimePartDataHandler mpdh = (MimePartDataHandler)dh;
MimePart mpart = mpdh.getPart();
if (mpart.getEncoding() != null)
is = mpdh.getContentStream();
}
if (is != null) {
buf = new byte[8192];
int len;
while ((len = is.read(buf)) > 0)
os.write(buf, 0, len);
} else {
os = MimeUtility.encode(os,
restrictEncoding(part, part.getEncoding()));
part.getDataHandler().writeTo(os);
}
} finally {
if (is != null)
is.close();
buf = null;
}
os.flush();
}
static class MimePartDataHandler extends DataHandler {
MimePart part;
public MimePartDataHandler(MimePart part) {
super(new MimePartDataSource(part));
this.part = part;
}
InputStream getContentStream() throws MessagingException {
InputStream is = null;
if (this.part instanceof MimeBodyPart) {
MimeBodyPart mbp = (MimeBodyPart)this.part;
is = mbp.getContentStream();
} else if (this.part instanceof MimeMessage) {
MimeMessage msg = (MimeMessage)this.part;
is = msg.getContentStream();
}
return is;
}
MimePart getPart() {
return this.part;
}
}
}

View file

@ -0,0 +1,798 @@
package javax.mail.internet;
import com.sun.mail.util.ASCIIUtility;
import com.sun.mail.util.FolderClosedIOException;
import com.sun.mail.util.LineOutputStream;
import com.sun.mail.util.MessageRemovedIOException;
import com.sun.mail.util.MimeUtil;
import com.sun.mail.util.PropUtil;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectStreamException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Vector;
import javax.activation.DataHandler;
import javax.mail.Address;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.FolderClosedException;
import javax.mail.Message;
import javax.mail.MessageRemovedException;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.util.SharedByteArrayInputStream;
public class MimeMessage extends Message implements MimePart {
protected DataHandler dh;
protected byte[] content;
protected InputStream contentStream;
protected InternetHeaders headers;
protected Flags flags;
protected boolean modified;
protected boolean saved;
protected Object cachedContent;
private static final MailDateFormat mailDateFormat = new MailDateFormat();
private boolean strict;
public MimeMessage(Session session) {
super(session);
this.modified = false;
this.saved = false;
this.strict = true;
this.modified = true;
this.headers = new InternetHeaders();
this.flags = new Flags();
initStrict();
}
public MimeMessage(Session session, InputStream is) throws MessagingException {
super(session);
this.modified = false;
this.saved = false;
this.strict = true;
this.flags = new Flags();
initStrict();
parse(is);
this.saved = true;
}
public MimeMessage(MimeMessage source) throws MessagingException {
super(source.session);
ByteArrayOutputStream bos;
this.modified = false;
this.saved = false;
this.strict = true;
this.flags = source.getFlags();
if (this.flags == null)
this.flags = new Flags();
int size = source.getSize();
if (size > 0) {
bos = new ByteArrayOutputStream(size);
} else {
bos = new ByteArrayOutputStream();
}
try {
this.strict = source.strict;
source.writeTo(bos);
bos.close();
SharedByteArrayInputStream bis = new SharedByteArrayInputStream(
bos.toByteArray());
parse(bis);
bis.close();
this.saved = true;
} catch (IOException ex) {
throw new MessagingException("IOException while copying message", ex);
}
}
protected MimeMessage(Folder folder, int msgnum) {
super(folder, msgnum);
this.modified = false;
this.saved = false;
this.strict = true;
this.flags = new Flags();
this.saved = true;
initStrict();
}
protected MimeMessage(Folder folder, InputStream is, int msgnum) throws MessagingException {
this(folder, msgnum);
initStrict();
parse(is);
}
protected MimeMessage(Folder folder, InternetHeaders headers, byte[] content, int msgnum) throws MessagingException {
this(folder, msgnum);
this.headers = headers;
this.content = content;
initStrict();
}
private void initStrict() {
if (this.session != null)
this.strict = PropUtil.getBooleanSessionProperty(this.session, "mail.mime.address.strict", true);
}
protected void parse(InputStream is) throws MessagingException {
if (!(is instanceof java.io.ByteArrayInputStream) && !(is instanceof BufferedInputStream) && !(is instanceof SharedInputStream))
is = new BufferedInputStream(is);
this.headers = createInternetHeaders(is);
if (is instanceof SharedInputStream) {
SharedInputStream sis = (SharedInputStream)is;
this.contentStream = sis.newStream(sis.getPosition(), -1L);
} else {
try {
this.content = ASCIIUtility.getBytes(is);
} catch (IOException ioex) {
throw new MessagingException("IOException", ioex);
}
}
this.modified = false;
}
public Address[] getFrom() throws MessagingException {
Address[] a = getAddressHeader("From");
if (a == null)
a = getAddressHeader("Sender");
return a;
}
public void setFrom(Address address) throws MessagingException {
if (address == null) {
removeHeader("From");
} else {
setHeader("From", address.toString());
}
}
public void setFrom(String address) throws MessagingException {
if (address == null) {
removeHeader("From");
} else {
setAddressHeader("From", InternetAddress.parse(address));
}
}
public void setFrom() throws MessagingException {
InternetAddress me = null;
try {
me = InternetAddress._getLocalAddress(this.session);
} catch (Exception ex) {
throw new MessagingException("No From address", ex);
}
if (me != null) {
setFrom(me);
} else {
throw new MessagingException("No From address");
}
}
public void addFrom(Address[] addresses) throws MessagingException {
addAddressHeader("From", addresses);
}
public Address getSender() throws MessagingException {
Address[] a = getAddressHeader("Sender");
if (a == null || a.length == 0)
return null;
return a[0];
}
public void setSender(Address address) throws MessagingException {
if (address == null) {
removeHeader("Sender");
} else {
setHeader("Sender", address.toString());
}
}
public static class RecipientType extends Message.RecipientType {
private static final long serialVersionUID = -5468290701714395543L;
public static final RecipientType NEWSGROUPS = new RecipientType("Newsgroups");
protected RecipientType(String type) {
super(type);
}
protected Object readResolve() throws ObjectStreamException {
if (this.type.equals("Newsgroups"))
return NEWSGROUPS;
return super.readResolve();
}
}
public Address[] getRecipients(Message.RecipientType type) throws MessagingException {
if (type == RecipientType.NEWSGROUPS) {
String s = getHeader("Newsgroups", ",");
return (s == null) ? null : NewsAddress.parse(s);
}
return getAddressHeader(getHeaderName(type));
}
public Address[] getAllRecipients() throws MessagingException {
Address[] all = super.getAllRecipients();
Address[] ng = getRecipients(RecipientType.NEWSGROUPS);
if (ng == null)
return all;
if (all == null)
return ng;
Address[] addresses = new Address[all.length + ng.length];
System.arraycopy(all, 0, addresses, 0, all.length);
System.arraycopy(ng, 0, addresses, all.length, ng.length);
return addresses;
}
public void setRecipients(Message.RecipientType type, Address[] addresses) throws MessagingException {
if (type == RecipientType.NEWSGROUPS) {
if (addresses == null || addresses.length == 0) {
removeHeader("Newsgroups");
} else {
setHeader("Newsgroups", NewsAddress.toString(addresses));
}
} else {
setAddressHeader(getHeaderName(type), addresses);
}
}
public void setRecipients(Message.RecipientType type, String addresses) throws MessagingException {
if (type == RecipientType.NEWSGROUPS) {
if (addresses == null || addresses.length() == 0) {
removeHeader("Newsgroups");
} else {
setHeader("Newsgroups", addresses);
}
} else {
setAddressHeader(getHeaderName(type), (addresses == null) ? null :
InternetAddress.parse(addresses));
}
}
public void addRecipients(Message.RecipientType type, Address[] addresses) throws MessagingException {
if (type == RecipientType.NEWSGROUPS) {
String s = NewsAddress.toString(addresses);
if (s != null)
addHeader("Newsgroups", s);
} else {
addAddressHeader(getHeaderName(type), addresses);
}
}
public void addRecipients(Message.RecipientType type, String addresses) throws MessagingException {
if (type == RecipientType.NEWSGROUPS) {
if (addresses != null && addresses.length() != 0)
addHeader("Newsgroups", addresses);
} else {
addAddressHeader(getHeaderName(type), InternetAddress.parse(addresses));
}
}
public Address[] getReplyTo() throws MessagingException {
Address[] a = getAddressHeader("Reply-To");
if (a == null || a.length == 0)
a = getFrom();
return a;
}
public void setReplyTo(Address[] addresses) throws MessagingException {
setAddressHeader("Reply-To", addresses);
}
private Address[] getAddressHeader(String name) throws MessagingException {
String s = getHeader(name, ",");
return (s == null) ? null : InternetAddress.parseHeader(s, this.strict);
}
private void setAddressHeader(String name, Address[] addresses) throws MessagingException {
String s = InternetAddress.toString(addresses, name.length() + 2);
if (s == null) {
removeHeader(name);
} else {
setHeader(name, s);
}
}
private void addAddressHeader(String name, Address[] addresses) throws MessagingException {
Address[] anew;
if (addresses == null || addresses.length == 0)
return;
Address[] a = getAddressHeader(name);
if (a == null || a.length == 0) {
anew = addresses;
} else {
anew = new Address[a.length + addresses.length];
System.arraycopy(a, 0, anew, 0, a.length);
System.arraycopy(addresses, 0, anew, a.length, addresses.length);
}
String s = InternetAddress.toString(anew, name.length() + 2);
if (s == null)
return;
setHeader(name, s);
}
public String getSubject() throws MessagingException {
String rawvalue = getHeader("Subject", null);
if (rawvalue == null)
return null;
try {
return MimeUtility.decodeText(MimeUtility.unfold(rawvalue));
} catch (UnsupportedEncodingException ex) {
return rawvalue;
}
}
public void setSubject(String subject) throws MessagingException {
setSubject(subject, null);
}
public void setSubject(String subject, String charset) throws MessagingException {
if (subject == null) {
removeHeader("Subject");
} else {
try {
setHeader("Subject", MimeUtility.fold(9,
MimeUtility.encodeText(subject, charset, null)));
} catch (UnsupportedEncodingException uex) {
throw new MessagingException("Encoding error", uex);
}
}
}
public Date getSentDate() throws MessagingException {
String s = getHeader("Date", null);
if (s != null)
try {
synchronized (mailDateFormat) {
return mailDateFormat.parse(s);
}
} catch (java.text.ParseException pex) {
return null;
}
return null;
}
public void setSentDate(Date d) throws MessagingException {
if (d == null) {
removeHeader("Date");
} else {
synchronized (mailDateFormat) {
setHeader("Date", mailDateFormat.format(d));
}
}
}
public Date getReceivedDate() throws MessagingException {
return null;
}
public int getSize() throws MessagingException {
if (this.content != null)
return this.content.length;
if (this.contentStream != null)
try {
int size = this.contentStream.available();
if (size > 0)
return size;
} catch (IOException e) {}
return -1;
}
public int getLineCount() throws MessagingException {
return -1;
}
public String getContentType() throws MessagingException {
String s = getHeader("Content-Type", null);
s = MimeUtil.cleanContentType(this, s);
if (s == null)
return "text/plain";
return s;
}
public boolean isMimeType(String mimeType) throws MessagingException {
return MimeBodyPart.isMimeType(this, mimeType);
}
public String getDisposition() throws MessagingException {
return MimeBodyPart.getDisposition(this);
}
public void setDisposition(String disposition) throws MessagingException {
MimeBodyPart.setDisposition(this, disposition);
}
public String getEncoding() throws MessagingException {
return MimeBodyPart.getEncoding(this);
}
public String getContentID() throws MessagingException {
return getHeader("Content-Id", null);
}
public void setContentID(String cid) throws MessagingException {
if (cid == null) {
removeHeader("Content-ID");
} else {
setHeader("Content-ID", cid);
}
}
public String getContentMD5() throws MessagingException {
return getHeader("Content-MD5", null);
}
public void setContentMD5(String md5) throws MessagingException {
setHeader("Content-MD5", md5);
}
public String getDescription() throws MessagingException {
return MimeBodyPart.getDescription(this);
}
public void setDescription(String description) throws MessagingException {
setDescription(description, null);
}
public void setDescription(String description, String charset) throws MessagingException {
MimeBodyPart.setDescription(this, description, charset);
}
public String[] getContentLanguage() throws MessagingException {
return MimeBodyPart.getContentLanguage(this);
}
public void setContentLanguage(String[] languages) throws MessagingException {
MimeBodyPart.setContentLanguage(this, languages);
}
public String getMessageID() throws MessagingException {
return getHeader("Message-ID", null);
}
public String getFileName() throws MessagingException {
return MimeBodyPart.getFileName(this);
}
public void setFileName(String filename) throws MessagingException {
MimeBodyPart.setFileName(this, filename);
}
private String getHeaderName(Message.RecipientType type) throws MessagingException {
String headerName;
if (type == Message.RecipientType.TO) {
headerName = "To";
} else if (type == Message.RecipientType.CC) {
headerName = "Cc";
} else if (type == Message.RecipientType.BCC) {
headerName = "Bcc";
} else if (type == RecipientType.NEWSGROUPS) {
headerName = "Newsgroups";
} else {
throw new MessagingException("Invalid Recipient Type");
}
return headerName;
}
public InputStream getInputStream() throws IOException, MessagingException {
return getDataHandler().getInputStream();
}
protected InputStream getContentStream() throws MessagingException {
if (this.contentStream != null)
return ((SharedInputStream)this.contentStream).newStream(0L, -1L);
if (this.content != null)
return new SharedByteArrayInputStream(this.content);
throw new MessagingException("No MimeMessage content");
}
public InputStream getRawInputStream() throws MessagingException {
return getContentStream();
}
public synchronized DataHandler getDataHandler() throws MessagingException {
if (this.dh == null)
this.dh = new MimeBodyPart.MimePartDataHandler(this);
return this.dh;
}
public Object getContent() throws IOException, MessagingException {
Object c;
if (this.cachedContent != null)
return this.cachedContent;
try {
c = getDataHandler().getContent();
} catch (FolderClosedIOException fex) {
throw new FolderClosedException(fex.getFolder(), fex.getMessage());
} catch (MessageRemovedIOException mex) {
throw new MessageRemovedException(mex.getMessage());
}
if (MimeBodyPart.cacheMultipart && (c instanceof Multipart || c instanceof Message) && (this.content != null || this.contentStream != null)) {
this.cachedContent = c;
if (c instanceof MimeMultipart)
((MimeMultipart)c).parse();
}
return c;
}
public synchronized void setDataHandler(DataHandler dh) throws MessagingException {
this.dh = dh;
this.cachedContent = null;
MimeBodyPart.invalidateContentHeaders(this);
}
public void setContent(Object o, String type) throws MessagingException {
if (o instanceof Multipart) {
setContent((Multipart)o);
} else {
setDataHandler(new DataHandler(o, type));
}
}
public void setText(String text) throws MessagingException {
setText(text, null);
}
public void setText(String text, String charset) throws MessagingException {
MimeBodyPart.setText(this, text, charset, "plain");
}
public void setText(String text, String charset, String subtype) throws MessagingException {
MimeBodyPart.setText(this, text, charset, subtype);
}
public void setContent(Multipart mp) throws MessagingException {
setDataHandler(new DataHandler(mp, mp.getContentType()));
mp.setParent(this);
}
public Message reply(boolean replyToAll) throws MessagingException {
return reply(replyToAll, true);
}
public Message reply(boolean replyToAll, boolean setAnswered) throws MessagingException {
MimeMessage reply = createMimeMessage(this.session);
String subject = getHeader("Subject", null);
if (subject != null) {
if (!subject.regionMatches(true, 0, "Re: ", 0, 4))
subject = "Re: " + subject;
reply.setHeader("Subject", subject);
}
Address[] a = getReplyTo();
reply.setRecipients(Message.RecipientType.TO, a);
if (replyToAll) {
Vector<InternetAddress> v = new Vector();
InternetAddress me = InternetAddress.getLocalAddress(this.session);
if (me != null)
v.addElement(me);
String alternates = null;
if (this.session != null)
alternates = this.session.getProperty("mail.alternates");
if (alternates != null)
eliminateDuplicates(v,
InternetAddress.parse(alternates, false));
String replyallccStr = null;
boolean replyallcc = false;
if (this.session != null)
replyallcc = PropUtil.getBooleanSessionProperty(this.session, "mail.replyallcc", false);
eliminateDuplicates(v, a);
a = getRecipients(Message.RecipientType.TO);
a = eliminateDuplicates(v, a);
if (a != null && a.length > 0)
if (replyallcc) {
reply.addRecipients(Message.RecipientType.CC, a);
} else {
reply.addRecipients(Message.RecipientType.TO, a);
}
a = getRecipients(Message.RecipientType.CC);
a = eliminateDuplicates(v, a);
if (a != null && a.length > 0)
reply.addRecipients(Message.RecipientType.CC, a);
a = getRecipients(RecipientType.NEWSGROUPS);
if (a != null && a.length > 0)
reply.setRecipients(RecipientType.NEWSGROUPS, a);
}
String msgId = getHeader("Message-Id", null);
if (msgId != null)
reply.setHeader("In-Reply-To", msgId);
String refs = getHeader("References", " ");
if (refs == null)
refs = getHeader("In-Reply-To", " ");
if (msgId != null)
if (refs != null) {
refs = MimeUtility.unfold(refs) + " " + msgId;
} else {
refs = msgId;
}
if (refs != null)
reply.setHeader("References", MimeUtility.fold(12, refs));
if (setAnswered)
try {
setFlags(answeredFlag, true);
} catch (MessagingException e) {}
return reply;
}
private static final Flags answeredFlag = new Flags(Flags.Flag.ANSWERED);
private Address[] eliminateDuplicates(Vector v, Address[] addrs) {
if (addrs == null)
return null;
int gone = 0;
for (int i = 0; i < addrs.length; i++) {
boolean found = false;
for (int j = 0; j < v.size(); j++) {
if (v.elementAt(j).equals(addrs[i])) {
found = true;
gone++;
addrs[i] = null;
break;
}
}
if (!found)
v.addElement(addrs[i]);
}
if (gone != 0) {
Address[] a;
if (addrs instanceof InternetAddress[]) {
a = new InternetAddress[addrs.length - gone];
} else {
a = new Address[addrs.length - gone];
}
for (int k = 0, j = 0; k < addrs.length; k++) {
if (addrs[k] != null)
a[j++] = addrs[k];
}
addrs = a;
}
return addrs;
}
public void writeTo(OutputStream os) throws IOException, MessagingException {
writeTo(os, null);
}
public void writeTo(OutputStream os, String[] ignoreList) throws IOException, MessagingException {
if (!this.saved)
saveChanges();
if (this.modified) {
MimeBodyPart.writeTo(this, os, ignoreList);
return;
}
Enumeration<String> hdrLines = getNonMatchingHeaderLines(ignoreList);
LineOutputStream los = new LineOutputStream(os);
while (hdrLines.hasMoreElements())
los.writeln(hdrLines.nextElement());
los.writeln();
if (this.content == null) {
InputStream is = null;
byte[] buf = new byte[8192];
try {
is = getContentStream();
int len;
while ((len = is.read(buf)) > 0)
os.write(buf, 0, len);
} finally {
if (is != null)
is.close();
buf = null;
}
} else {
os.write(this.content);
}
os.flush();
}
public String[] getHeader(String name) throws MessagingException {
return this.headers.getHeader(name);
}
public String getHeader(String name, String delimiter) throws MessagingException {
return this.headers.getHeader(name, delimiter);
}
public void setHeader(String name, String value) throws MessagingException {
this.headers.setHeader(name, value);
}
public void addHeader(String name, String value) throws MessagingException {
this.headers.addHeader(name, value);
}
public void removeHeader(String name) throws MessagingException {
this.headers.removeHeader(name);
}
public Enumeration getAllHeaders() throws MessagingException {
return this.headers.getAllHeaders();
}
public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
return this.headers.getMatchingHeaders(names);
}
public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
return this.headers.getNonMatchingHeaders(names);
}
public void addHeaderLine(String line) throws MessagingException {
this.headers.addHeaderLine(line);
}
public Enumeration getAllHeaderLines() throws MessagingException {
return this.headers.getAllHeaderLines();
}
public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
return this.headers.getMatchingHeaderLines(names);
}
public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
return this.headers.getNonMatchingHeaderLines(names);
}
public synchronized Flags getFlags() throws MessagingException {
return (Flags)this.flags.clone();
}
public synchronized boolean isSet(Flags.Flag flag) throws MessagingException {
return this.flags.contains(flag);
}
public synchronized void setFlags(Flags flag, boolean set) throws MessagingException {
if (set) {
this.flags.add(flag);
} else {
this.flags.remove(flag);
}
}
public void saveChanges() throws MessagingException {
this.modified = true;
this.saved = true;
updateHeaders();
}
protected void updateMessageID() throws MessagingException {
setHeader("Message-ID", "<" +
UniqueValue.getUniqueMessageIDValue(this.session) + ">");
}
protected synchronized void updateHeaders() throws MessagingException {
MimeBodyPart.updateHeaders(this);
setHeader("MIME-Version", "1.0");
updateMessageID();
if (this.cachedContent != null) {
this.dh = new DataHandler(this.cachedContent, getContentType());
this.cachedContent = null;
this.content = null;
if (this.contentStream != null)
try {
this.contentStream.close();
} catch (IOException e) {}
this.contentStream = null;
}
}
protected InternetHeaders createInternetHeaders(InputStream is) throws MessagingException {
return new InternetHeaders(is);
}
protected MimeMessage createMimeMessage(Session session) throws MessagingException {
return new MimeMessage(session);
}
}

View file

@ -0,0 +1,457 @@
package javax.mail.internet;
import com.sun.mail.util.ASCIIUtility;
import com.sun.mail.util.LineInputStream;
import com.sun.mail.util.LineOutputStream;
import com.sun.mail.util.PropUtil;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.activation.DataSource;
import javax.mail.BodyPart;
import javax.mail.MessageAware;
import javax.mail.MessageContext;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.MultipartDataSource;
public class MimeMultipart extends Multipart {
protected DataSource ds = null;
protected boolean parsed = true;
protected boolean complete = true;
protected String preamble = null;
protected boolean ignoreMissingEndBoundary = true;
protected boolean ignoreMissingBoundaryParameter = true;
protected boolean ignoreExistingBoundaryParameter = false;
protected boolean allowEmpty = false;
public MimeMultipart() {
this("mixed");
}
public MimeMultipart(String subtype) {
String boundary = UniqueValue.getUniqueBoundaryValue();
ContentType cType = new ContentType("multipart", subtype, null);
cType.setParameter("boundary", boundary);
this.contentType = cType.toString();
initializeProperties();
}
public MimeMultipart(BodyPart... parts) throws MessagingException {
this();
for (BodyPart bp : parts)
super.addBodyPart(bp);
}
public MimeMultipart(String subtype, BodyPart... parts) throws MessagingException {
this(subtype);
for (BodyPart bp : parts)
super.addBodyPart(bp);
}
public MimeMultipart(DataSource ds) throws MessagingException {
if (ds instanceof MessageAware) {
MessageContext mc = ((MessageAware)ds).getMessageContext();
setParent(mc.getPart());
}
if (ds instanceof MultipartDataSource) {
setMultipartDataSource((MultipartDataSource)ds);
return;
}
this.parsed = false;
this.ds = ds;
this.contentType = ds.getContentType();
}
protected void initializeProperties() {
this.ignoreMissingEndBoundary = PropUtil.getBooleanSystemProperty("mail.mime.multipart.ignoremissingendboundary", true);
this.ignoreMissingBoundaryParameter = PropUtil.getBooleanSystemProperty("mail.mime.multipart.ignoremissingboundaryparameter", true);
this.ignoreExistingBoundaryParameter = PropUtil.getBooleanSystemProperty("mail.mime.multipart.ignoreexistingboundaryparameter", false);
this.allowEmpty = PropUtil.getBooleanSystemProperty("mail.mime.multipart.allowempty", false);
}
public synchronized void setSubType(String subtype) throws MessagingException {
ContentType cType = new ContentType(this.contentType);
cType.setSubType(subtype);
this.contentType = cType.toString();
}
public synchronized int getCount() throws MessagingException {
parse();
return super.getCount();
}
public synchronized BodyPart getBodyPart(int index) throws MessagingException {
parse();
return super.getBodyPart(index);
}
public synchronized BodyPart getBodyPart(String CID) throws MessagingException {
parse();
int count = getCount();
for (int i = 0; i < count; i++) {
MimeBodyPart part = (MimeBodyPart)getBodyPart(i);
String s = part.getContentID();
if (s != null && s.equals(CID))
return part;
}
return null;
}
public boolean removeBodyPart(BodyPart part) throws MessagingException {
parse();
return super.removeBodyPart(part);
}
public void removeBodyPart(int index) throws MessagingException {
parse();
super.removeBodyPart(index);
}
public synchronized void addBodyPart(BodyPart part) throws MessagingException {
parse();
super.addBodyPart(part);
}
public synchronized void addBodyPart(BodyPart part, int index) throws MessagingException {
parse();
super.addBodyPart(part, index);
}
public synchronized boolean isComplete() throws MessagingException {
parse();
return this.complete;
}
public synchronized String getPreamble() throws MessagingException {
parse();
return this.preamble;
}
public synchronized void setPreamble(String preamble) throws MessagingException {
this.preamble = preamble;
}
protected synchronized void updateHeaders() throws MessagingException {
parse();
for (int i = 0; i < this.parts.size(); i++)
this.parts.elementAt(i).updateHeaders();
}
public synchronized void writeTo(OutputStream os) throws IOException, MessagingException {
parse();
String boundary = "--" + new ContentType(this.contentType)
.getParameter("boundary");
LineOutputStream los = new LineOutputStream(os);
if (this.preamble != null) {
byte[] pb = ASCIIUtility.getBytes(this.preamble);
los.write(pb);
if (pb.length > 0 && pb[pb.length - 1] != 13 && pb[pb.length - 1] != 10)
los.writeln();
}
if (this.parts.size() == 0) {
if (this.allowEmpty) {
los.writeln(boundary);
los.writeln();
} else {
throw new MessagingException("Empty multipart: " + this.contentType);
}
} else {
for (int i = 0; i < this.parts.size(); i++) {
los.writeln(boundary);
this.parts.elementAt(i).writeTo(os);
los.writeln();
}
}
los.writeln(boundary + "--");
}
protected synchronized void parse() throws MessagingException {
if (this.parsed)
return;
initializeProperties();
InputStream in = null;
SharedInputStream sin = null;
long start = 0L, end = 0L;
try {
in = this.ds.getInputStream();
if (!(in instanceof java.io.ByteArrayInputStream) && !(in instanceof BufferedInputStream) && !(in instanceof SharedInputStream))
in = new BufferedInputStream(in);
} catch (Exception ex) {
throw new MessagingException("No inputstream from datasource", ex);
}
if (in instanceof SharedInputStream)
sin = (SharedInputStream)in;
ContentType cType = new ContentType(this.contentType);
String boundary = null;
if (!this.ignoreExistingBoundaryParameter) {
String bp = cType.getParameter("boundary");
if (bp != null)
boundary = "--" + bp;
}
if (boundary == null && !this.ignoreMissingBoundaryParameter && !this.ignoreExistingBoundaryParameter)
throw new MessagingException("Missing boundary parameter");
try {
LineInputStream lin = new LineInputStream(in);
StringBuffer preamblesb = null;
String lineSeparator = null;
String line;
while ((line = lin.readLine()) != null) {
int k;
for (k = line.length() - 1; k >= 0; k--) {
char c = line.charAt(k);
if (c != ' ' && c != '\t')
break;
}
line = line.substring(0, k + 1);
if (boundary != null) {
if (line.equals(boundary))
break;
if (line.length() == boundary.length() + 2 &&
line.startsWith(boundary) && line.endsWith("--")) {
line = null;
break;
}
} else if (line.length() > 2 && line.startsWith("--") && (
line.length() <= 4 || !allDashes(line))) {
boundary = line;
break;
}
if (line.length() > 0) {
if (lineSeparator == null)
try {
lineSeparator = System.getProperty("line.separator", "\n");
} catch (SecurityException ex) {
lineSeparator = "\n";
}
if (preamblesb == null)
preamblesb = new StringBuffer(line.length() + 2);
preamblesb.append(line).append(lineSeparator);
}
}
if (preamblesb != null)
this.preamble = preamblesb.toString();
if (line == null) {
if (this.allowEmpty)
return;
throw new MessagingException("Missing start boundary");
}
byte[] bndbytes = ASCIIUtility.getBytes(boundary);
int bl = bndbytes.length;
int[] bcs = new int[256];
for (int i = 0; i < bl; i++)
bcs[bndbytes[i] & 0xFF] = i + 1;
int[] gss = new int[bl];
for (int j = bl; j > 0; j--) {
int k = bl - 1;
while (true) {
if (k >= j) {
if (bndbytes[k] == bndbytes[k - j]) {
gss[k - 1] = j;
} else {
break;
}
k--;
continue;
}
while (k > 0)
gss[--k] = j;
break;
}
}
gss[bl - 1] = 1;
boolean done = false;
while (!done) {
int eolLen;
MimeBodyPart part;
InternetHeaders headers = null;
if (sin != null) {
start = sin.getPosition();
while ((line = lin.readLine()) != null && line.length() > 0);
if (line == null) {
if (!this.ignoreMissingEndBoundary)
throw new MessagingException("missing multipart end boundary");
this.complete = false;
break;
}
} else {
headers = createInternetHeaders(in);
}
if (!in.markSupported())
throw new MessagingException("Stream doesn't support mark");
ByteArrayOutputStream buf = null;
if (sin == null) {
buf = new ByteArrayOutputStream();
} else {
end = sin.getPosition();
}
byte[] inbuf = new byte[bl];
byte[] previnbuf = new byte[bl];
int inSize = 0;
int prevSize = 0;
boolean first = true;
while (true) {
in.mark(bl + 4 + 1000);
eolLen = 0;
inSize = readFully(in, inbuf, 0, bl);
if (inSize < bl) {
if (!this.ignoreMissingEndBoundary)
throw new MessagingException("missing multipart end boundary");
if (sin != null)
end = sin.getPosition();
this.complete = false;
done = true;
break;
}
int k;
for (k = bl - 1; k >= 0 &&
inbuf[k] == bndbytes[k]; k--);
if (k < 0) {
eolLen = 0;
if (!first) {
int b = previnbuf[prevSize - 1];
if (b == 13 || b == 10) {
eolLen = 1;
if (b == 10 && prevSize >= 2) {
b = previnbuf[prevSize - 2];
if (b == 13)
eolLen = 2;
}
}
}
if (first || eolLen > 0) {
if (sin != null)
end = sin.getPosition() - (long)bl - (long)eolLen;
int b2 = in.read();
if (b2 == 45 &&
in.read() == 45) {
this.complete = true;
done = true;
break;
}
while (b2 == 32 || b2 == 9)
b2 = in.read();
if (b2 == 10)
break;
if (b2 == 13) {
in.mark(1);
if (in.read() != 10) {
in.reset();
break;
}
break;
}
}
k = 0;
}
int skip = Math.max(k + 1 - bcs[inbuf[k] & Byte.MAX_VALUE], gss[k]);
if (skip < 2) {
if (sin == null && prevSize > 1)
buf.write(previnbuf, 0, prevSize - 1);
in.reset();
skipFully(in, 1L);
if (prevSize >= 1) {
previnbuf[0] = previnbuf[prevSize - 1];
previnbuf[1] = inbuf[0];
prevSize = 2;
} else {
previnbuf[0] = inbuf[0];
prevSize = 1;
}
} else {
if (prevSize > 0 && sin == null)
buf.write(previnbuf, 0, prevSize);
prevSize = skip;
in.reset();
skipFully(in, (long)prevSize);
byte[] tmp = inbuf;
inbuf = previnbuf;
previnbuf = tmp;
}
first = false;
}
if (sin != null) {
part = createMimeBodyPartIs(sin.newStream(start, end));
} else {
if (prevSize - eolLen > 0)
buf.write(previnbuf, 0, prevSize - eolLen);
if (!this.complete && inSize > 0)
buf.write(inbuf, 0, inSize);
part = createMimeBodyPart(headers, buf.toByteArray());
}
super.addBodyPart(part);
}
} catch (IOException ioex) {
throw new MessagingException("IO Error", ioex);
} finally {
try {
in.close();
} catch (IOException e) {}
}
this.parsed = true;
}
private static boolean allDashes(String s) {
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != '-')
return false;
}
return true;
}
private static int readFully(InputStream in, byte[] buf, int off, int len) throws IOException {
if (len == 0)
return 0;
int total = 0;
while (len > 0) {
int bsize = in.read(buf, off, len);
if (bsize <= 0)
break;
off += bsize;
total += bsize;
len -= bsize;
}
return (total > 0) ? total : -1;
}
private void skipFully(InputStream in, long offset) throws IOException {
while (offset > 0L) {
long cur = in.skip(offset);
if (cur <= 0L)
throw new EOFException("can't skip");
offset -= cur;
}
}
protected InternetHeaders createInternetHeaders(InputStream is) throws MessagingException {
return new InternetHeaders(is);
}
protected MimeBodyPart createMimeBodyPart(InternetHeaders headers, byte[] content) throws MessagingException {
return new MimeBodyPart(headers, content);
}
protected MimeBodyPart createMimeBodyPart(InputStream is) throws MessagingException {
return new MimeBodyPart(is);
}
private MimeBodyPart createMimeBodyPartIs(InputStream is) throws MessagingException {
try {
return createMimeBodyPart(is);
} finally {
try {
is.close();
} catch (IOException e) {}
}
}
}

View file

@ -0,0 +1,35 @@
package javax.mail.internet;
import java.util.Enumeration;
import javax.mail.MessagingException;
import javax.mail.Part;
public interface MimePart extends Part {
String getHeader(String paramString1, String paramString2) throws MessagingException;
void addHeaderLine(String paramString) throws MessagingException;
Enumeration getAllHeaderLines() throws MessagingException;
Enumeration getMatchingHeaderLines(String[] paramArrayOfString) throws MessagingException;
Enumeration getNonMatchingHeaderLines(String[] paramArrayOfString) throws MessagingException;
String getEncoding() throws MessagingException;
String getContentID() throws MessagingException;
String getContentMD5() throws MessagingException;
void setContentMD5(String paramString) throws MessagingException;
String[] getContentLanguage() throws MessagingException;
void setContentLanguage(String[] paramArrayOfString) throws MessagingException;
void setText(String paramString) throws MessagingException;
void setText(String paramString1, String paramString2) throws MessagingException;
void setText(String paramString1, String paramString2, String paramString3) throws MessagingException;
}

View file

@ -0,0 +1,70 @@
package javax.mail.internet;
import com.sun.mail.util.FolderClosedIOException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.UnknownServiceException;
import javax.activation.DataSource;
import javax.mail.FolderClosedException;
import javax.mail.MessageAware;
import javax.mail.MessageContext;
import javax.mail.MessagingException;
public class MimePartDataSource implements DataSource, MessageAware {
protected MimePart part;
private MessageContext context;
public MimePartDataSource(MimePart part) {
this.part = part;
}
public InputStream getInputStream() throws IOException {
try {
InputStream is;
if (this.part instanceof MimeBodyPart) {
is = ((MimeBodyPart)this.part).getContentStream();
} else if (this.part instanceof MimeMessage) {
is = ((MimeMessage)this.part).getContentStream();
} else {
throw new MessagingException("Unknown part");
}
String encoding = MimeBodyPart.restrictEncoding(this.part, this.part.getEncoding());
if (encoding != null)
return MimeUtility.decode(is, encoding);
return is;
} catch (FolderClosedException fex) {
throw new FolderClosedIOException(fex.getFolder(),
fex.getMessage());
} catch (MessagingException mex) {
throw new IOException(mex.getMessage());
}
}
public OutputStream getOutputStream() throws IOException {
throw new UnknownServiceException("Writing not supported");
}
public String getContentType() {
try {
return this.part.getContentType();
} catch (MessagingException mex) {
return "application/octet-stream";
}
}
public String getName() {
try {
if (this.part instanceof MimeBodyPart)
return ((MimeBodyPart)this.part).getFileName();
} catch (MessagingException e) {}
return "";
}
public synchronized MessageContext getMessageContext() {
if (this.context == null)
this.context = new MessageContext(this.part);
return this.context;
}
}

View file

@ -0,0 +1,820 @@
package javax.mail.internet;
import com.sun.mail.util.ASCIIUtility;
import com.sun.mail.util.BASE64DecoderStream;
import com.sun.mail.util.BASE64EncoderStream;
import com.sun.mail.util.BEncoderStream;
import com.sun.mail.util.LineInputStream;
import com.sun.mail.util.PropUtil;
import com.sun.mail.util.QDecoderStream;
import com.sun.mail.util.QEncoderStream;
import com.sun.mail.util.QPDecoderStream;
import com.sun.mail.util.QPEncoderStream;
import com.sun.mail.util.UUDecoderStream;
import com.sun.mail.util.UUEncoderStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.EncodingAware;
import javax.mail.MessagingException;
public class MimeUtility {
private static final Map nonAsciiCharsetMap = new HashMap();
private static final boolean decodeStrict = PropUtil.getBooleanSystemProperty("mail.mime.decodetext.strict", true);
private static final boolean encodeEolStrict = PropUtil.getBooleanSystemProperty("mail.mime.encodeeol.strict", false);
private static final boolean ignoreUnknownEncoding = PropUtil.getBooleanSystemProperty("mail.mime.ignoreunknownencoding", false);
private static final boolean foldEncodedWords = PropUtil.getBooleanSystemProperty("mail.mime.foldencodedwords", false);
private static final boolean foldText = PropUtil.getBooleanSystemProperty("mail.mime.foldtext", true);
public static String getEncoding(DataSource ds) {
ContentType cType = null;
InputStream is = null;
String encoding = null;
if (ds instanceof EncodingAware) {
encoding = ((EncodingAware)ds).getEncoding();
if (encoding != null)
return encoding;
}
try {
cType = new ContentType(ds.getContentType());
is = ds.getInputStream();
boolean isText = cType.match("text/*");
int i = checkAscii(is, -1, !isText);
switch (i) {
case 1:
encoding = "7bit";
break;
case 2:
if (isText && nonAsciiCharset(cType)) {
encoding = "base64";
} else {
encoding = "quoted-printable";
}
break;
default:
encoding = "base64";
break;
}
} catch (Exception ex) {
return "base64";
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {}
}
return encoding;
}
private static boolean nonAsciiCharset(ContentType ct) {
Boolean bool;
String charset = ct.getParameter("charset");
if (charset == null)
return false;
charset = charset.toLowerCase(Locale.ENGLISH);
synchronized (nonAsciiCharsetMap) {
bool = (Boolean)nonAsciiCharsetMap.get(charset);
}
if (bool == null) {
try {
byte[] b = "\r\n".getBytes(charset);
bool = (b.length != 2 || b[0] != 13 || b[1] != 10);
} catch (UnsupportedEncodingException uex) {
bool = Boolean.FALSE;
} catch (RuntimeException ex) {
bool = Boolean.TRUE;
}
synchronized (nonAsciiCharsetMap) {
nonAsciiCharsetMap.put(charset, bool);
}
}
return bool;
}
public static String getEncoding(DataHandler dh) {
ContentType cType = null;
String encoding = null;
if (dh.getName() != null)
return getEncoding(dh.getDataSource());
try {
cType = new ContentType(dh.getContentType());
} catch (Exception ex) {
return "base64";
}
if (cType.match("text/*")) {
AsciiOutputStream aos = new AsciiOutputStream(false, false);
try {
dh.writeTo(aos);
} catch (IOException e) {}
switch (aos.getAscii()) {
case 1:
encoding = "7bit";
break;
case 2:
encoding = "quoted-printable";
break;
default:
encoding = "base64";
break;
}
} else {
AsciiOutputStream aos = new AsciiOutputStream(true, encodeEolStrict);
try {
dh.writeTo(aos);
} catch (IOException e) {}
if (aos.getAscii() == 1) {
encoding = "7bit";
} else {
encoding = "base64";
}
}
return encoding;
}
public static InputStream decode(InputStream is, String encoding) throws MessagingException {
if (encoding.equalsIgnoreCase("base64"))
return new BASE64DecoderStream(is);
if (encoding.equalsIgnoreCase("quoted-printable"))
return new QPDecoderStream(is);
if (encoding.equalsIgnoreCase("uuencode") ||
encoding.equalsIgnoreCase("x-uuencode") ||
encoding.equalsIgnoreCase("x-uue"))
return new UUDecoderStream(is);
if (encoding.equalsIgnoreCase("binary") ||
encoding.equalsIgnoreCase("7bit") ||
encoding.equalsIgnoreCase("8bit"))
return is;
if (!ignoreUnknownEncoding)
throw new MessagingException("Unknown encoding: " + encoding);
return is;
}
public static OutputStream encode(OutputStream os, String encoding) throws MessagingException {
if (encoding == null)
return os;
if (encoding.equalsIgnoreCase("base64"))
return new BASE64EncoderStream(os);
if (encoding.equalsIgnoreCase("quoted-printable"))
return new QPEncoderStream(os);
if (encoding.equalsIgnoreCase("uuencode") ||
encoding.equalsIgnoreCase("x-uuencode") ||
encoding.equalsIgnoreCase("x-uue"))
return new UUEncoderStream(os);
if (encoding.equalsIgnoreCase("binary") ||
encoding.equalsIgnoreCase("7bit") ||
encoding.equalsIgnoreCase("8bit"))
return os;
throw new MessagingException("Unknown encoding: " + encoding);
}
public static OutputStream encode(OutputStream os, String encoding, String filename) throws MessagingException {
if (encoding == null)
return os;
if (encoding.equalsIgnoreCase("base64"))
return new BASE64EncoderStream(os);
if (encoding.equalsIgnoreCase("quoted-printable"))
return new QPEncoderStream(os);
if (encoding.equalsIgnoreCase("uuencode") ||
encoding.equalsIgnoreCase("x-uuencode") ||
encoding.equalsIgnoreCase("x-uue"))
return new UUEncoderStream(os, filename);
if (encoding.equalsIgnoreCase("binary") ||
encoding.equalsIgnoreCase("7bit") ||
encoding.equalsIgnoreCase("8bit"))
return os;
throw new MessagingException("Unknown encoding: " + encoding);
}
public static String encodeText(String text) throws UnsupportedEncodingException {
return encodeText(text, null, null);
}
public static String encodeText(String text, String charset, String encoding) throws UnsupportedEncodingException {
return encodeWord(text, charset, encoding, false);
}
public static String decodeText(String etext) throws UnsupportedEncodingException {
String lwsp = " \t\n\r";
if (etext.indexOf("=?") == -1)
return etext;
StringTokenizer st = new StringTokenizer(etext, lwsp, true);
StringBuffer sb = new StringBuffer();
StringBuffer wsb = new StringBuffer();
boolean prevWasEncoded = false;
while (st.hasMoreTokens()) {
String word;
String s = st.nextToken();
char c;
if ((c = s.charAt(0)) == ' ' || c == '\t' || c == '\r' || c == '\n') {
wsb.append(c);
continue;
}
try {
word = decodeWord(s);
if (!prevWasEncoded && wsb.length() > 0)
sb.append(wsb);
prevWasEncoded = true;
} catch (ParseException pex) {
word = s;
if (!decodeStrict) {
String dword = decodeInnerWords(word);
if (dword != word) {
if (!prevWasEncoded || !word.startsWith("=?"))
if (wsb.length() > 0)
sb.append(wsb);
prevWasEncoded = word.endsWith("?=");
word = dword;
} else {
if (wsb.length() > 0)
sb.append(wsb);
prevWasEncoded = false;
}
} else {
if (wsb.length() > 0)
sb.append(wsb);
prevWasEncoded = false;
}
}
sb.append(word);
wsb.setLength(0);
}
sb.append(wsb);
return sb.toString();
}
public static String encodeWord(String word) throws UnsupportedEncodingException {
return encodeWord(word, null, null);
}
public static String encodeWord(String word, String charset, String encoding) throws UnsupportedEncodingException {
return encodeWord(word, charset, encoding, true);
}
private static String encodeWord(String string, String charset, String encoding, boolean encodingWord) throws UnsupportedEncodingException {
String jcharset;
boolean b64;
int ascii = checkAscii(string);
if (ascii == 1)
return string;
if (charset == null) {
jcharset = getDefaultJavaCharset();
charset = getDefaultMIMECharset();
} else {
jcharset = javaCharset(charset);
}
if (encoding == null)
if (ascii != 3) {
encoding = "Q";
} else {
encoding = "B";
}
if (encoding.equalsIgnoreCase("B")) {
b64 = true;
} else if (encoding.equalsIgnoreCase("Q")) {
b64 = false;
} else {
throw new UnsupportedEncodingException("Unknown transfer encoding: " + encoding);
}
StringBuffer outb = new StringBuffer();
doEncode(string, b64, jcharset, 68 -
charset.length(), "=?" + charset + "?" + encoding + "?", true, encodingWord, outb);
return outb.toString();
}
private static void doEncode(String string, boolean b64, String jcharset, int avail, String prefix, boolean first, boolean encodingWord, StringBuffer buf) throws UnsupportedEncodingException {
int len;
byte[] bytes = string.getBytes(jcharset);
if (b64) {
len = BEncoderStream.encodedLength(bytes);
} else {
len = QEncoderStream.encodedLength(bytes, encodingWord);
}
int size;
if (len > avail && (size = string.length()) > 1) {
int split = size / 2;
if (Character.isHighSurrogate(string.charAt(split - 1)))
split--;
if (split > 0)
doEncode(string.substring(0, split), b64, jcharset, avail, prefix, first, encodingWord, buf);
doEncode(string.substring(split, size), b64, jcharset, avail, prefix, false, encodingWord, buf);
} else {
OutputStream eos;
ByteArrayOutputStream os = new ByteArrayOutputStream();
if (b64) {
eos = new BEncoderStream(os);
} else {
eos = new QEncoderStream(os, encodingWord);
}
try {
eos.write(bytes);
eos.close();
} catch (IOException e) {}
byte[] encodedBytes = os.toByteArray();
if (!first)
if (foldEncodedWords) {
buf.append("\r\n ");
} else {
buf.append(" ");
}
buf.append(prefix);
for (int i = 0; i < encodedBytes.length; i++)
buf.append((char)encodedBytes[i]);
buf.append("?=");
}
}
public static String decodeWord(String eword) throws ParseException, UnsupportedEncodingException {
if (!eword.startsWith("=?"))
throw new ParseException("encoded word does not start with \"=?\": " + eword);
int start = 2;
int pos;
if ((pos = eword.indexOf('?', start)) == -1)
throw new ParseException("encoded word does not include charset: " + eword);
String charset = eword.substring(start, pos);
int lpos = charset.indexOf('*');
if (lpos >= 0)
charset = charset.substring(0, lpos);
charset = javaCharset(charset);
start = pos + 1;
if ((pos = eword.indexOf('?', start)) == -1)
throw new ParseException("encoded word does not include encoding: " + eword);
String encoding = eword.substring(start, pos);
start = pos + 1;
if ((pos = eword.indexOf("?=", start)) == -1)
throw new ParseException("encoded word does not end with \"?=\": " + eword);
String word = eword.substring(start, pos);
try {
String decodedWord;
if (word.length() > 0) {
InputStream is;
ByteArrayInputStream bis = new ByteArrayInputStream(
ASCIIUtility.getBytes(word));
if (encoding.equalsIgnoreCase("B")) {
is = new BASE64DecoderStream(bis);
} else if (encoding.equalsIgnoreCase("Q")) {
is = new QDecoderStream(bis);
} else {
throw new UnsupportedEncodingException("unknown encoding: " + encoding);
}
int count = bis.available();
byte[] bytes = new byte[count];
count = is.read(bytes, 0, count);
decodedWord = (count <= 0) ? "" : new String(bytes, 0, count, charset);
} else {
decodedWord = "";
}
if (pos + 2 < eword.length()) {
String rest = eword.substring(pos + 2);
if (!decodeStrict)
rest = decodeInnerWords(rest);
decodedWord = decodedWord + rest;
}
return decodedWord;
} catch (UnsupportedEncodingException uex) {
throw uex;
} catch (IOException ioex) {
throw new ParseException(ioex.toString());
} catch (IllegalArgumentException iex) {
throw new UnsupportedEncodingException(charset);
}
}
private static String decodeInnerWords(String word) throws UnsupportedEncodingException {
int start = 0;
StringBuffer buf = new StringBuffer();
int i;
while ((i = word.indexOf("=?", start)) >= 0) {
buf.append(word.substring(start, i));
int end = word.indexOf('?', i + 2);
if (end < 0)
break;
end = word.indexOf('?', end + 1);
if (end < 0)
break;
end = word.indexOf("?=", end + 1);
if (end < 0)
break;
String s = word.substring(i, end + 2);
try {
s = decodeWord(s);
} catch (ParseException e) {}
buf.append(s);
start = end + 2;
}
if (start == 0)
return word;
if (start < word.length())
buf.append(word.substring(start));
return buf.toString();
}
public static String quote(String word, String specials) {
int len = (word == null) ? 0 : word.length();
if (len == 0)
return "\"\"";
boolean needQuoting = false;
for (int i = 0; i < len; i++) {
char c = word.charAt(i);
if (c == '"' || c == '\\' || c == '\r' || c == '\n') {
StringBuffer sb = new StringBuffer(len + 3);
sb.append('"');
sb.append(word.substring(0, i));
int lastc = 0;
for (int j = i; j < len; j++) {
char cc = word.charAt(j);
if (cc == '"' || cc == '\\' || cc == '\r' || cc == '\n')
if (cc != '\n' || lastc != 13)
sb.append('\\');
sb.append(cc);
lastc = cc;
}
sb.append('"');
return sb.toString();
}
if (c < ' ' || c >= '\u007F' || specials.indexOf(c) >= 0)
needQuoting = true;
}
if (needQuoting) {
StringBuffer sb = new StringBuffer(len + 2);
sb.append('"').append(word).append('"');
return sb.toString();
}
return word;
}
public static String fold(int used, String s) {
if (!foldText)
return s;
int end;
for (end = s.length() - 1; end >= 0; end--) {
char c = s.charAt(end);
if (c != ' ' && c != '\t' && c != '\r' && c != '\n')
break;
}
if (end != s.length() - 1)
s = s.substring(0, end + 1);
if (used + s.length() <= 76)
return s;
StringBuffer sb = new StringBuffer(s.length() + 4);
char lastc = '\000';
while (used + s.length() > 76) {
int lastspace = -1;
for (int i = 0; i < s.length() && (
lastspace == -1 || used + i <= 76); i++) {
char c = s.charAt(i);
if ((c == ' ' || c == '\t') &&
lastc != ' ' && lastc != '\t')
lastspace = i;
lastc = c;
}
if (lastspace == -1) {
sb.append(s);
s = "";
used = 0;
break;
}
sb.append(s.substring(0, lastspace));
sb.append("\r\n");
lastc = s.charAt(lastspace);
sb.append(lastc);
s = s.substring(lastspace + 1);
used = 1;
}
sb.append(s);
return sb.toString();
}
public static String unfold(String s) {
if (!foldText)
return s;
StringBuffer sb = null;
int i;
while ((i = indexOfAny(s, "\r\n")) >= 0) {
int start = i;
int l = s.length();
i++;
if (i < l && s.charAt(i - 1) == '\r' && s.charAt(i) == '\n')
i++;
if (start == 0 || s.charAt(start - 1) != '\\') {
char c;
if (i < l && ((c = s.charAt(i)) == ' ' || c == '\t')) {
i++;
while (i < l && ((c = s.charAt(i)) == ' ' || c == '\t'))
i++;
if (sb == null)
sb = new StringBuffer(s.length());
if (start != 0) {
sb.append(s.substring(0, start));
sb.append(' ');
}
s = s.substring(i);
continue;
}
if (sb == null)
sb = new StringBuffer(s.length());
sb.append(s.substring(0, i));
s = s.substring(i);
continue;
}
if (sb == null)
sb = new StringBuffer(s.length());
sb.append(s.substring(0, start - 1));
sb.append(s.substring(start, i));
s = s.substring(i);
}
if (sb != null) {
sb.append(s);
return sb.toString();
}
return s;
}
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;
}
}
public static String javaCharset(String charset) {
if (mime2java == null || charset == null)
return charset;
String alias = (String)
mime2java.get(charset.toLowerCase(Locale.ENGLISH));
return (alias == null) ? charset : alias;
}
public static String mimeCharset(String charset) {
if (java2mime == null || charset == null)
return charset;
String alias = (String)
java2mime.get(charset.toLowerCase(Locale.ENGLISH));
return (alias == null) ? charset : alias;
}
public static String getDefaultJavaCharset() {
if (defaultJavaCharset == null) {
String mimecs = null;
try {
mimecs = System.getProperty("mail.mime.charset");
} catch (SecurityException e) {}
if (mimecs != null && mimecs.length() > 0) {
defaultJavaCharset = javaCharset(mimecs);
return defaultJavaCharset;
}
try {
defaultJavaCharset = System.getProperty("file.encoding", "8859_1");
} catch (SecurityException sex) {
InputStreamReader reader = new InputStreamReader(new NullInputStream());
defaultJavaCharset = reader.getEncoding();
if (defaultJavaCharset == null)
defaultJavaCharset = "8859_1";
}
}
class NullInputStream extends InputStream {
public int read() {
return 0;
}
};
return defaultJavaCharset;
}
static String getDefaultMIMECharset() {
if (defaultMIMECharset == null)
try {
defaultMIMECharset = System.getProperty("mail.mime.charset");
} catch (SecurityException e) {}
if (defaultMIMECharset == null)
defaultMIMECharset = mimeCharset(getDefaultJavaCharset());
return defaultMIMECharset;
}
private static Hashtable java2mime = new Hashtable(40);
private static Hashtable mime2java = new Hashtable(10);
public static final int ALL = -1;
private static String defaultJavaCharset;
private static String defaultMIMECharset;
static final int ALL_ASCII = 1;
static final int MOSTLY_ASCII = 2;
static final int MOSTLY_NONASCII = 3;
static {
try {
InputStream is = MimeUtility.class
.getResourceAsStream("/META-INF/javamail.charset.map");
if (is != null)
try {
is = new LineInputStream(is);
loadMappings((LineInputStream)is, java2mime);
loadMappings((LineInputStream)is, mime2java);
} finally {
try {
is.close();
} catch (Exception e) {}
}
} catch (Exception e) {}
if (java2mime.isEmpty()) {
java2mime.put("8859_1", "ISO-8859-1");
java2mime.put("iso8859_1", "ISO-8859-1");
java2mime.put("iso8859-1", "ISO-8859-1");
java2mime.put("8859_2", "ISO-8859-2");
java2mime.put("iso8859_2", "ISO-8859-2");
java2mime.put("iso8859-2", "ISO-8859-2");
java2mime.put("8859_3", "ISO-8859-3");
java2mime.put("iso8859_3", "ISO-8859-3");
java2mime.put("iso8859-3", "ISO-8859-3");
java2mime.put("8859_4", "ISO-8859-4");
java2mime.put("iso8859_4", "ISO-8859-4");
java2mime.put("iso8859-4", "ISO-8859-4");
java2mime.put("8859_5", "ISO-8859-5");
java2mime.put("iso8859_5", "ISO-8859-5");
java2mime.put("iso8859-5", "ISO-8859-5");
java2mime.put("8859_6", "ISO-8859-6");
java2mime.put("iso8859_6", "ISO-8859-6");
java2mime.put("iso8859-6", "ISO-8859-6");
java2mime.put("8859_7", "ISO-8859-7");
java2mime.put("iso8859_7", "ISO-8859-7");
java2mime.put("iso8859-7", "ISO-8859-7");
java2mime.put("8859_8", "ISO-8859-8");
java2mime.put("iso8859_8", "ISO-8859-8");
java2mime.put("iso8859-8", "ISO-8859-8");
java2mime.put("8859_9", "ISO-8859-9");
java2mime.put("iso8859_9", "ISO-8859-9");
java2mime.put("iso8859-9", "ISO-8859-9");
java2mime.put("sjis", "Shift_JIS");
java2mime.put("jis", "ISO-2022-JP");
java2mime.put("iso2022jp", "ISO-2022-JP");
java2mime.put("euc_jp", "euc-jp");
java2mime.put("koi8_r", "koi8-r");
java2mime.put("euc_cn", "euc-cn");
java2mime.put("euc_tw", "euc-tw");
java2mime.put("euc_kr", "euc-kr");
}
if (mime2java.isEmpty()) {
mime2java.put("iso-2022-cn", "ISO2022CN");
mime2java.put("iso-2022-kr", "ISO2022KR");
mime2java.put("utf-8", "UTF8");
mime2java.put("utf8", "UTF8");
mime2java.put("ja_jp.iso2022-7", "ISO2022JP");
mime2java.put("ja_jp.eucjp", "EUCJIS");
mime2java.put("euc-kr", "KSC5601");
mime2java.put("euckr", "KSC5601");
mime2java.put("us-ascii", "ISO-8859-1");
mime2java.put("x-us-ascii", "ISO-8859-1");
}
}
private static void loadMappings(LineInputStream is, Hashtable table) {
while (true) {
String currLine;
try {
currLine = is.readLine();
} catch (IOException ioex) {
break;
}
if (currLine == null)
break;
if (currLine.startsWith("--") && currLine.endsWith("--"))
break;
if (currLine.trim().length() == 0 || currLine.startsWith("#"))
continue;
StringTokenizer tk = new StringTokenizer(currLine, " \t");
try {
String key = tk.nextToken();
String value = tk.nextToken();
table.put(key.toLowerCase(Locale.ENGLISH), value);
} catch (NoSuchElementException e) {}
}
}
static int checkAscii(String s) {
int ascii = 0, non_ascii = 0;
int l = s.length();
for (int i = 0; i < l; i++) {
if (nonascii(s.charAt(i))) {
non_ascii++;
} else {
ascii++;
}
}
if (non_ascii == 0)
return 1;
if (ascii > non_ascii)
return 2;
return 3;
}
static int checkAscii(byte[] b) {
int ascii = 0, non_ascii = 0;
for (int i = 0; i < b.length; i++) {
if (nonascii(b[i] & 0xFF)) {
non_ascii++;
} else {
ascii++;
}
}
if (non_ascii == 0)
return 1;
if (ascii > non_ascii)
return 2;
return 3;
}
static int checkAscii(InputStream is, int max, boolean breakOnNonAscii) {
int ascii = 0, non_ascii = 0;
int block = 4096;
int linelen = 0;
boolean longLine = false, badEOL = false;
boolean checkEOL = (encodeEolStrict && breakOnNonAscii);
byte[] buf = null;
if (max != 0) {
block = (max == -1) ? 4096 : Math.min(max, 4096);
buf = new byte[block];
}
while (max != 0) {
int len;
try {
if ((len = is.read(buf, 0, block)) == -1)
break;
int lastb = 0;
for (int i = 0; i < len; i++) {
int b = buf[i] & 0xFF;
if (checkEOL && ((lastb == 13 && b != 10) || (lastb != 13 && b == 10)))
badEOL = true;
if (b == 13 || b == 10) {
linelen = 0;
} else {
linelen++;
if (linelen > 998)
longLine = true;
}
if (nonascii(b)) {
if (breakOnNonAscii)
return 3;
non_ascii++;
} else {
ascii++;
}
lastb = b;
}
} catch (IOException ioex) {
break;
}
if (max != -1)
max -= len;
}
if (max == 0 && breakOnNonAscii)
return 3;
if (non_ascii == 0) {
if (badEOL)
return 3;
if (longLine)
return 2;
return 1;
}
if (ascii > non_ascii)
return 2;
return 3;
}
static final boolean nonascii(int b) {
return (b >= 127 || (b < 32 && b != 13 && b != 10 && b != 9));
}
}

View file

@ -0,0 +1,92 @@
package javax.mail.internet;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.mail.Address;
public class NewsAddress extends Address {
protected String newsgroup;
protected String host;
private static final long serialVersionUID = -4203797299824684143L;
public NewsAddress() {}
public NewsAddress(String newsgroup) {
this(newsgroup, null);
}
public NewsAddress(String newsgroup, String host) {
this.newsgroup = newsgroup;
this.host = host;
}
public String getType() {
return "news";
}
public void setNewsgroup(String newsgroup) {
this.newsgroup = newsgroup;
}
public String getNewsgroup() {
return this.newsgroup;
}
public void setHost(String host) {
this.host = host;
}
public String getHost() {
return this.host;
}
public String toString() {
return this.newsgroup;
}
public boolean equals(Object a) {
if (!(a instanceof NewsAddress))
return false;
NewsAddress s = (NewsAddress)a;
return (((this.newsgroup == null && s.newsgroup == null) || (this.newsgroup != null &&
this.newsgroup.equals(s.newsgroup))) && ((this.host == null && s.host == null) || (this.host != null && s.host != null &&
this.host.equalsIgnoreCase(s.host))));
}
public int hashCode() {
int hash = 0;
if (this.newsgroup != null)
hash += this.newsgroup.hashCode();
if (this.host != null)
hash += this.host.toLowerCase(Locale.ENGLISH).hashCode();
return hash;
}
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();
}
public static NewsAddress[] parse(String newsgroups) throws AddressException {
StringTokenizer st = new StringTokenizer(newsgroups, ",");
Vector<NewsAddress> 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;
}
}

View file

@ -0,0 +1,517 @@
package javax.mail.internet;
import com.sun.mail.util.ASCIIUtility;
import com.sun.mail.util.PropUtil;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
public class ParameterList {
private Map list = new LinkedHashMap();
private Set multisegmentNames;
private Map slist;
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);
private static final boolean splitLongParameters = PropUtil.getBooleanSystemProperty("mail.mime.splitlongparameters", true);
private static class Value {
String value;
String charset;
String encodedValue;
private Value() {}
}
private static class MultiValue extends ArrayList {
private static final long serialVersionUID = 699561094618751023L;
String value;
private MultiValue() {}
}
private static class ParamEnum implements Enumeration {
private Iterator it;
ParamEnum(Iterator it) {
this.it = it;
}
public boolean hasMoreElements() {
return this.it.hasNext();
}
public Object nextElement() {
return this.it.next();
}
}
public ParameterList() {
if (decodeParameters) {
this.multisegmentNames = new HashSet();
this.slist = new HashMap();
}
}
public ParameterList(String s) throws ParseException {
this();
HeaderTokenizer h = new HeaderTokenizer(s, "()<>@,;:\\\"\t []/?=");
while (true) {
HeaderTokenizer.Token tk = h.next();
int type = tk.getType();
if (type == -4)
break;
if ((char)type == ';') {
tk = h.next();
if (tk.getType() == -4)
break;
if (tk.getType() != -1)
throw new ParseException("In parameter list <" + s + ">" + ", expected parameter name, " + "got \"" +
tk.getValue() + "\"");
String name = tk.getValue().toLowerCase(Locale.ENGLISH);
tk = h.next();
if ((char)tk.getType() != '=')
throw new ParseException("In parameter list <" + s + ">" + ", expected '=', " + "got \"" +
tk.getValue() + "\"");
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();
if (type != -1 && type != -2)
throw new ParseException("In parameter list <" + s + ">" + ", expected parameter value, " + "got \"" +
tk.getValue() + "\"");
String value = tk.getValue();
this.lastName = name;
if (decodeParameters) {
putEncodedName(name, value);
continue;
}
this.list.put(name, value);
continue;
}
if (type == -1 && this.lastName != null && ((applehack && (
this.lastName.equals("name") ||
this.lastName.equals("filename"))) || !parametersStrict)) {
String lastValue = (String)this.list.get(this.lastName);
String value = lastValue + " " + tk.getValue();
this.list.put(this.lastName, value);
continue;
}
throw new ParseException("In parameter list <" + s + ">" + ", expected ';', got \"" +
tk.getValue() + "\"");
}
if (decodeParameters)
combineMultisegmentNames(false);
}
public void combineSegments() {
if (decodeParameters && this.multisegmentNames.size() > 0)
try {
combineMultisegmentNames(true);
} catch (ParseException e) {}
}
private void putEncodedName(String name, String value) throws ParseException {
int star = name.indexOf('*');
if (star < 0) {
this.list.put(name, value);
} else if (star == name.length() - 1) {
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());
}
this.list.put(name, v);
} else {
Object v;
String rname = name.substring(0, star);
this.multisegmentNames.add(rname);
this.list.put(rname, "");
if (name.endsWith("*")) {
if (name.endsWith("*0*")) {
v = extractCharset(value);
} else {
v = new Value();
((Value)v).encodedValue = value;
((Value)v).value = value;
}
name = name.substring(0, name.length() - 1);
} else {
v = value;
}
this.slist.put(name, v);
}
}
private void combineMultisegmentNames(boolean keepConsistentOnFailure) throws ParseException {
boolean success = false;
try {
Iterator<String> it = this.multisegmentNames.iterator();
while (it.hasNext()) {
String name = it.next();
MultiValue mv = new MultiValue();
String charset = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int segment;
for (segment = 0;; segment++) {
String sname = name + "*" + segment;
Object v = this.slist.get(sname);
if (v == null)
break;
mv.add(v);
try {
if (v instanceof Value) {
Value vv = (Value)v;
if (segment == 0) {
charset = vv.charset;
} else if (charset == null) {
this.multisegmentNames.remove(name);
break;
}
decodeBytes(vv.value, bos);
} else {
bos.write(ASCIIUtility.getBytes((String)v));
}
} catch (IOException e) {}
this.slist.remove(sname);
}
if (segment == 0) {
this.list.remove(name);
continue;
}
try {
if (charset != null)
charset = MimeUtility.javaCharset(charset);
if (charset == null || charset.length() == 0)
charset = MimeUtility.getDefaultJavaCharset();
if (charset != null) {
mv.value = bos.toString(charset);
} else {
mv.value = bos.toString();
}
} catch (UnsupportedEncodingException uex) {
if (decodeParametersStrict)
throw new ParseException(uex.toString());
try {
mv.value = bos.toString("iso-8859-1");
} catch (UnsupportedEncodingException e) {}
}
this.list.put(name, mv);
}
success = true;
} finally {
if (keepConsistentOnFailure || success) {
if (this.slist.size() > 0) {
Iterator sit = this.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());
}
}
}
this.list.putAll(this.slist);
}
this.multisegmentNames.clear();
this.slist.clear();
}
}
}
public int size() {
return this.list.size();
}
public String get(String name) {
String value;
Object v = this.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;
}
public void set(String name, String value) {
name = name.trim().toLowerCase(Locale.ENGLISH);
if (decodeParameters) {
try {
putEncodedName(name, value);
} catch (ParseException pex) {
this.list.put(name, value);
}
} else {
this.list.put(name, value);
}
}
public void set(String name, String value, String charset) {
if (encodeParameters) {
Value ev = encodeValue(value, charset);
if (ev != null) {
this.list.put(name.trim().toLowerCase(Locale.ENGLISH), ev);
} else {
set(name, value);
}
} else {
set(name, value);
}
}
public void remove(String name) {
this.list.remove(name.trim().toLowerCase(Locale.ENGLISH));
}
public Enumeration getNames() {
return new ParamEnum(this.list.keySet().iterator());
}
public String toString() {
return toString(0);
}
public String toString(int used) {
ToStringBuffer sb = new ToStringBuffer(used);
Iterator<Map.Entry> e = this.list.entrySet().iterator();
while (e.hasNext()) {
Map.Entry ent = e.next();
String name = (String)ent.getKey();
Object v = ent.getValue();
if (v instanceof MultiValue) {
MultiValue vv = (MultiValue)v;
name = name + "*";
for (int i = 0; i < vv.size(); i++) {
String str1, ns;
Object va = vv.get(i);
if (va instanceof Value) {
ns = name + i + "*";
str1 = ((Value)va).encodedValue;
} else {
ns = name + i;
str1 = (String)va;
}
sb.addNV(ns, quote(str1));
}
continue;
}
if (v instanceof Value) {
name = name + "*";
String str = ((Value)v).encodedValue;
sb.addNV(name, quote(str));
continue;
}
String value = (String)v;
if (value.length() > 60 && splitLongParameters && encodeParameters) {
int seg = 0;
name = name + "*";
while (value.length() > 60) {
sb.addNV(name + seg, quote(value.substring(0, 60)));
value = value.substring(60);
seg++;
}
if (value.length() > 0)
sb.addNV(name + seg, quote(value));
continue;
}
sb.addNV(name, quote(value));
}
return sb.toString();
}
private static class ToStringBuffer {
private int used;
private StringBuffer sb = new StringBuffer();
public ToStringBuffer(int used) {
this.used = used;
}
public void addNV(String name, String value) {
this.sb.append("; ");
this.used += 2;
int len = name.length() + value.length() + 1;
if (this.used + len > 76) {
this.sb.append("\r\n\t");
this.used = 8;
}
this.sb.append(name).append('=');
this.used += name.length() + 1;
if (this.used + value.length() > 76) {
String s = MimeUtility.fold(this.used, value);
this.sb.append(s);
int lastlf = s.lastIndexOf('\n');
if (lastlf >= 0) {
this.used += s.length() - lastlf - 1;
} else {
this.used += s.length();
}
} else {
this.sb.append(value);
this.used += value.length();
}
}
public String toString() {
return this.sb.toString();
}
}
private static String quote(String value) {
return MimeUtility.quote(value, "()<>@,;:\\\"\t []/?=");
}
private static final char[] hex = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' };
private static Value encodeValue(String value, String charset) {
byte[] b;
if (MimeUtility.checkAscii(value) == 1)
return null;
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);
if (c <= ' ' || c >= '\u007F' || c == '*' || c == '\'' || c == '%' || "()<>@,;:\\\"\t []/?="
.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;
}
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;
}
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;
}
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;
}
private static String decodeBytes(String value, String charset) throws ParseException, UnsupportedEncodingException {
byte[] b = new byte[value.length()];
int bi;
for (int 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());
}
b[bi++] = (byte)c;
}
if (charset != null)
charset = MimeUtility.javaCharset(charset);
if (charset == null || charset.length() == 0)
charset = MimeUtility.getDefaultJavaCharset();
return new String(b, 0, bi, charset);
}
private static void decodeBytes(String value, OutputStream os) throws ParseException, IOException {
for (int 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);
}
}
}

View file

@ -0,0 +1,13 @@
package javax.mail.internet;
import javax.mail.MessagingException;
public class ParseException extends MessagingException {
private static final long serialVersionUID = 7649991205183658089L;
public ParseException() {}
public ParseException(String s) {
super(s);
}
}

View file

@ -0,0 +1,39 @@
package javax.mail.internet;
import com.sun.mail.util.LineOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import javax.mail.MessagingException;
public class PreencodedMimeBodyPart extends MimeBodyPart {
private String encoding;
public PreencodedMimeBodyPart(String encoding) {
this.encoding = encoding;
}
public String getEncoding() throws MessagingException {
return this.encoding;
}
public void writeTo(OutputStream os) throws IOException, MessagingException {
LineOutputStream los = null;
if (os instanceof LineOutputStream) {
los = (LineOutputStream)os;
} else {
los = new LineOutputStream(os);
}
Enumeration<String> hdrLines = getAllHeaderLines();
while (hdrLines.hasMoreElements())
los.writeln(hdrLines.nextElement());
los.writeln();
getDataHandler().writeTo(os);
os.flush();
}
protected void updateHeaders() throws MessagingException {
super.updateHeaders();
MimeBodyPart.setEncoding(this, this.encoding);
}
}

View file

@ -0,0 +1,9 @@
package javax.mail.internet;
import java.io.InputStream;
public interface SharedInputStream {
long getPosition();
InputStream newStream(long paramLong1, long paramLong2);
}

View file

@ -0,0 +1,36 @@
package javax.mail.internet;
import java.util.concurrent.atomic.AtomicInteger;
import javax.mail.Session;
class UniqueValue {
private static AtomicInteger id = new AtomicInteger();
public static String getUniqueBoundaryValue() {
StringBuffer s = new StringBuffer();
long hash = (long)s.hashCode();
s.append("----=_Part_").append(id.getAndIncrement()).append("_")
.append(hash).append('.')
.append(System.currentTimeMillis());
return s.toString();
}
public static String getUniqueMessageIDValue(Session ssn) {
String suffix = null;
InternetAddress addr = InternetAddress.getLocalAddress(ssn);
if (addr != null) {
suffix = addr.getAddress();
} else {
suffix = "javamailuser@localhost";
}
int at = suffix.lastIndexOf('@');
if (at >= 0)
suffix = suffix.substring(at);
StringBuffer s = new StringBuffer();
s.append(s.hashCode()).append('.')
.append(id.getAndIncrement()).append('.')
.append(System.currentTimeMillis())
.append(suffix);
return s.toString();
}
}

View file

@ -0,0 +1,26 @@
package javax.mail.search;
import javax.mail.Address;
import javax.mail.internet.InternetAddress;
public abstract class AddressStringTerm extends StringTerm {
private static final long serialVersionUID = 3086821234204980368L;
protected AddressStringTerm(String pattern) {
super(pattern, true);
}
protected boolean match(Address a) {
if (a instanceof InternetAddress) {
InternetAddress ia = (InternetAddress)a;
return match(ia.toUnicodeString());
}
return match(a.toString());
}
public boolean equals(Object obj) {
if (!(obj instanceof AddressStringTerm))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,32 @@
package javax.mail.search;
import javax.mail.Address;
public abstract class AddressTerm extends SearchTerm {
protected Address address;
private static final long serialVersionUID = 2005405551929769980L;
protected AddressTerm(Address address) {
this.address = address;
}
public Address getAddress() {
return this.address;
}
protected boolean match(Address a) {
return a.equals(this.address);
}
public boolean equals(Object obj) {
if (!(obj instanceof AddressTerm))
return false;
AddressTerm at = (AddressTerm)obj;
return at.address.equals(this.address);
}
public int hashCode() {
return this.address.hashCode();
}
}

View file

@ -0,0 +1,53 @@
package javax.mail.search;
import javax.mail.Message;
public final class AndTerm extends SearchTerm {
private SearchTerm[] terms;
private static final long serialVersionUID = -3583274505380989582L;
public AndTerm(SearchTerm t1, SearchTerm t2) {
this.terms = new SearchTerm[2];
this.terms[0] = t1;
this.terms[1] = t2;
}
public AndTerm(SearchTerm[] t) {
this.terms = new SearchTerm[t.length];
for (int i = 0; i < t.length; i++)
this.terms[i] = t[i];
}
public SearchTerm[] getTerms() {
return (SearchTerm[])this.terms.clone();
}
public boolean match(Message msg) {
for (int i = 0; i < this.terms.length; i++) {
if (!this.terms[i].match(msg))
return false;
}
return true;
}
public boolean equals(Object obj) {
if (!(obj instanceof AndTerm))
return false;
AndTerm at = (AndTerm)obj;
if (at.terms.length != this.terms.length)
return false;
for (int i = 0; i < this.terms.length; i++) {
if (!this.terms[i].equals(at.terms[i]))
return false;
}
return true;
}
public int hashCode() {
int hash = 0;
for (int i = 0; i < this.terms.length; i++)
hash += this.terms[i].hashCode();
return hash;
}
}

View file

@ -0,0 +1,51 @@
package javax.mail.search;
import java.io.IOException;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
public final class BodyTerm extends StringTerm {
private static final long serialVersionUID = -4888862527916911385L;
public BodyTerm(String pattern) {
super(pattern);
}
public boolean match(Message msg) {
return matchPart(msg);
}
private boolean matchPart(Part p) {
try {
if (p.isMimeType("text/*")) {
String s = (String)p.getContent();
if (s == null)
return false;
return match(s);
}
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 (MessagingException e) {
} catch (IOException e) {
} catch (RuntimeException e) {}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof BodyTerm))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,30 @@
package javax.mail.search;
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;
protected int comparison;
private static final long serialVersionUID = 1456646953666474308L;
public boolean equals(Object obj) {
if (!(obj instanceof ComparisonTerm))
return false;
ComparisonTerm ct = (ComparisonTerm)obj;
return (ct.comparison == this.comparison);
}
public int hashCode() {
return this.comparison;
}
}

View file

@ -0,0 +1,51 @@
package javax.mail.search;
import java.util.Date;
public abstract class DateTerm extends ComparisonTerm {
protected Date date;
private static final long serialVersionUID = 4818873430063720043L;
protected DateTerm(int comparison, Date date) {
this.comparison = comparison;
this.date = date;
}
public Date getDate() {
return new Date(this.date.getTime());
}
public int getComparison() {
return this.comparison;
}
protected boolean match(Date d) {
switch (this.comparison) {
case 1:
return (d.before(this.date) || d.equals(this.date));
case 2:
return d.before(this.date);
case 3:
return d.equals(this.date);
case 4:
return !d.equals(this.date);
case 5:
return d.after(this.date);
case 6:
return (d.after(this.date) || d.equals(this.date));
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof DateTerm))
return false;
DateTerm dt = (DateTerm)obj;
return (dt.date.equals(this.date) && super.equals(obj));
}
public int hashCode() {
return this.date.hashCode() + super.hashCode();
}
}

View file

@ -0,0 +1,63 @@
package javax.mail.search;
import javax.mail.Flags;
import javax.mail.Message;
import javax.mail.MessagingException;
public final class FlagTerm extends SearchTerm {
private boolean set;
private Flags flags;
private static final long serialVersionUID = -142991500302030647L;
public FlagTerm(Flags flags, boolean set) {
this.flags = flags;
this.set = set;
}
public Flags getFlags() {
return (Flags)this.flags.clone();
}
public boolean getTestSet() {
return this.set;
}
public boolean match(Message msg) {
try {
Flags f = msg.getFlags();
if (this.set) {
if (f.contains(this.flags))
return true;
return false;
}
Flags.Flag[] sf = this.flags.getSystemFlags();
for (int i = 0; i < sf.length; i++) {
if (f.contains(sf[i]))
return false;
}
String[] s = this.flags.getUserFlags();
for (int j = 0; j < s.length; j++) {
if (f.contains(s[j]))
return false;
}
return true;
} catch (MessagingException e) {
return false;
} catch (RuntimeException e) {
return false;
}
}
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));
}
public int hashCode() {
return this.set ? this.flags.hashCode() : (this.flags.hashCode() ^ 0xFFFFFFFF);
}
}

View file

@ -0,0 +1,34 @@
package javax.mail.search;
import javax.mail.Address;
import javax.mail.Message;
public final class FromStringTerm extends AddressStringTerm {
private static final long serialVersionUID = 5801127523826772788L;
public FromStringTerm(String pattern) {
super(pattern);
}
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 (match(from[i]))
return true;
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof FromStringTerm))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,34 @@
package javax.mail.search;
import javax.mail.Address;
import javax.mail.Message;
public final class FromTerm extends AddressTerm {
private static final long serialVersionUID = 5214730291502658665L;
public FromTerm(Address address) {
super(address);
}
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 (match(from[i]))
return true;
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof FromTerm))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,46 @@
package javax.mail.search;
import java.util.Locale;
import javax.mail.Message;
public final class HeaderTerm extends StringTerm {
private String headerName;
private static final long serialVersionUID = 8342514650333389122L;
public HeaderTerm(String headerName, String pattern) {
super(pattern);
this.headerName = headerName;
}
public String getHeaderName() {
return this.headerName;
}
public boolean match(Message msg) {
String[] headers;
try {
headers = msg.getHeader(this.headerName);
} catch (Exception e) {
return false;
}
if (headers == null)
return false;
for (int i = 0; i < headers.length; i++) {
if (match(headers[i]))
return true;
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof HeaderTerm))
return false;
HeaderTerm ht = (HeaderTerm)obj;
return (ht.headerName.equalsIgnoreCase(this.headerName) && super.equals(ht));
}
public int hashCode() {
return this.headerName.toLowerCase(Locale.ENGLISH).hashCode() + super.hashCode();
}
}

View file

@ -0,0 +1,49 @@
package javax.mail.search;
public abstract class IntegerComparisonTerm extends ComparisonTerm {
protected int number;
private static final long serialVersionUID = -6963571240154302484L;
protected IntegerComparisonTerm(int comparison, int number) {
this.comparison = comparison;
this.number = number;
}
public int getNumber() {
return this.number;
}
public int getComparison() {
return this.comparison;
}
protected boolean match(int i) {
switch (this.comparison) {
case 1:
return (i <= this.number);
case 2:
return (i < this.number);
case 3:
return (i == this.number);
case 4:
return (i != this.number);
case 5:
return (i > this.number);
case 6:
return (i >= this.number);
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof IntegerComparisonTerm))
return false;
IntegerComparisonTerm ict = (IntegerComparisonTerm)obj;
return (ict.number == this.number && super.equals(obj));
}
public int hashCode() {
return this.number + super.hashCode();
}
}

View file

@ -0,0 +1,33 @@
package javax.mail.search;
import javax.mail.Message;
public final class MessageIDTerm extends StringTerm {
private static final long serialVersionUID = -2121096296454691963L;
public MessageIDTerm(String msgid) {
super(msgid);
}
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 (match(s[i]))
return true;
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof MessageIDTerm))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,27 @@
package javax.mail.search;
import javax.mail.Message;
public final class MessageNumberTerm extends IntegerComparisonTerm {
private static final long serialVersionUID = -5379625829658623812L;
public MessageNumberTerm(int number) {
super(3, number);
}
public boolean match(Message msg) {
int msgno;
try {
msgno = msg.getMessageNumber();
} catch (Exception e) {
return false;
}
return match(msgno);
}
public boolean equals(Object obj) {
if (!(obj instanceof MessageNumberTerm))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,32 @@
package javax.mail.search;
import javax.mail.Message;
public final class NotTerm extends SearchTerm {
private SearchTerm term;
private static final long serialVersionUID = 7152293214217310216L;
public NotTerm(SearchTerm t) {
this.term = t;
}
public SearchTerm getTerm() {
return this.term;
}
public boolean match(Message msg) {
return !this.term.match(msg);
}
public boolean equals(Object obj) {
if (!(obj instanceof NotTerm))
return false;
NotTerm nt = (NotTerm)obj;
return nt.term.equals(this.term);
}
public int hashCode() {
return this.term.hashCode() << 1;
}
}

View file

@ -0,0 +1,53 @@
package javax.mail.search;
import javax.mail.Message;
public final class OrTerm extends SearchTerm {
private SearchTerm[] terms;
private static final long serialVersionUID = 5380534067523646936L;
public OrTerm(SearchTerm t1, SearchTerm t2) {
this.terms = new SearchTerm[2];
this.terms[0] = t1;
this.terms[1] = t2;
}
public OrTerm(SearchTerm[] t) {
this.terms = new SearchTerm[t.length];
for (int i = 0; i < t.length; i++)
this.terms[i] = t[i];
}
public SearchTerm[] getTerms() {
return (SearchTerm[])this.terms.clone();
}
public boolean match(Message msg) {
for (int i = 0; i < this.terms.length; i++) {
if (this.terms[i].match(msg))
return true;
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof OrTerm))
return false;
OrTerm ot = (OrTerm)obj;
if (ot.terms.length != this.terms.length)
return false;
for (int i = 0; i < this.terms.length; i++) {
if (!this.terms[i].equals(ot.terms[i]))
return false;
}
return true;
}
public int hashCode() {
int hash = 0;
for (int i = 0; i < this.terms.length; i++)
hash += this.terms[i].hashCode();
return hash;
}
}

View file

@ -0,0 +1,30 @@
package javax.mail.search;
import java.util.Date;
import javax.mail.Message;
public final class ReceivedDateTerm extends DateTerm {
private static final long serialVersionUID = -2756695246195503170L;
public ReceivedDateTerm(int comparison, Date date) {
super(comparison, date);
}
public boolean match(Message msg) {
Date d;
try {
d = msg.getReceivedDate();
} catch (Exception e) {
return false;
}
if (d == null)
return false;
return match(d);
}
public boolean equals(Object obj) {
if (!(obj instanceof ReceivedDateTerm))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,46 @@
package javax.mail.search;
import javax.mail.Address;
import javax.mail.Message;
public final class RecipientStringTerm extends AddressStringTerm {
private Message.RecipientType type;
private static final long serialVersionUID = -8293562089611618849L;
public RecipientStringTerm(Message.RecipientType type, String pattern) {
super(pattern);
this.type = type;
}
public Message.RecipientType getRecipientType() {
return this.type;
}
public boolean match(Message msg) {
Address[] recipients;
try {
recipients = msg.getRecipients(this.type);
} catch (Exception e) {
return false;
}
if (recipients == null)
return false;
for (int i = 0; i < recipients.length; i++) {
if (match(recipients[i]))
return true;
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof RecipientStringTerm))
return false;
RecipientStringTerm rst = (RecipientStringTerm)obj;
return (rst.type.equals(this.type) && super.equals(obj));
}
public int hashCode() {
return this.type.hashCode() + super.hashCode();
}
}

View file

@ -0,0 +1,46 @@
package javax.mail.search;
import javax.mail.Address;
import javax.mail.Message;
public final class RecipientTerm extends AddressTerm {
private Message.RecipientType type;
private static final long serialVersionUID = 6548700653122680468L;
public RecipientTerm(Message.RecipientType type, Address address) {
super(address);
this.type = type;
}
public Message.RecipientType getRecipientType() {
return this.type;
}
public boolean match(Message msg) {
Address[] recipients;
try {
recipients = msg.getRecipients(this.type);
} catch (Exception e) {
return false;
}
if (recipients == null)
return false;
for (int i = 0; i < recipients.length; i++) {
if (match(recipients[i]))
return true;
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof RecipientTerm))
return false;
RecipientTerm rt = (RecipientTerm)obj;
return (rt.type.equals(this.type) && super.equals(obj));
}
public int hashCode() {
return this.type.hashCode() + super.hashCode();
}
}

View file

@ -0,0 +1,13 @@
package javax.mail.search;
import javax.mail.MessagingException;
public class SearchException extends MessagingException {
private static final long serialVersionUID = -7092886778226268686L;
public SearchException() {}
public SearchException(String s) {
super(s);
}
}

View file

@ -0,0 +1,10 @@
package javax.mail.search;
import java.io.Serializable;
import javax.mail.Message;
public abstract class SearchTerm implements Serializable {
private static final long serialVersionUID = -6652358452205992789L;
public abstract boolean match(Message paramMessage);
}

View file

@ -0,0 +1,30 @@
package javax.mail.search;
import java.util.Date;
import javax.mail.Message;
public final class SentDateTerm extends DateTerm {
private static final long serialVersionUID = 5647755030530907263L;
public SentDateTerm(int comparison, Date date) {
super(comparison, date);
}
public boolean match(Message msg) {
Date d;
try {
d = msg.getSentDate();
} catch (Exception e) {
return false;
}
if (d == null)
return false;
return match(d);
}
public boolean equals(Object obj) {
if (!(obj instanceof SentDateTerm))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,29 @@
package javax.mail.search;
import javax.mail.Message;
public final class SizeTerm extends IntegerComparisonTerm {
private static final long serialVersionUID = -2556219451005103709L;
public SizeTerm(int comparison, int size) {
super(comparison, size);
}
public boolean match(Message msg) {
int size;
try {
size = msg.getSize();
} catch (Exception e) {
return false;
}
if (size == -1)
return false;
return match(size);
}
public boolean equals(Object obj) {
if (!(obj instanceof SizeTerm))
return false;
return super.equals(obj);
}
}

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