Source code: com/xpn/xwiki/test/smtp/SimpleSmtpServer.java
1 /*
2 * Dumbster: a dummy SMTP server.
3 * Copyright (C) 2003, Jason Paul Kitchen
4 * lilnottsman@yahoo.com
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 package com.xpn.xwiki.test.smtp;
21
22 import java.io.*;
23 import java.net.ServerSocket;
24 import java.net.Socket;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28
29 /**
30 * Dummy SMTP server for testing purposes.
31 */
32 public class SimpleSmtpServer implements Runnable {
33 /** Stores all of the email received since this instance started up. */
34 private List receivedMail;
35
36 /** SMTP uses port 25. */
37 public static final int SMTP_PORT = 225;
38
39 /** Indicates whether this server is stopped or not. */
40 private volatile boolean stopped = true;
41
42 /** Indicates if a stop request has been sent to this server. */
43 private volatile boolean doStop = false;
44
45 /**
46 * Constructor.
47 */
48 public SimpleSmtpServer() {
49 receivedMail = new ArrayList();
50 }
51
52 /**
53 * Main loop of the SMTP server.
54 */
55 public void run() {
56 stopped = false;
57 ServerSocket serverSocket = null;
58 try {
59 serverSocket = new ServerSocket(SMTP_PORT);
60 serverSocket.setSoTimeout(500); // Block for maximum of 1.5 seconds
61
62 // Server infinite loop
63 while(!doStop) {
64 Socket socket = null;
65 try {
66 socket = serverSocket.accept();
67 } catch(InterruptedIOException iioe) {
68 if (socket != null) { socket.close(); }
69 continue; // Non-blocking socket timeout occurred: try accept() again
70 }
71
72 // Get the input and output streams
73 BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
74 PrintWriter out = new PrintWriter(socket.getOutputStream());
75
76 // Initialize the state machine
77 SmtpState smtpState = SmtpState.CONNECT;
78 SmtpRequest smtpRequest = new SmtpRequest(SmtpActionType.CONNECT, "", smtpState);
79
80 // Execute the connection request
81 SmtpResponse smtpResponse = smtpRequest.execute();
82
83 // Send initial response
84 sendResponse(out, smtpResponse);
85 smtpState = smtpResponse.getNextState();
86
87 SmtpMessage msg = new SmtpMessage();
88
89 while(smtpState != SmtpState.CONNECT) {
90 String line = input.readLine();
91
92 if (line == null) {
93 break;
94 }
95 // Create request from client input and current state
96 SmtpRequest request = SmtpRequest.createRequest(line, smtpState);
97 // Execute request and create response object
98 SmtpResponse response = request.execute();
99 // Move to next internal state
100 smtpState = response.getNextState();
101 // Send reponse to client
102 sendResponse(out, response);
103
104 // Store input in message
105 msg.store(response, request.getParams());
106 }
107
108 receivedMail.add(msg);
109 socket.close();
110 }
111 } catch (Exception e) {
112 // e.printStackTrace();
113 } finally {
114 if (serverSocket != null) {
115 try {
116 serverSocket.close();
117 } catch (IOException e) {
118 e.printStackTrace();
119 }
120 }
121 }
122 stopped = true;
123 }
124
125 /**
126 * Send response to client.
127 * @param out socket output stream
128 * @param smtpResponse response object
129 */
130 private void sendResponse(PrintWriter out, SmtpResponse smtpResponse) {
131 if (smtpResponse.getCode() > 0) {
132 out.print(smtpResponse.getCode()+" "+smtpResponse.getMessage()+"\r\n");
133 out.flush();
134 }
135 }
136
137 /**
138 * Get email received by this instance since start up.
139 * @return List of String
140 */
141 public Iterator getReceivedEmail() {
142 return receivedMail.iterator();
143 }
144
145 /**
146 * Get the number of messages received.
147 * @return size of received email list
148 */
149 public int getReceievedEmailSize() {
150 return receivedMail.size();
151 }
152
153 /**
154 * Forces the server to stop after processing the current request.
155 */
156 public void stop() {
157 doStop = true;
158 while(!isStopped()) {} // Wait for email server to stop
159 }
160
161 /**
162 * Indicates whether this server is stopped or not.
163 * @return true iff this server is stopped
164 */
165 public boolean isStopped() {
166 return stopped;
167 }
168
169 /**
170 * Creates an instance of SimpleSmtpServer and starts it.
171 * @return a reference to the SMTP server
172 */
173 public static SimpleSmtpServer start() {
174 SimpleSmtpServer server = new SimpleSmtpServer();
175 Thread t = new Thread(server);
176 t.start();
177 return server;
178 }
179
180 }