package mireka.pop;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import mireka.login.LoginSpecification;
import mireka.pop.store.MaildropRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* PopServer contains configuration information and lifecycle management for the
* POP3 service.
*/
public class PopServer {
/** Host name used if we can't find one */
private final static String UNKNOWN_HOSTNAME = "localhost";
private final Logger logger = LoggerFactory.getLogger(PopServer.class);
/**
* The address to which the listening socket will bind. It is stored as a
* String instead of InetAddress, so it could be configured using CanDI.
* Null means all interfaces.
*/
private String bindAddress = null;
private int port = 110;
private int maximumConnections = 100;
private TlsConfiguration tlsConfiguration = new PrivateTlsConfiguration();
/**
* The host name that will be reported to POP clients
*/
private String hostName;
private ServerThread serverThread;
private LoginSpecification loginSpecification;
private PrincipalMaildropTable principalMaildropTable;
private MaildropRepository maildropRepository;
public PopServer() {
try {
this.hostName = InetAddress.getLocalHost().getCanonicalHostName();
} catch (UnknownHostException e) {
this.hostName = UNKNOWN_HOSTNAME;
}
}
@PostConstruct
public void start() {
logger.info("Starting POP server {}...", getName());
if (serverThread != null)
throw new IllegalStateException("POP server already started");
ServerSocket serverSocket;
try {
serverSocket = createServerSocket();
} catch (Exception e) {
throw new RuntimeException(e);
}
serverThread = new ServerThread(serverSocket, this);
serverThread.start();
}
private ServerSocket createServerSocket() throws IOException {
InetSocketAddress isa;
if (this.bindAddress == null) {
isa = new InetSocketAddress(this.port);
} else {
isa = new InetSocketAddress(this.bindAddress, this.port);
}
ServerSocket serverSocket = new ServerSocket();
// http://java.sun.com/j2se/1.5.0/docs/api/java/net/ServerSocket.html#setReuseAddress(boolean)
serverSocket.setReuseAddress(true);
serverSocket.bind(isa, 0);
return serverSocket;
}
@PreDestroy
public void shutdown() {
logger.info("Stopping POP3 service {}", getName());
serverThread.shutdown();
logger.info("POP3 service {} stopped", getName());
}
/**
* @return the name used in log messages to refer to this server instance
*/
private String getName() {
return getDisplayableLocalSocketAddress();
}
public String getDisplayableLocalSocketAddress() {
return (bindAddress == null ? "*" : bindAddress) + ":" + port;
}
/**
* @x.category GETSET
*/
public String getBindAddress() {
return bindAddress;
}
/**
* @x.category GETSET
*/
public void setBindAddress(String bindAddress) {
this.bindAddress = bindAddress;
}
/**
* @x.category GETSET
*/
public int getPort() {
return port;
}
/**
* @x.category GETSET
*/
public void setPort(int port) {
this.port = port;
}
/**
* @x.category GETSET
*/
public int getMaximumConnections() {
return maximumConnections;
}
/**
* @x.category GETSET
*/
public void setMaximumConnections(int maximumConnections) {
this.maximumConnections = maximumConnections;
}
/** @return the host name that will be reported to SMTP clients */
public String getHostName() {
if (this.hostName == null)
return UNKNOWN_HOSTNAME;
else
return this.hostName;
}
/** The host name that will be reported to SMTP clients */
public void setHostName(String hostName) {
this.hostName = hostName;
}
/**
* @x.category GETSET
*/
public void setLoginSpecification(LoginSpecification loginSpecification) {
this.loginSpecification = loginSpecification;
}
/**
* @x.category GETSET
*/
public LoginSpecification getLoginSpecification() {
return loginSpecification;
}
/**
* @x.category GETSET
*/
public MaildropRepository getMaildropRepository() {
return maildropRepository;
}
/**
* @x.category GETSET
*/
public void setMaildropRepository(MaildropRepository maildropRepository) {
this.maildropRepository = maildropRepository;
}
/**
* @x.category GETSET
*/
public PrincipalMaildropTable getPrincipalMaildropTable() {
return principalMaildropTable;
}
/**
* @x.category GETSET
*/
public void setPrincipalMaildropTable(
PrincipalMaildropTable principalMaildropTable) {
this.principalMaildropTable = principalMaildropTable;
}
/**
* @x.category GETSET
*/
public void setTlsConfiguration(TlsConfiguration tlsExtension) {
this.tlsConfiguration = tlsExtension;
}
/**
* @x.category GETSET
*/
public TlsConfiguration getTlsConfiguration() {
return tlsConfiguration;
}
}