KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > protomatter > syslog > SMTPMailTransport


1 package com.protomatter.syslog;
2
3 /**
4  * {{{ The Protomatter Software License, Version 1.0
5  * derived from The Apache Software License, Version 1.1
6  *
7  * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed for the
24  * Protomatter Software Project
25  * (http://protomatter.sourceforge.net/)."
26  * Alternately, this acknowledgment may appear in the software itself,
27  * if and wherever such third-party acknowledgments normally appear.
28  *
29  * 4. The names "Protomatter" and "Protomatter Software Project" must
30  * not be used to endorse or promote products derived from this
31  * software without prior written permission. For written
32  * permission, please contact support@protomatter.com.
33  *
34  * 5. Products derived from this software may not be called "Protomatter",
35  * nor may "Protomatter" appear in their name, without prior written
36  * permission of the Protomatter Software Project
37  * (support@protomatter.com).
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE. }}}
51  */

52
53 import java.io.*;
54 import java.net.*;
55 import java.util.*;
56 import java.text.*;
57 import com.protomatter.util.*;
58
59 /**
60  * A simple class that talks SMTP to servers. This and the
61  * <tt>MailMessage</tt> classes were created since we'll want to
62  * create messages independantly of a mail transport, and that's
63  * not possible with the JavaMail API. This class is thread
64  * safe, but note that multiple parallel calls to the
65  * sending API will cause multiple connections to be made
66  * to the SMTP server.
67  */

