KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > chipchat > Room


1 /*
2  * Created on 2003. 2. 20.
3  */

4 package chipchat;
5
6 import java.io.IOException JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Iterator JavaDoc;
9
10 /**
11  * @author Mr. Lee
12  */

13 public final class Room extends Thread JavaDoc {
14     // Room Infomations..
15
/** Chennel */
16     private Channel channel;
17     /** Room id number */
18     private Long JavaDoc roomid;
19     /** The name of room */
20     private String JavaDoc name;
21     /** Maximum number of person in this room */
22     private int maxMan;
23     /** Password */
24     private String JavaDoc passwd;
25     /** Host id number */
26     private int host;
27     /** Users */
28     private HashMap JavaDoc users = new HashMap JavaDoc();
29     /** Administrators */
30     private HashMap JavaDoc admins = new HashMap JavaDoc();
31     /** Message to send. */
32     private Msg msg;
33     /** Is this room finished? */
34     private boolean isFinish = false;
35
36     /** Lock object */
37     private Object JavaDoc msgInputLock = new Object JavaDoc();
38     /** Lock object */
39     private Object JavaDoc msgOutputLock = new Object JavaDoc();
40
41     /**
42      * @param channel Chennel of this room
43      * @param roomid Id number of room
44      * @param name The name of room
45      * @param maxMan The number of maximum person
46      * @param passwd Password
47      * @param host Id number of host
48      */

49     public Room(
50         final Channel channel,
51         final Long JavaDoc roomid,
52         final String JavaDoc name,
53         final int maxMan,
54         final String JavaDoc passwd,
55         final int host) {
56
57         this.channel = channel;
58         this.roomid = roomid;
59         this.name = name;
60         this.maxMan = maxMan;
61         if (passwd != null && passwd.equals("")) {
62             this.passwd = null;
63         } else {
64             this.passwd = passwd;
65         }
66         this.host = host;
67         this.setDaemon(true);
68         this.start();
69     }
70
71     /*
72      * Functions about user.
73      */

74     /**
75      * Set master.
76      * @param master The id of master
77      * @return Id number of new master
78      */

79     int setMaster(final int master) {
80         User user;
81         synchronized (users) {
82             user = (User) users.get(new Integer JavaDoc(master));
83         }
84         if (user != null) {
85             this.host = master;
86             inputAdminInfo();
87             inputAdminChange(user.getUsername());
88             return this.host;
89         } else {
90             return setMaster();
91         }
92
93     }
94     /**
95      * Set master anyone.
96      * @return New id number of master.
97      */

98     int setMaster() {
99         User user;
100
101         synchronized (users) {
102             if (!users.isEmpty()) {
103                 user = (User) users.get(users.keySet().iterator().next());
104             } else {
105                 return host;
106             }
107         }
108
109         host = user.getUserid().intValue();
110         inputAdminInfo();
111         inputAdminChange(user.getUsername());
112
113         return host;
114     }
115
116     /**
117      * Is Full.
118      * @return Is Full?
119      */

120     boolean isFull() {
121         return (maxMan == users.size());
122     }
123
124     /**
125      * Is Empty.
126      * @return Is Empty?
127      */

128     boolean isEmpty() {
129         return (0 == users.size());
130     }
131
132     /**
133      * Insert user into this room.
134      * @param user User
135      * @param passwd Password
136      * @return Error Code, 0 : Ok, -1 : Room is full, -2 : Wrong password.
137      */

138     int enterUser(final User user, final String JavaDoc passwd) {
139         synchronized (users) {
140             // Àοø¼ö °Ë»ç.
141
if (users.size() >= maxMan) {
142                 return -1;
143             }
144             // Password°Ë»ç.
145
if (this.passwd != null
146                 && (!this.passwd.equalsIgnoreCase(passwd))) {
147                 return -2;
148             }
149             users.put(user.getUserid(), user);
150         }
151         channel.setListChanged();
152         inputInfo("GetIn", user.getUserid() + ">" + user.getUsername());
153         inputUserInfo();
154         return 0;
155     }
156
157     /**
158      * Insert administrator into this room.
159      * @param user User
160      * @param passwd Password
161      * @return Error Code, 0 : Ok
162      */

163     int enterAdmin(final User user, final String JavaDoc passwd) {
164         synchronized (admins) {
165             admins.put(user.getUserid(), user);
166         }
167         return 0;
168     }
169
170     /**
171      * Get user out in this room.
172      * @param user User
173      */

174     void exitUser(final User user) {
175         boolean needSetMaster = false;
176         synchronized (users) {
177             if (users.remove(user.getUserid()) == null) {
178                 if (admins.remove(user.getUserid()) == null) {
179                     System.out.println("Error : Userid not Exist in room.");
180                 }
181                 return;
182             }
183             channel.setListChanged();
184             if (users.size() == 0) {
185                 this.maxMan = 0;
186                 this.isFinish = true;
187                 channel.removeRoom(roomid);
188             }
189             if (user.getUserid().intValue() == host) {
190                 needSetMaster = true;
191             }
192         }
193         if (needSetMaster) {
194             setMaster();
195         }
196         inputInfo("GetOut", user.getUsername());
197         inputUserInfo();
198     }
199
200     /*
201      * Functions relativing to message.
202      */

203     /**
204      * Input message.
205      * @param msg Message
206      */

207     void inputMsg(final Msg msg) {
208         synchronized (msgInputLock) {
209             while (this.msg != null && !isFinish) {
210                 try {
211                     msgInputLock.wait(100);
212                 } catch (InterruptedException JavaDoc e) {
213                     e.printStackTrace();
214                 }
215             }
216             this.msg = msg;
217         }
218         synchronized (msgOutputLock) {
219             msgOutputLock.notify();
220         }
221     }
222
223     /**
224      * Input message.
225      * @param to To
226      * @param msg Message
227      * @param writer Writer name
228      */

229     void inputMsg(final int to, final String JavaDoc msg, final String JavaDoc writer) {
230         inputMsg(new Msg(Msg.TYPE_MSG, to, msg, writer));
231     }
232
233     /**
234      * Input custom message.
235      * @param to To
236      * @param msg Message
237      * @param writer Writer name
238      */

239     void inputCustomMsg(final int to, final String JavaDoc msg, final String JavaDoc writer) {
240         inputMsg(new Msg(Msg.TYPE_CUSTOMMSG, to, msg, writer));
241     }
242
243     /**
244      * Input message.
245      * @param msgType Tye of message
246      * @param to To
247      * @param msg Message
248      * @param writer Writer name
249      */

250     void inputMsg(
251         final int msgType,
252         final int to,
253         final String JavaDoc msg,
254         final String JavaDoc writer) {
255         inputMsg(new Msg(msgType, to, msg, writer));
256     }
257
258     /**
259      * Whisper message.
260      * @param from From
261      * @param to To
262      * @param msg Message
263      * @param writer Writer name
264      */

265     void inputWhisper(
266         final int from,
267         final int to,
268         final String JavaDoc msg,
269         final String JavaDoc writer) {
270         if (from == to) {
271             inputError(from, "WSP:SendToMyself");
272             return;
273         }
274         User user = (User) users.get(new Integer JavaDoc(to));
275         if (user == null) {
276             inputError(from, "WSP:NotExistAnother");
277         } else {
278             inputMsg(new Msg(Msg.TYPE_WSPSND, from, msg, user.getUsername()));
279             inputMsg(new Msg(Msg.TYPE_WSPRCV, to, msg, writer));
280         }
281     }
282
283     /**
284      * Input error message.
285      * @param to To
286      * @param msg Message
287      */

288     void inputError(final int to, final String JavaDoc msg) {
289         inputMsg(new Msg(Msg.TYPE_ERROR, to, msg, null));
290     }
291
292     /**
293      * Input room info.
294      */

295     void inputRoomInfo() {
296         int isPasswd = (passwd != null && (!"".equals(passwd))) ? 1 : 0;
297         inputInfo("RoomInfo", maxMan + ">" + isPasswd + ">" + name);
298     }
299
300     /**
301      * Input User List information.
302      */

303     void inputUserInfo() {
304         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
305         synchronized (users) {
306             for (Iterator JavaDoc i = users.keySet().iterator(); i.hasNext();) {
307                 Object JavaDoc key = i.next();
308                 User user = (User) users.get(key);
309                 sb.append(user.getUserid()).append("<").append(
310                     user.getUsername()).append(
311                     ">");
312             }
313         }
314         inputMsg(Msg.TYPE_USERS, -1, sb.toString(), null);
315     }
316
317     /**
318      * Input Administrator information.
319      */

320     void inputAdminInfo() {
321         inputMsg(new Msg(Msg.TYPE_ADMIN, -1, "" + host, null));
322     }
323
324     /**
325      * Input message that administrator is chaged.
326      * @param to To
327      */

328     void inputAdminChange(final String JavaDoc to) {
329         inputMsg(new Msg(Msg.TYPE_ADMINCHANGE, -1, to, null));
330     }
331
332     /**
333      * Input command for someone to keep quiet.
334      * @param from From. Must be administrator.
335      * @param to To
336      */

337     void inputKeepQuiet(final int from, final int to) {
338         if (from == host) {
339             User user = (User) users.get(new Integer JavaDoc(to));
340             if (user == null) {
341                 inputError(host, "KEEPQUIET:NotExistUser");
342             } else {
343                 inputMsg(
344                     new Msg(
345                         Msg.TYPE_KEEPQUIET,
346                         -1,
347                         "" + to,
348                         user.getUsername()));
349             }
350         } else {
351             inputError(from, "YouNotMaster");
352         }
353     }
354
355     /**
356      * Input command for someone to get out.
357      * @param from From
358      * @param to To
359      */

360     void inputKickOut(final int from, final int to) {
361         if (from == host) {
362             User user = (User) users.get(new Integer JavaDoc(to));
363             if (user == null) {
364                 inputError(host, "KICKOUT:NotExistUser");
365             } else {
366                 inputMsg(
367                     new Msg(Msg.TYPE_KICKOUT, -1, "" + to, user.getUsername()));
368             }
369         } else {
370             inputError(from, "YouNotMaster");
371         }
372     }
373
374     /**
375      * Input command that administrator entrust to other.
376      * @param from From
377      * @param to To
378      */

379     void inputEntrust(final int from, final int to) {
380         if (from == host) {
381             User user = (User) users.get(new Integer JavaDoc(to));
382             if (user == null) {
383                 inputError(host, "ENTRUST:NotExistUser");
384             } else {
385                 host = to;
386                 inputAdminInfo();
387                 inputAdminChange(user.getUsername());
388             }
389         } else {
390             inputError(from, "YouNotMaster");
391         }
392     }
393
394     /**
395      * Input some information message.
396      * @param infoName Name of infomation
397      * @param appendMsg Appending message
398      */

399     void inputInfo(final String JavaDoc infoName, final String JavaDoc appendMsg) {
400         inputMsg(new Msg(Msg.TYPE_INFO, -1, appendMsg, infoName));
401     }
402
403     /**
404      * Chage password of this room.
405      * @param from From
406      * @param newPasswd New password
407      */

408     void changePasswd(final int from, final String JavaDoc newPasswd) {
409         if (from == host) {
410             this.passwd = newPasswd;
411             inputRoomInfo();
412             inputInfo("ChangePasswd", "");
413         } else {
414             inputError(from, "YouNotMaster");
415         }
416     }
417
418     /**
419      * Change Room name.
420      * @param from From
421      * @param name Room name
422      */

423     void changeRoomName(final int from, final String JavaDoc name) {
424         if (from == host) {
425             this.name = name;
426             inputRoomInfo();
427             inputInfo("ChangeRoomName", name);
428         } else {
429             inputError(from, "YouNotMaster");
430         }
431     }
432
433     /**
434      * Change maximum number of mem.
435      * @param from From
436      * @param num Number
437      */

438     void changeMaxMan(final int from, final int num) {
439         if (from == host) {
440             this.maxMan = num;
441             inputRoomInfo();
442             inputInfo("ChangeMaxMan", "" + num);
443         } else {
444             inputError(from, "YouNotMaster");
445         }
446     }
447
448     /**
449      * Run function of Thread.
450      */

451     public void run() {
452         // User°¡ µé¾î¿À±â¸¦ ±â´Ù¸°´Ù.
453
synchronized (msgOutputLock) {
454             try {
455                 msgOutputLock.wait(60000);
456             } catch (InterruptedException JavaDoc e) {
457                 e.printStackTrace();
458             }
459         }
460
461         // User°¡ 60ÃÊ µ¿¾È µé¾î¿ÀÁö ¾ÊÀ¸¸é ¹æÀ» Áö¿ò.
462
if (msg == null) {
463             System.out.println(
464                 "This room is timeout. Member does not enter. ["
465                     + this.roomid
466                     + "]:"
467                     + this.name);
468             maxMan = 0;
469             isFinish = true;
470             channel.removeRoom(roomid);
471             return;
472         }
473
474         while (!isFinish) {
475             synchronized (msgOutputLock) {
476                 if (msg != null) {
477                     Msg lmsg = msg;
478                     msg = null;
479                     synchronized (msgInputLock) {
480                         msgInputLock.notify();
481                     }
482                     synchronized (users) {
483                         for (Iterator JavaDoc i = users.keySet().iterator();
484                             i.hasNext();
485                             ) {
486                             Object JavaDoc key = i.next();
487                             User user = (User) users.get(key);
488                             String JavaDoc smsg =
489                                 lmsg.getString(user.getUserid().intValue());
490                             if (smsg != null) {
491                                 try {
492                                     user.getOutputStream().write(
493                                         smsg.getBytes());
494                                     user.getOutputStream().flush();
495                                 } catch (IOException JavaDoc e) {
496                                     e.printStackTrace();
497                                 }
498                             }
499                         }
500                     }
501                     synchronized (admins) {
502                         if (admins.size() > 0) {
503                             Iterator JavaDoc i = admins.keySet().iterator();
504                             while (i.hasNext()) {
505                                 Object JavaDoc key = i.next();
506                                 User user = (User) admins.get(key);
507                                 String JavaDoc smsg = lmsg.getString(-2);
508                                 if (smsg != null) {
509                                     try {
510                                         user.getOutputStream().write(
511                                             smsg.getBytes());
512                                         user.getOutputStream().flush();
513                                     } catch (IOException JavaDoc e) {
514                                         e.printStackTrace();
515                                     }
516                                 }
517                             }
518                         }
519                     }
520                 } else {
521                     try {
522                         msgOutputLock.wait(1000);
523                     } catch (InterruptedException JavaDoc e) {
524                         e.printStackTrace();
525                     }
526                 }
527             }
528         }
529     }
530
531     /**
532      * Getter of maxMan
533      * @return maxMan
534      */

535     public int getMaxMan() {
536         return maxMan;
537     }
538
539     /**
540      * Getter of name
541      * @return name
542      */

543     public String JavaDoc getRoomName() {
544         return name;
545     }
546
547     /**
548      * Getter of passwd
549      * @return passwd
550      */

551     public String JavaDoc getPasswd() {
552         return passwd;
553     }
554
555     /**
556      * Getter of users
557      * @return users
558      */

559     public HashMap JavaDoc getUsers() {
560         return users;
561     }
562
563     /**
564      * Getter of roomid
565      * @return roomid
566      */

567     public Long JavaDoc getRoomid() {
568         return roomid;
569     }
570
571     /**
572      * Getter of roomid
573      * @return master
574      */

575     public int getMaster() {
576         return host;
577     }
578
579 }
580
Popular Tags