package voxo.server.controllers;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.channels.ShutdownChannelGroupException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.EnumSet;
import javax.mail.MessagingException;
import voxo.common.Verbose;
import voxo.common.entities.Packet;
import voxo.common.enums.EnumVerbose;
import voxo.common.packets.ChatPacket;
import voxo.common.packets.ClientRequestPacket;
import voxo.common.packets.LoginPacket;
import voxo.common.packets.RegisterPacket;
import voxo.server.Messages;
import voxo.server.actions.ClientSearchRequestAction;
import voxo.server.actions.ContactAcceptAction;
import voxo.server.actions.ContactAddAction;
import voxo.server.actions.ContactRemoveAction;
import voxo.server.actions.SendEmailAction;
import voxo.server.actions.UserLoginAction;
import voxo.server.actions.UserLogoutAction;
import voxo.server.actions.UserRegisterAction;
import voxo.server.exceptions.RequestException;
import voxo.server.managers.UserManager;
import voxo.server.services.IBatisService;
import voxo.server.threads.HeartBeatThread;
import voxo.server.threads.NetworkReceiver;
import voxo.server.threads.ShutdownHook;
public class ServerController {
private Thread netThread;
private NetworkReceiver nr;
private Thread hbThread;
private HeartBeatThread hb;
private Verbose verbose;
private boolean debug;
public ServerController(String[] args) {
// Init the verbose
ArrayList<String> ala = new ArrayList<String>();
for(String s : args)
ala.add(s);
debug = ala.contains("debug"); //$NON-NLS-1$
this.verbose = new Verbose(ala.contains("gui"), !ala.contains("noconsole"), !ala.contains("nolog")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// Starting
verbose.addConsoleMsg(Messages.getString("ServerController.DBG_InitServerNotice"), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
// Init the SQL connection
try {
IBatisService.init();
if(debug)
verbose.addConsoleMsg(Messages.getString("ServerController.DBG_InitDatabaseNotice"), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
} catch (IOException e) {
this.verbose.addConsoleMsg(e, EnumSet.of(EnumVerbose.ToConsole, EnumVerbose.ToLog));
System.exit(0);
}
// Set everyone offline
try {
UserManager.updateAllUsersOffline();
if(debug)
verbose.addConsoleMsg(Messages.getString("ServerController.DBG_InitOfflineUsersNotice"), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
} catch (SQLException e) {
this.verbose.addConsoleMsg(e, EnumSet.of(EnumVerbose.ToConsole, EnumVerbose.ToLog));
System.exit(0);
}
// Start network thread
this.nr = new NetworkReceiver(this);
this.netThread = new Thread(this.nr, "NetworkReceiverThread"); //$NON-NLS-1$
this.netThread.start();
if(debug)
verbose.addConsoleMsg(Messages.getString("ServerController.DBG_InitNetworkReceiverNotice"), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
// Start heartbeat thread
this.hb = new HeartBeatThread(this);
this.hbThread = new Thread(this.hb, "HeartBeatThread"); //$NON-NLS-1$
this.hbThread.start();
if(debug)
verbose.addConsoleMsg(Messages.getString("ServerController.DBG_InitHeartBeatThreadNotice"), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
// Thread shutdown control
Runtime.getRuntime().addShutdownHook(new ShutdownHook(nr, hb));
if(debug)
verbose.addConsoleMsg(Messages.getString("ServerController.DBG_InitShutdownHookNotice"), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
// Finished init
verbose.addConsoleMsg(Messages.getString("ServerController.DBG_InitServerOnlineNotice"), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
}
public void parsePacket(InetAddress ip, Packet p) {
if(debug)
verbose.addConsoleMsg(String.format(Messages.getString("ServerController.DBG_ReceivedPacket"), p.getP().toString()), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
try {
switch (p.getP()) {
case CLIENT_Login:
new UserLoginAction(ip, (LoginPacket) p.getO());
break;
case CLIENT_Logout:
new UserLogoutAction(ip.getHostAddress(), (String) p.getO());
break;
case CLIENT_Register:
new UserRegisterAction(ip, (RegisterPacket) p.getO());
break;
case CLIENT_AddContact:
new ContactAddAction(ip, (ClientRequestPacket) p.getO());
break;
case CLIENT_ConfirmContact:
new ContactAcceptAction(ip, (ClientRequestPacket) p.getO());
break;
case CLIENT_RemoveContact:
new ContactRemoveAction(ip, (ClientRequestPacket) p.getO());
break;
case CLIENT_SearchRequest:
new ClientSearchRequestAction(ip, (String) p.getO());
break;
case CLIENT_SendEmail:
new SendEmailAction(ip, (ChatPacket) p.getO());
break;
case CLIENT_HeartBeat:
hb.respondBeat(ip.getHostAddress());
break;
default:
this.verbose.addConsoleMsg(Messages.getString("ServerController.ERR_UnknownPacket") + p.toString(), EnumSet.of(EnumVerbose.ToConsole, EnumVerbose.ToLog)); //$NON-NLS-1$
break;
}
} catch (RequestException e) {
this.verbose.addConsoleMsg(e.getError(), EnumSet.of(EnumVerbose.ToConsole));
} catch (MessagingException | IOException | SQLException e) {
this.verbose.addConsoleMsg(e, EnumSet.of(EnumVerbose.ToConsole, EnumVerbose.ToLog));
}
}
public Verbose getVerbose() {
return this.verbose;
}
public void setVerbose(Verbose verbose) {
this.verbose = verbose;
}
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
}