| Method from org.apache.tools.mail.MailMessage Detail: |
public void bcc(String bcc) throws IOException {
sendRcpt(bcc);
// No need to keep track of Bcc'd addresses
}
Sets the bcc address. Does NOT set any header since it's a *blind* copy.
This method may be called multiple times. |
public void cc(String cc) throws IOException {
sendRcpt(cc);
this.cc.addElement(cc);
}
Sets the cc address. Also sets the "Cc" header. This method may be
called multiple times. |
void connect() throws IOException {
socket = new Socket(host, port);
out = new MailPrintStream(
new BufferedOutputStream(
socket.getOutputStream()));
in = new SmtpResponseReader(socket.getInputStream());
getReady();
}
|
void disconnect() throws IOException {
if (out != null) {
out.close();
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
// ignore
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// ignore
}
}
}
|
void flushHeaders() throws IOException {
// RFC 822 s4.1:
// "Header fields are NOT required to occur in any particular order,
// except that the message body MUST occur AFTER the headers"
// (the same section specifies a reccommended order, which we ignore)
for (int i = 0; i < headersKeys.size(); i++) {
String name = (String) headersKeys.elementAt(i);
String value = (String) headersValues.elementAt(i);
out.println(name + ": " + value);
}
out.println();
out.flush();
}
|
public void from(String from) throws IOException {
sendFrom(from);
this.from = from;
}
Sets the from address. Also sets the "From" header. This method should
be called only once. |
public PrintStream getPrintStream() throws IOException {
setFromHeader();
setReplyToHeader();
setToHeader();
setCcHeader();
setHeader("X-Mailer", "org.apache.tools.mail.MailMessage (ant.apache.org)");
sendData();
flushHeaders();
return out;
}
Returns a PrintStream that can be used to write the body of the message.
A stream is used since email bodies are byte-oriented. A writer can
be wrapped on top if necessary for internationalization.
This is actually done in Message.java |
void getReady() throws IOException {
String response = in.getResponse();
int[] ok = {OK_READY};
if (!isResponseOK(response, ok)) {
throw new IOException(
"Didn't get introduction from server: " + response);
}
}
|
boolean isResponseOK(String response,
int[] ok) {
// Check that the response is one of the valid codes
for (int i = 0; i < ok.length; i++) {
if (response.startsWith("" + ok[i])) {
return true;
}
}
return false;
}
|
public void replyto(String rto) {
this.replyto.addElement(rto);
}
Sets the replyto address
This method may be
called multiple times. |
static String sanitizeAddress(String s) {
int paramDepth = 0;
int start = 0;
int end = 0;
int len = s.length();
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
if (c == '(") {
paramDepth++;
if (start == 0) {
end = i; // support "address (name)"
}
} else if (c == ')") {
paramDepth--;
if (end == 0) {
start = i + 1; // support "(name) address"
}
} else if (paramDepth == 0 && c == '< ") {
start = i + 1;
} else if (paramDepth == 0 && c == ' >") {
end = i;
}
}
if (end == 0) {
end = len;
}
return s.substring(start, end);
}
|
void send(String msg,
int[] ok) throws IOException {
out.rawPrint(msg + "\r\n"); // raw supports < CRLF >.< CRLF >
String response = in.getResponse();
if (!isResponseOK(response, ok)) {
throw new IOException("Unexpected reply to command: "
+ msg + ": " + response);
}
}
|
public void sendAndClose() throws IOException {
try {
sendDot();
sendQuit();
} finally {
disconnect();
}
}
Sends the message and closes the connection to the server.
The MailMessage object cannot be reused. |
void sendData() throws IOException {
int[] ok = {OK_DATA};
send("DATA", ok);
}
|
void sendDot() throws IOException {
int[] ok = {OK_DOT};
send("\r\n.", ok); // make sure dot is on new line
}
|
void sendFrom(String from) throws IOException {
int[] ok = {OK_FROM};
send("MAIL FROM: " + "< " + sanitizeAddress(from) + " >", ok);
}
|
void sendHelo() throws IOException {
String local = InetAddress.getLocalHost().getHostName();
int[] ok = {OK_HELO};
send("HELO " + local, ok);
}
|
void sendQuit() throws IOException {
int[] ok = {OK_QUIT};
try {
send("QUIT", ok);
} catch (IOException e) {
throw new ErrorInQuitException(e);
}
}
|
void sendRcpt(String rcpt) throws IOException {
int[] ok = {OK_RCPT_1, OK_RCPT_2};
send("RCPT TO: " + "< " + sanitizeAddress(rcpt) + " >", ok);
}
|
void setCcHeader() {
if (!cc.isEmpty()) {
setHeader("Cc", vectorToList(cc));
}
}
|
void setFromHeader() {
setHeader("From", from);
}
|
public void setHeader(String name,
String value) {
// Blindly trust the user doesn't set any invalid headers
headersKeys.add(name);
headersValues.add(value);
}
Sets the named header to the given value. RFC 822 provides the rules for
what text may constitute a header name and value. |
public void setPort(int port) {
this.port = port;
}
Set the port to connect to the SMTP host. |
void setReplyToHeader() {
if (!replyto.isEmpty()) {
setHeader("Reply-To", vectorToList(replyto));
}
}
|
public void setSubject(String subj) {
setHeader("Subject", subj);
}
Sets the subject of the mail message. Actually sets the "Subject"
header. |
void setToHeader() {
if (!to.isEmpty()) {
setHeader("To", vectorToList(to));
}
}
|
public void to(String to) throws IOException {
sendRcpt(to);
this.to.addElement(to);
}
Sets the to address. Also sets the "To" header. This method may be
called multiple times. |
String vectorToList(Vector v) {
StringBuffer buf = new StringBuffer();
Enumeration e = v.elements();
while (e.hasMoreElements()) {
buf.append(e.nextElement());
if (e.hasMoreElements()) {
buf.append(", ");
}
}
return buf.toString();
}
|