68 class SMTPMailTransport
69 {
70   private String JavaDoc hostname = null;
71   private int port = 25;
72   private String JavaDoc transportAgent = "protomatter-syslog-agent";
73   private String JavaDoc CRLF = "\r\n";
74   private SimpleDateFormat dateFormat = new SimpleDateFormat ("EEE, d MMM yyyy HH:mm:ss");
75
76   /**
77    * Create a new transport to speak to the given SMTP
78    * server on port 25.
79    */

80   public SMTPMailTransport(String JavaDoc hostname)
81   {
82     this(hostname, 25);
83     this.hostname = hostname;
84   }
85
86   /**
87    * Create a new transport to speak to the given SMTP
88    * server on the given port.
89    */

90   public SMTPMailTransport(String JavaDoc hostname, int port)
91   {
92     this.hostname = hostname;
93     this.port = port;
94   }
95
96   /**
97    * Get the transport agent name.
98    */

99   public String JavaDoc getTransportAgentName()
100   {
101     return this.transportAgent;
102   }
103
104   /**
105    * Set the transport agent name.
106    */

107   public void setTransportAgentName(String JavaDoc transportAgent)
108   {
109     this.transportAgent = transportAgent;
110   }
111
112   /**
113    * Send a message.
114    */

115   public void sendMessage(MailMessage message)
116   throws MailException, IOException
117   {
118     try
119     {
120       Socket s = new Socket(hostname, port);
121
122       PrintWriter writer = new PrintWriter(s.getOutputStream());
123       BufferedReader reader = new BufferedReader(
124         new InputStreamReader(s.getInputStream()));
125
126       String JavaDoc UR = Syslog.getResourceString(MessageConstants.MAILLOG_UNEXPECTED_RESPONSE_MESSAGE);
127
128       String JavaDoc line = reader.readLine();
129       if (!line.startsWith("2"))
130         throw new MailException(MessageFormat.format(UR, new Object JavaDoc[] { line }));
131
132       writer.print("HELO ");
133       writer.print(transportAgent);
134       writer.print(CRLF);
135       writer.flush();
136
137       line = reader.readLine();
138       if (!line.startsWith("2"))
139         throw new MailException(MessageFormat.format(UR, new Object JavaDoc[] { line }));
140
141       writer.print("MAIL FROM: ");
142       writer.print(message.getFromAddress());
143       writer.print(CRLF);
144       writer.flush();
145
146       line = reader.readLine();
147       if (!line.startsWith("2"))
148         throw new MailException(MessageFormat.format(UR, new Object JavaDoc[] { line }));
149
150
151       // add recipients ("To" list)
152
Enumeration e = message.getTo().elements();
153       while (e.hasMoreElements())
154       {
155         writer.print("RCPT TO: ");
156         writer.print((String JavaDoc)e.nextElement());
157         writer.print(CRLF);
158         writer.flush();
159
160         line = reader.readLine();
161         if (!line.startsWith("2"))
162           throw new MailException(MessageFormat.format(UR, new Object JavaDoc[] { line }));
163       }
164
165       // add recipients ("CC" list)
166
e = message.getCC().elements();
167       while (e.hasMoreElements())
168       {
169         writer.print("RCPT TO: ");
170         writer.print((String JavaDoc)e.nextElement());
171         writer.print(CRLF);
172         writer.flush();
173
174         line = reader.readLine();
175         if (!line.startsWith("2"))
176           throw new MailException(MessageFormat.format(UR, new Object JavaDoc[] { line }));
177       }
178
179       // add recipients ("BCC" list)
180
e = message.getBCC().elements();
181       while (e.hasMoreElements())
182       {
183         writer.print("RCPT TO: ");
184         writer.print((String JavaDoc)e.nextElement());
185         writer.print(CRLF);
186         writer.flush();
187
188         line = reader.readLine();
189         if (!line.startsWith("2"))
190           throw new MailException(MessageFormat.format(UR, new Object JavaDoc[] { line }));
191       }
192
193       Object JavaDoc body = message.getBody();
194
195       writer.print("DATA");
196       writer.print(CRLF);
197       writer.flush();
198       line = reader.readLine();
199       if (!line.startsWith("3"))
200         throw new MailException(MessageFormat.format(UR, new Object JavaDoc[] { line }));
201
202       writer.print("To: ");
203       e = message.getTo().elements();
204       while (e.hasMoreElements())
205       {
206         writer.print((String JavaDoc)e.nextElement());
207         if (e.hasMoreElements())
208           writer.print(", ");
209       }
210       writer.print(CRLF);
211
212       writer.print("CC: ");
213       e = message.getCC().elements();
214       if (e.hasMoreElements())
215       {
216         while (e.hasMoreElements())
217         {
218           writer.print((String JavaDoc)e.nextElement());
219           if (e.hasMoreElements())
220             writer.print(", ");
221         }
222       }
223       writer.print(CRLF);
224
225       String JavaDoc fromName = message.getFromName();
226       if (fromName == null)
227         fromName = "";
228       writer.print("From: ");
229       writer.print(fromName);
230       writer.print(" <");
231       writer.print(message.getFromAddress());
232       writer.print(">");
233       writer.print(CRLF);
234
235       writer.print("Subject: ");
236       writer.print(message.getSubject());
237       writer.print(CRLF);
238
239       writer.print("Date: ");
240       writer.print(dateFormat.format(new Date()));
241       writer.print(CRLF);
242
243       if (body instanceof MIMEMessage)
244       {
245         MIMEMessage mBody = (MIMEMessage)body;
246         writer.print("Content-type: multipart/alternative; boundary=\"");
247         writer.print(mBody.getBoundary());
248         writer.print("\"");
249         writer.print(CRLF);
250       }
251
252       writer.print(CRLF);
253       writer.print(convertText(message.getBody().toString()));
254       writer.print(CRLF);
255       writer.print(CRLF);
256       writer.print(".");
257       writer.print(CRLF);
258       writer.flush();
259
260       line = reader.readLine();
261       if (!line.startsWith("2"))
262         throw new MailException(MessageFormat.format(UR, new Object JavaDoc[] { line }));
263
264       writer.print("QUIT");
265       writer.print(CRLF);
266       writer.flush();
267
268       line = reader.readLine();
269       if (!line.startsWith("2"))
270         throw new MailException(MessageFormat.format(UR, new Object JavaDoc[] { line }));
271     }
272     catch (Exception JavaDoc x)
273     {
274       if (x instanceof IOException)
275         throw (IOException)x;
276       throw new MailException(Syslog.getResourceString(MessageConstants.MAILLOG_TRANSPORT_EXCEPTION_MESSAGE), x);
277     }
278   }
279   
280   private String JavaDoc convertText(String JavaDoc text)
281   {
282       // swaps out end of line markers for CRLF so that
283
// the message will behave right in SMTP mail.
284

285       String JavaDoc endOfLine = System.getProperty("line.separator");
286       if (CRLF.equals(endOfLine))
287       {
288           // no conversion needed, probably windows.
289
return text;
290       }
291       
292       StringBuffer JavaDoc newText = new StringBuffer JavaDoc(text.length() + 512);
293       if (endOfLine.length() == 1)
294       {
295           char eol = endOfLine.charAt(0);
296           char c;
297           for (int i=0; i<text.length(); i++)
298           {
299               c = text.charAt(i);
300               if (c == eol)
301               {
302                   newText.append(CRLF);
303               }
304               else
305               {
306                   newText.append(c);
307               }
308           }
309           return newText.toString();
310       }
311       else
312       {
313           // bah. inefficient. we need to replace
314
// all occurrances of "endOfLine" with "CRLF"
315

316           // this should never happen, though, since every
317
// OS uses a single char EOL except windows,
318
// which already uses CRLF.
319
return text;
320       }
321   }
322 }
323
Popular Tags