Source Code Cross Referenced for MailMessage.java in  » Build » ANT » org » apache » tools » mail » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Build » ANT » org.apache.tools.mail 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         *
017:         */
018:
019:        /*
020:         * The original version of this class was donated by Jason Hunter,
021:         * who wrote the class as part of the com.oreilly.servlet
022:         * package for his book "Java Servlet Programming" (O'Reilly).
023:         * See http://www.servlets.com.
024:         *
025:         */
026:
027:        package org.apache.tools.mail;
028:
029:        import java.io.IOException;
030:        import java.io.PrintStream;
031:        import java.io.BufferedOutputStream;
032:        import java.io.OutputStream;
033:        import java.net.Socket;
034:        import java.net.InetAddress;
035:        import java.util.Vector;
036:        import java.util.Enumeration;
037:
038:        /**
039:         * A class to help send SMTP email.
040:         * This class is an improvement on the sun.net.smtp.SmtpClient class
041:         * found in the JDK.  This version has extra functionality, and can be used
042:         * with JVMs that did not extend from the JDK.  It's not as robust as
043:         * the JavaMail Standard Extension classes, but it's easier to use and
044:         * easier to install, and has an Open Source license.
045:         * <p>
046:         * It can be used like this:
047:         * <blockquote><pre>
048:         * String mailhost = "localhost";  // or another mail host
049:         * String from = "Mail Message Servlet &lt;MailMessage@server.com&gt;";
050:         * String to = "to@you.com";
051:         * String cc1 = "cc1@you.com";
052:         * String cc2 = "cc2@you.com";
053:         * String bcc = "bcc@you.com";
054:         * &nbsp;
055:         * MailMessage msg = new MailMessage(mailhost);
056:         * msg.setPort(25);
057:         * msg.from(from);
058:         * msg.to(to);
059:         * msg.cc(cc1);
060:         * msg.cc(cc2);
061:         * msg.bcc(bcc);
062:         * msg.setSubject("Test subject");
063:         * PrintStream out = msg.getPrintStream();
064:         * &nbsp;
065:         * Enumeration enum = req.getParameterNames();
066:         * while (enum.hasMoreElements()) {
067:         *   String name = (String)enum.nextElement();
068:         *   String value = req.getParameter(name);
069:         *   out.println(name + " = " + value);
070:         * }
071:         * &nbsp;
072:         * msg.sendAndClose();
073:         * </pre></blockquote>
074:         * <p>
075:         * Be sure to set the from address, then set the recepient
076:         * addresses, then set the subject and other headers, then get the
077:         * PrintStream, then write the message, and finally send and close.
078:         * The class does minimal error checking internally; it counts on the mail
079:         * host to complain if there's any malformatted input or out of order
080:         * execution.
081:         * <p>
082:         * An attachment mechanism based on RFC 1521 could be implemented on top of
083:         * this class.  In the meanwhile, JavaMail is the best solution for sending
084:         * email with attachments.
085:         * <p>
086:         * Still to do:
087:         * <ul>
088:         * <li>Figure out how to close the connection in case of error
089:         * </ul>
090:         *
091:         * @version 1.1, 2000/03/19, added angle brackets to address, helps some servers
092:         * version 1.0, 1999/12/29
093:         */
094:        public class MailMessage {
095:
096:            /** default mailhost */
097:            public static final String DEFAULT_HOST = "localhost";
098:
099:            /** default port for SMTP: 25 */
100:            public static final int DEFAULT_PORT = 25;
101:
102:            /** host name for the mail server */
103:            private String host;
104:
105:            /** host port for the mail server */
106:            private int port = DEFAULT_PORT;
107:
108:            /** sender email address */
109:            private String from;
110:
111:            /** list of email addresses to reply to */
112:            private Vector replyto;
113:
114:            /** list of email addresses to send to */
115:            private Vector to;
116:
117:            /** list of email addresses to cc to */
118:            private Vector cc;
119:
120:            /** headers to send in the mail */
121:            private Vector headersKeys;
122:            private Vector headersValues;
123:
124:            private MailPrintStream out;
125:
126:            private SmtpResponseReader in;
127:
128:            private Socket socket;
129:            private static final int OK_READY = 220;
130:            private static final int OK_HELO = 250;
131:            private static final int OK_FROM = 250;
132:            private static final int OK_RCPT_1 = 250;
133:            private static final int OK_RCPT_2 = 251;
134:            private static final int OK_DATA = 354;
135:            private static final int OK_DOT = 250;
136:            private static final int OK_QUIT = 221;
137:
138:            /**
139:             * Constructs a new MailMessage to send an email.
140:             * Use localhost as the mail server with port 25.
141:             *
142:             * @exception IOException if there's any problem contacting the mail server
143:             */
144:            public MailMessage() throws IOException {
145:                this (DEFAULT_HOST, DEFAULT_PORT);
146:            }
147:
148:            /**
149:             * Constructs a new MailMessage to send an email.
150:             * Use the given host as the mail server with port 25.
151:             *
152:             * @param host the mail server to use
153:             * @exception IOException if there's any problem contacting the mail server
154:             */
155:            public MailMessage(String host) throws IOException {
156:                this (host, DEFAULT_PORT);
157:            }
158:
159:            /**
160:             * Constructs a new MailMessage to send an email.
161:             * Use the given host and port as the mail server.
162:             *
163:             * @param host the mail server to use
164:             * @param port the port to connect to
165:             * @exception IOException if there's any problem contacting the mail server
166:             */
167:            public MailMessage(String host, int port) throws IOException {
168:                this .port = port;
169:                this .host = host;
170:                replyto = new Vector();
171:                to = new Vector();
172:                cc = new Vector();
173:                headersKeys = new Vector();
174:                headersValues = new Vector();
175:                connect();
176:                sendHelo();
177:            }
178:
179:            /**
180:             * Set the port to connect to the SMTP host.
181:             * @param port the port to use for connection.
182:             * @see #DEFAULT_PORT
183:             */
184:            public void setPort(int port) {
185:                this .port = port;
186:            }
187:
188:            /**
189:             * Sets the from address.  Also sets the "From" header.  This method should
190:             * be called only once.
191:             * @param from the from address
192:             * @exception IOException if there's any problem reported by the mail server
193:             */
194:            public void from(String from) throws IOException {
195:                sendFrom(from);
196:                this .from = from;
197:            }
198:
199:            /**
200:             * Sets the replyto address
201:             * This method may be
202:             * called multiple times.
203:             * @param rto the replyto address
204:             *
205:             */
206:            public void replyto(String rto) {
207:                this .replyto.addElement(rto);
208:            }
209:
210:            /**
211:             * Sets the to address.  Also sets the "To" header.  This method may be
212:             * called multiple times.
213:             *
214:             * @param to the to address
215:             * @exception IOException if there's any problem reported by the mail server
216:             */
217:            public void to(String to) throws IOException {
218:                sendRcpt(to);
219:                this .to.addElement(to);
220:            }
221:
222:            /**
223:             * Sets the cc address.  Also sets the "Cc" header.  This method may be
224:             * called multiple times.
225:             *
226:             * @param cc the cc address
227:             * @exception IOException if there's any problem reported by the mail server
228:             */
229:            public void cc(String cc) throws IOException {
230:                sendRcpt(cc);
231:                this .cc.addElement(cc);
232:            }
233:
234:            /**
235:             * Sets the bcc address.  Does NOT set any header since it's a *blind* copy.
236:             * This method may be called multiple times.
237:             *
238:             * @param bcc the bcc address
239:             * @exception IOException if there's any problem reported by the mail server
240:             */
241:            public void bcc(String bcc) throws IOException {
242:                sendRcpt(bcc);
243:                // No need to keep track of Bcc'd addresses
244:            }
245:
246:            /**
247:             * Sets the subject of the mail message.  Actually sets the "Subject"
248:             * header.
249:             * @param subj the subject of the mail message
250:             */
251:            public void setSubject(String subj) {
252:                setHeader("Subject", subj);
253:            }
254:
255:            /**
256:             * Sets the named header to the given value.  RFC 822 provides the rules for
257:             * what text may constitute a header name and value.
258:             * @param name name of the header
259:             * @param value contents of the header
260:             */
261:            public void setHeader(String name, String value) {
262:                // Blindly trust the user doesn't set any invalid headers
263:                headersKeys.add(name);
264:                headersValues.add(value);
265:            }
266:
267:            /**
268:             * Returns a PrintStream that can be used to write the body of the message.
269:             * A stream is used since email bodies are byte-oriented.  A writer can
270:             * be wrapped on top if necessary for internationalization.
271:             * This is actually done in Message.java
272:             *
273:             * @return a printstream containing the data and the headers of the email
274:             * @exception IOException if there's any problem reported by the mail server
275:             * @see org.apache.tools.ant.taskdefs.email.Message
276:             */
277:            public PrintStream getPrintStream() throws IOException {
278:                setFromHeader();
279:                setReplyToHeader();
280:                setToHeader();
281:                setCcHeader();
282:                setHeader("X-Mailer",
283:                        "org.apache.tools.mail.MailMessage (ant.apache.org)");
284:                sendData();
285:                flushHeaders();
286:                return out;
287:            }
288:
289:            // RFC 822 s4.1: "From:" header must be sent
290:            // We rely on error checking by the MTA
291:            void setFromHeader() {
292:                setHeader("From", from);
293:            }
294:
295:            // RFC 822 s4.1: "Reply-To:" header is optional
296:            void setReplyToHeader() {
297:                if (!replyto.isEmpty()) {
298:                    setHeader("Reply-To", vectorToList(replyto));
299:                }
300:            }
301:
302:            void setToHeader() {
303:                if (!to.isEmpty()) {
304:                    setHeader("To", vectorToList(to));
305:                }
306:            }
307:
308:            void setCcHeader() {
309:                if (!cc.isEmpty()) {
310:                    setHeader("Cc", vectorToList(cc));
311:                }
312:            }
313:
314:            String vectorToList(Vector v) {
315:                StringBuffer buf = new StringBuffer();
316:                Enumeration e = v.elements();
317:                while (e.hasMoreElements()) {
318:                    buf.append(e.nextElement());
319:                    if (e.hasMoreElements()) {
320:                        buf.append(", ");
321:                    }
322:                }
323:                return buf.toString();
324:            }
325:
326:            void flushHeaders() throws IOException {
327:                // RFC 822 s4.1:
328:                //   "Header fields are NOT required to occur in any particular order,
329:                //    except that the message body MUST occur AFTER the headers"
330:                // (the same section specifies a reccommended order, which we ignore)
331:                for (int i = 0; i < headersKeys.size(); i++) {
332:                    String name = (String) headersKeys.elementAt(i);
333:                    String value = (String) headersValues.elementAt(i);
334:                    out.println(name + ": " + value);
335:                }
336:                out.println();
337:                out.flush();
338:            }
339:
340:            /**
341:             * Sends the message and closes the connection to the server.
342:             * The MailMessage object cannot be reused.
343:             *
344:             * @exception IOException if there's any problem reported by the mail server
345:             */
346:            public void sendAndClose() throws IOException {
347:                try {
348:                    sendDot();
349:                    sendQuit();
350:                } finally {
351:                    disconnect();
352:                }
353:            }
354:
355:            // Make a limited attempt to extract a sanitized email address
356:            // Prefer text in <brackets>, ignore anything in (parentheses)
357:            static String sanitizeAddress(String s) {
358:                int paramDepth = 0;
359:                int start = 0;
360:                int end = 0;
361:                int len = s.length();
362:
363:                for (int i = 0; i < len; i++) {
364:                    char c = s.charAt(i);
365:                    if (c == '(') {
366:                        paramDepth++;
367:                        if (start == 0) {
368:                            end = i; // support "address (name)"
369:                        }
370:                    } else if (c == ')') {
371:                        paramDepth--;
372:                        if (end == 0) {
373:                            start = i + 1; // support "(name) address"
374:                        }
375:                    } else if (paramDepth == 0 && c == '<') {
376:                        start = i + 1;
377:                    } else if (paramDepth == 0 && c == '>') {
378:                        end = i;
379:                    }
380:                }
381:
382:                if (end == 0) {
383:                    end = len;
384:                }
385:
386:                return s.substring(start, end);
387:            }
388:
389:            // * * * * * Raw protocol methods below here * * * * *
390:
391:            void connect() throws IOException {
392:                socket = new Socket(host, port);
393:                out = new MailPrintStream(new BufferedOutputStream(socket
394:                        .getOutputStream()));
395:                in = new SmtpResponseReader(socket.getInputStream());
396:                getReady();
397:            }
398:
399:            void getReady() throws IOException {
400:                String response = in.getResponse();
401:                int[] ok = { OK_READY };
402:                if (!isResponseOK(response, ok)) {
403:                    throw new IOException(
404:                            "Didn't get introduction from server: " + response);
405:                }
406:            }
407:
408:            void sendHelo() throws IOException {
409:                String local = InetAddress.getLocalHost().getHostName();
410:                int[] ok = { OK_HELO };
411:                send("HELO " + local, ok);
412:            }
413:
414:            void sendFrom(String from) throws IOException {
415:                int[] ok = { OK_FROM };
416:                send("MAIL FROM: " + "<" + sanitizeAddress(from) + ">", ok);
417:            }
418:
419:            void sendRcpt(String rcpt) throws IOException {
420:                int[] ok = { OK_RCPT_1, OK_RCPT_2 };
421:                send("RCPT TO: " + "<" + sanitizeAddress(rcpt) + ">", ok);
422:            }
423:
424:            void sendData() throws IOException {
425:                int[] ok = { OK_DATA };
426:                send("DATA", ok);
427:            }
428:
429:            void sendDot() throws IOException {
430:                int[] ok = { OK_DOT };
431:                send("\r\n.", ok); // make sure dot is on new line
432:            }
433:
434:            void sendQuit() throws IOException {
435:                int[] ok = { OK_QUIT };
436:                try {
437:                    send("QUIT", ok);
438:                } catch (IOException e) {
439:                    throw new ErrorInQuitException(e);
440:                }
441:            }
442:
443:            void send(String msg, int[] ok) throws IOException {
444:                out.rawPrint(msg + "\r\n"); // raw supports <CRLF>.<CRLF>
445:                String response = in.getResponse();
446:                if (!isResponseOK(response, ok)) {
447:                    throw new IOException("Unexpected reply to command: " + msg
448:                            + ": " + response);
449:                }
450:            }
451:
452:            boolean isResponseOK(String response, int[] ok) {
453:                // Check that the response is one of the valid codes
454:                for (int i = 0; i < ok.length; i++) {
455:                    if (response.startsWith("" + ok[i])) {
456:                        return true;
457:                    }
458:                }
459:                return false;
460:            }
461:
462:            void disconnect() throws IOException {
463:                if (out != null) {
464:                    out.close();
465:                }
466:                if (in != null) {
467:                    try {
468:                        in.close();
469:                    } catch (IOException e) {
470:                        // ignore
471:                    }
472:                }
473:                if (socket != null) {
474:                    try {
475:                        socket.close();
476:                    } catch (IOException e) {
477:                        // ignore
478:                    }
479:                }
480:            }
481:        }
482:
483:        /**
484:         * This PrintStream subclass makes sure that <CRLF>. becomes <CRLF>..
485:         *  per RFC 821.  It also ensures that new lines are always \r\n.
486:         */
487:        class MailPrintStream extends PrintStream {
488:
489:            private int lastChar;
490:
491:            public MailPrintStream(OutputStream out) {
492:                super (out, true); // deprecated, but email is byte-oriented
493:            }
494:
495:            // Mac does \n\r, but that's tough to distinguish from Windows \r\n\r\n.
496:            // Don't tackle that problem right now.
497:            public void write(int b) {
498:                if (b == '\n' && lastChar != '\r') {
499:                    rawWrite('\r'); // ensure always \r\n
500:                    rawWrite(b);
501:                } else if (b == '.' && lastChar == '\n') {
502:                    rawWrite('.'); // add extra dot
503:                    rawWrite(b);
504:                } else {
505:                    rawWrite(b);
506:                }
507:                lastChar = b;
508:            }
509:
510:            public void write(byte[] buf, int off, int len) {
511:                for (int i = 0; i < len; i++) {
512:                    write(buf[off + i]);
513:                }
514:            }
515:
516:            void rawWrite(int b) {
517:                super .write(b);
518:            }
519:
520:            void rawPrint(String s) {
521:                int len = s.length();
522:                for (int i = 0; i < len; i++) {
523:                    rawWrite(s.charAt(i));
524:                }
525:            }
526:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.