1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.cb.jset.server;
21
22 import org.apache.log4j.Logger;
23
24 import java.rmi.RemoteException;
25 import java.rmi.server.UnicastRemoteObject;
26 import java.util.Vector;
27 import java.util.List;
28 import java.net.MalformedURLException;
29
30 /***
31 * Provides accesses to RemoteSetGame implementations.
32 *
33 * @author jerome@coffeebreaks.org - last modified by $LastChangedBy: jerome $
34 * @version $Id: JSetGameServer.java 130 2004-04-15 05:18:07Z jerome $
35 */
36 public class JSetGameServer extends UnicastRemoteObject implements RemoteSetGameServer
37 {
38 private static final Logger LOGGER = Logger.getLogger(JSetGameServer.class);
39
40 /***
41 * A class used to register the different creates games.
42 */
43 private static class Games
44 {
45 private final List _games = new Vector();
46
47 private synchronized void addGame(final RemoteSetGame game)
48 {
49 _games.add(game);
50 }
51
52 /***
53 * @param game
54 * @todo ending remote games should deregister themselves
55 */
56 private synchronized void removeGame(final RemoteSetGame game)
57 {
58 _games.remove(game);
59 }
60
61 private synchronized RemoteSetGame[] getGames()
62 {
63 RemoteSetGame[] games = new RemoteSetGame[_games.size()];
64 games = (RemoteSetGame[]) _games.toArray(games);
65 return games;
66 }
67
68 private synchronized RemoteSetGame getGame(final int id) throws RemoteException
69 {
70 for (int i = 0; i < _games.size(); i++)
71 {
72 final RemoteSetGame game = (RemoteSetGame) _games.get(i);
73 if (game.getID() == id)
74 {
75 return game;
76 }
77 }
78 return null;
79 }
80
81 private void closeGames()
82 {
83 for (int i = 0; i < _games.size(); i++)
84 {
85 final JSetRemoteGameImpl game = (JSetRemoteGameImpl) _games.get(i);
86 game.terminate();
87 }
88 }
89 }
90
91 private final Games _games = new Games();
92
93 /***
94 * Creates a new instance of JSetGameServer.
95 * @throws RemoteException if failed to export object
96 * @todo specify a port
97 */
98 public JSetGameServer() throws RemoteException
99 {
100 addShutdownHook();
101 }
102
103 /***
104 * Create a game with the specified number of players.
105 * @param name the name of the game.
106 * @param nbPlayers the number of players.
107 * @return the new game id
108 * @throws java.rmi.RemoteException upon communication related exception on this remote call
109 */
110 public int createGame(final String name, final int nbPlayers) throws java.rmi.RemoteException
111 {
112
113 final RemoteSetGame game = new JSetRemoteGameImpl(name, nbPlayers);
114 _games.addGame(game);
115 return game.getID();
116 }
117
118 /***
119 * Returns the game identified by the specified id.
120 * @param id the id of the game to return
121 * @return the game if found, or <code>null</code> if none found.
122 * @throws java.rmi.RemoteException upon communication related exception on this remote call
123 */
124 public RemoteSetGame getGame(final int id) throws RemoteException
125 {
126 return _games.getGame(id);
127 }
128
129 /***
130 * @return the different remote games known to this server.
131 * @throws java.rmi.RemoteException upon communication related exception on this remote call
132 */
133 public RemoteSetGame[] getGames() throws RemoteException
134 {
135 return _games.getGames();
136 }
137
138 /***
139 * Make sure all games are closed when this game server dies.
140 */
141 private void addShutdownHook()
142 {
143 /***
144 * a Runnable that close all games.
145 */
146 class JSetShutdownHook implements Runnable
147 {
148 /***
149 * run this runnable
150 */
151 public void run()
152 {
153 LOGGER.debug("ShutdownHook: dying.");
154 _games.closeGames();
155 }
156 }
157 LOGGER.debug("Registering shutdown hook");
158 Runtime.getRuntime().addShutdownHook(new Thread(new JSetShutdownHook()));
159 }
160
161 /***
162 * Starts a JSetGameServer.
163 * @param args no specific argument expected
164 */
165 public static void main(final String[] args)
166 {
167
168
169 org.apache.log4j.PropertyConfigurator.configure("log4j.properties");
170 LOGGER.info("CLASSPATH:" + System.getProperty("java.class.path"));
171 if (System.getSecurityManager() == null)
172 {
173 LOGGER.debug("adding RMISecurityManager");
174 System.setSecurityManager(new java.rmi.RMISecurityManager());
175 }
176 final String name = "//localhost/JSetServer";
177 RemoteSetGameServer server;
178 try
179 {
180 server = new JSetGameServer();
181 }
182 catch (RemoteException e)
183 {
184 LOGGER.error("JSetGameServer exception: failure to export game server object.", e);
185 System.exit(-1);
186 return;
187 }
188 try
189 {
190 java.rmi.Naming.rebind(name, server);
191 LOGGER.info("JSetGameServer bound");
192 }
193 catch (RemoteException e)
194 {
195 LOGGER.error("JSetGameServer exception: couldn't connect to registry."
196 + " Check that the rmiregistry is running on the specified host.", e);
197 System.exit(-1);
198 }
199 catch (MalformedURLException e)
200 {
201 LOGGER.error("JSetGameServer exception: check your config " + name, e);
202 System.exit(-1);
203 }
204 }
205 }