package net.sf.colossus.server;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.colossus.webcommon.IGameManager;
import net.sf.colossus.webcommon.IManagedGame;
import net.sf.colossus.webserver.GameManager;
public class ManagedGame implements IManagedGame
{
private static final Logger LOGGER = Logger.getLogger(ManagedGame.class
.getName());
private final String id;
private Registry registry;
private IGameManager gm;
/** True if registration to registry was successful */
private boolean bound = false;
public ManagedGame(String id) throws RemoteException
{
this.id = id;
LOGGER.info("ManagedGame for id " + id + " instantiated.");
try
{
initRegistry();
}
catch (RemoteException e)
{
LOGGER.log(Level.SEVERE, "Can't locate registry!", e);
throw e;
}
}
public String tellStatus() throws RemoteException
{
return "It's real!";
}
public String getRegistryId()
{
return "ManagedGame-" + id;
}
private void initRegistry() throws RemoteException
{
registry = LocateRegistry.getRegistry();
}
public boolean getBound()
{
return bound;
}
/** Register this managed game to rmi registry so that GameManager can
* can find it from there via it's game id.
*
* @return An exception indicating a failure, null if all is ok.
*/
Exception registerToRegistry()
{
Exception gotException = null;
try
{
// NOTE: !!!
// When I use the exportObject without port argument, it returns
// something different and/or the object can NOT be unexported!
// In the API for UnicastRemoteObject constructor is defined,
// port zero means anonymous ports; this is NOT specified at the
// exportObject methods, but seems to be the case nevertheless.
// ==> in future, use with port 0 or perhaps in future some
// own defined port?
Remote stub = UnicastRemoteObject.exportObject(this, 0);
registry.bind(getRegistryId(), stub);
bound = true;
LOGGER.info("OK: Registered to registry...");
}
catch (AlreadyBoundException e)
{
gotException = e;
LOGGER.log(Level.SEVERE, "Id " + getRegistryId()
+ "Already bound?", e);
}
catch (RemoteException e)
{
gotException = e;
LOGGER.log(Level.SEVERE, "Id " + getRegistryId()
+ "Remote exception.", e);
}
return gotException;
}
void unregisterFromRegistry() throws AccessException, NotBoundException,
RemoteException
{
registry.unbind(getRegistryId());
UnicastRemoteObject.unexportObject(this, false);
bound = false;
}
/** Register with own GameId-based RegistryId to the GameManager.
*
*/
void registerToGameManager() throws AccessException, NotBoundException,
RemoteException
{
gm = (IGameManager)registry.lookup(GameManager.OBJ_ID);
gm.registerGame(getRegistryId());
}
void unregisterFromGameManager() throws AccessException, RemoteException,
NotBoundException
{
gm.unregisterGame(getRegistryId());
}
/**
* @param args
*/
public static void main(String[] args)
{
Exception gotException = null;
try
{
ManagedGame mg = new ManagedGame("1234");
mg.registerToRegistry();
LOGGER.info("Now registering game to manager...");
mg.registerToGameManager();
LOGGER.info("Sleeping 7 seconds...");
sleepFor(7000);
LOGGER.info("Now UNregistering from game manager...");
mg.unregisterFromGameManager();
LOGGER.info("Now UNregistering from registry...");
mg.unregisterFromRegistry();
}
catch (AccessException e)
{
gotException = e;
}
catch (NotBoundException e)
{
gotException = e;
}
catch (RemoteException e)
{
gotException = e;
}
if (gotException != null)
{
LOGGER.log(Level.SEVERE, "main: exception " + gotException);
System.exit(1);
}
System.out.println("OK, main() ends now.");
}
// Helper for main()
private static void sleepFor(long millis)
{
try
{
Thread.sleep(millis);
}
catch (InterruptedException e)
{
LOGGER.log(Level.FINEST,
"InterruptException caught... ignoring it...");
}
}
}