package vicazh.hyperpool.stream.net;
import java.io.*;
import java.net.*;
import java.net.Socket;
import java.text.*;
import java.util.*;
import java.util.logging.*;
import vicazh.hyperpool.*;
import vicazh.hyperpool.stream.Element;
import vicazh.hyperpool.stream.*;
import vicazh.hyperpool.stream.Connection;
/**
* The in service
*
* @author Victor Zhigunov
* @version 0.4.11
*/
public class InService extends Service implements Runnable, InServiceMBean {
public InService() {
}
/**
* @param timeout
* socket timeout
*/
public InService(int timeout) {
this(null, timeout);
}
private String msg;
public int timeout;
/**
* @param msg
* port use message
* @param timeout
* socket timeout
*/
public InService(String msg, int timeout) {
this.timeout = timeout;
this.msg = msg;
}
private ServerSocket serversocket;
private int port;
public void setAttribute(String name, Object value) throws Exception {
if (name.equals(ElementMBean.INIT))
super.setAttribute(name, InetAddress.getLocalHost()
.getHostAddress());
else {
setPort((Integer) value);
super.setAttribute(name, value);
}
if (serversocket == null)
throw (new BindException(MessageFormat.format(msg, port)));
}
public void setPort(int port) throws IOException {
this.port = port;
if (timeout > 0) {
if (serversocket != null)
close();
try {
serversocket = new ServerSocket(port);
new Thread(this).start();
} catch (BindException e) {
if (msg == null)
throw (e);
System.out.println(MessageFormat.format(msg, port) + ": "
+ e.getMessage());
}
}
}
public int getPort() {
return port;
}
private static int MC;
public void run() {
if (MC > 0)
for (int i = 0; i < MC; i++)
new ReTrans().start();
else
try {
while (serversocket != null)
new Trans(serversocket.accept()).start();
} catch (IOException e) {
}
}
private class ReTrans extends Thread {
public void run() {
try {
while (serversocket != null)
new Trans(serversocket.accept()).run();
} catch (IOException e) {
}
}
}
private class Trans extends Thread {
private Socket socket;
public Trans(Socket socket) {
this.socket = socket;
}
public void run() {
try {
if (Start.MU > 0) {
Set<Object> set = new HashSet<Object>();
for (Connection c : getConnections())
set.add(((InConnection) c).address);
Start.logger.finest(getClass().getName() + ":set.size:"
+ set.size());
if (set.size() >= Start.MU)
return;
}
Connection connection = getConnection(socket);
socket.setSoTimeout(timeout);
connection.setServer(new BufferedOutputStream(socket
.getOutputStream()));
connection.setClient(((Element) getElement()).get(connection
.getServer()));
add(connection);
Transfer.run(new BufferedInputStream(socket.getInputStream()),
connection.getClient());
} catch (BreakException e) {
} catch (Exception e) {
Start.logger.log(Level.SEVERE, e.getMessage(), e);
} finally {
try {
socket.close();
} catch (Exception ex) {
}
}
}
}
protected Connection getConnection(Socket socket) {
return new InConnection(this, socket);
}
public void stop() throws Exception {
close();
super.stop();
}
private void close() throws IOException {
try {
serversocket.close();
} catch (Exception e) {
}
serversocket = null;
while (getConnections().size() > 0)
getConnections().get(0).getClient().close();
}
}