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 import org.cb.jset.SetGameConnection;
24 import org.cb.jset.JSetGameImpl;
25 import org.cb.jset.CardSet;
26 import org.cb.jset.MatchingException;
27 import org.cb.jset.SetGamePlayer;
28 import org.cb.jset.CardProperties;
29
30 import java.rmi.RemoteException;
31 import java.rmi.server.UnicastRemoteObject;
32 import java.io.Serializable;
33
34 /***
35 * An implementation of a remote Game.
36 * <p>
37 * Contains several inner classes that act as wrappers, allowing to transparently use remote implementations locally.
38 *
39 * @author jerome@coffeebreaks.org - last modified by $LastChangedBy: jerome $
40 * @version $Id: JSetRemoteGameImpl.java 130 2004-04-15 05:18:07Z jerome $
41 */
42 public class JSetRemoteGameImpl extends UnicastRemoteObject implements RemoteSetGame
43 {
44 private final Logger _logger = Logger.getLogger(this.getClass().getName());
45
46 private final JSetGameImpl _game;
47
48 /***
49 * Constructs a remote game instance given the specified name and number of players.
50 * @param name
51 * @param nbPlayers
52 * @throws java.rmi.RemoteException upon communication related exception on this remote call
53 */
54 JSetRemoteGameImpl(final String name, final int nbPlayers) throws RemoteException
55 {
56 super();
57 _game = new JSetGameImpl(name, nbPlayers);
58 init();
59 }
60
61 /***
62 * A remote Game connection that effectively wrapps a local one.
63 */
64 static class LocalConnectionWrapper extends UnicastRemoteObject implements Serializable, RemoteSetGameConnection
65 {
66 private final transient SetGameConnection _localConnection;
67
68 /***
69 * Constructs an instance of <code>LocalConnectionWrapper</code>
70 * @param localConnection
71 * @throws java.rmi.RemoteException upon communication related exception on this remote call
72 */
73 public LocalConnectionWrapper(final SetGameConnection localConnection) throws RemoteException
74 {
75 _localConnection = localConnection;
76 }
77
78 /***
79 * Used by a registered player to try to match a set of set.
80 * @param set the set to try to match.
81 * @throws MatchingException if the set doesn't match or if a card is not on the board.
82 * @see org.cb.jset.SetGameConnection#matchSet(org.cb.jset.CardSet)
83 */
84 public void matchSet(final CardSet set) throws MatchingException
85 {
86 _localConnection.matchSet(set);
87 }
88
89 /***
90 * Close the game connection, effectively leaving the game.
91 * @see org.cb.jset.SetGameConnection#close()
92 */
93 public void close()
94 {
95 _localConnection.close();
96 }
97
98 /***
99 * Say wether the game connection is closed or not.
100 * @return <code>true</code> if the connection is closed, <code>false</code> otherwise.
101 * @see org.cb.jset.SetGameConnection#isClosed()
102 */
103 public boolean isClosed()
104 {
105 return _localConnection.isClosed();
106 }
107 }
108
109 /***
110 * Implementation of a player for a remote game.
111 * Effectively wraps a {@link RemoteSetGamePlayer}.
112 */
113 static class RemotePlayerWrapper implements SetGamePlayer
114 {
115 private final RemoteSetGamePlayer _remotePlayer;
116
117
118
119 /***
120 * Constructs an instance using the specified remotePlayer.
121 * @param remotePlayer
122 */
123 public RemotePlayerWrapper(final RemoteSetGamePlayer remotePlayer)
124 {
125 _remotePlayer = remotePlayer;
126 }
127
128 private void treatConnectionProblem(final RemoteException e)
129 {
130
131
132 throw new IllegalStateException("Failure to make a remote call... " + e.getMessage());
133 }
134
135 /***
136 * @return the name of the player.
137 */
138 public String getName()
139 {
140 try
141 {
142 return _remotePlayer.getName();
143 }
144 catch (RemoteException e)
145 {
146 treatConnectionProblem(e);
147 }
148 return "";
149 }
150
151 /***
152 * Called by a game when the player should be blocked.
153 * @see #isBlocked()
154 */
155 public void block()
156 {
157 try
158 {
159 _remotePlayer.block();
160 }
161 catch (RemoteException e)
162 {
163 treatConnectionProblem(e);
164 }
165 }
166
167 /***
168 * Called by a game when the player should be unblocked.
169 * @see #isBlocked()
170 */
171 public void unblock()
172 {
173 try
174 {
175 _remotePlayer.unblock();
176 }
177 catch (RemoteException e)
178 {
179 treatConnectionProblem(e);
180 }
181 }
182
183 /***
184 * A blocked player doesn't have the right to play.
185 * @return <code>true</code> is the player is blocked, <code>false</code> otherwise.
186 */
187 public boolean isBlocked()
188 {
189 try
190 {
191 return _remotePlayer.isBlocked();
192 }
193 catch (RemoteException e)
194 {
195 treatConnectionProblem(e);
196 }
197 return false;
198 }
199
200
201 /***
202 * Called to notify a disconnection from a game.
203 */
204 public void disconnect()
205 {
206 try
207 {
208 _remotePlayer.disconnect();
209 }
210 catch (RemoteException e)
211 {
212 treatConnectionProblem(e);
213 }
214 }
215
216 /***
217 * Called to notify that the specified cards were added to the board.
218 * @param cards the cards that were added to the board.
219 */
220 public void cardsAdded(final CardProperties[] cards)
221 {
222 try
223 {
224 _remotePlayer.cardsAdded(cards);
225 }
226 catch (RemoteException e)
227 {
228 treatConnectionProblem(e);
229 }
230 }
231
232 /***
233 * Called to notify that the specified set was removed from the board.
234 * The set should be a {@link CardSet#isMatching() matching set}.
235 * @param set the set that was removed from the board
236 */
237 public void setRemoved(final CardSet set)
238 {
239 try
240 {
241 _remotePlayer.setRemoved(set);
242 }
243 catch (RemoteException e)
244 {
245 treatConnectionProblem(e);
246 }
247 }
248 }
249
250 void init()
251 {
252 _game.start();
253 }
254
255 void terminate()
256 {
257 _game.terminate();
258 }
259
260 /***
261 * @inheritDoc
262 */
263 public String getName() throws RemoteException
264 {
265 return _game.getName();
266 }
267
268 /***
269 * @inheritDoc
270 */
271 public int getCurrentNbPlayers() throws RemoteException
272 {
273 return _game.getCurrentNbPlayers();
274 }
275
276 /***
277 * @inheritDoc
278 */
279 public int getMaxNbPlayers() throws RemoteException
280 {
281 return _game.getMaxNbPlayers();
282 }
283
284 /***
285 * @inheritDoc
286 */
287 public RemoteSetGameConnection connect(final RemoteSetGamePlayer player) throws RemoteException
288 {
289 if (_logger.isInfoEnabled())
290 {
291 _logger.info("Connecting player:" + player.getName() + ">");
292 }
293 final SetGameConnection conn;
294 synchronized (this)
295 {
296 final SetGamePlayer playerWrapper = new RemotePlayerWrapper(player);
297 conn = _game.connect(playerWrapper);
298 }
299 return new LocalConnectionWrapper(conn);
300 }
301
302 /***
303 * @inheritDoc
304 */
305 public int getID() throws RemoteException
306 {
307 return _game.getID();
308 }
309 }