Source code: org/relayirc/chatengine/Channel.java
1
2 /*
3 * FILE: Channel.java
4 *
5 * The contents of this file are subject to the Mozilla Public License
6 * Version 1.0 (the "License"); you may not use this file except in
7 * compliance with the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS"
11 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
12 * License for the specific language governing rights and limitations
13 * under the License.
14 *
15 * The Original Code is Relay IRC chat client.
16 *
17 * The Initial Developer of the Original Code is David M. Johnson.
18 * Portions created by David M. Johnson are Copyright (C) 1998.
19 * All Rights Reserved.
20 *
21 * Contributor(s): No contributors to this file.
22 */
23 package org.relayirc.chatengine;
24 import org.relayirc.util.*;
25
26 import java.io.*;
27 import java.util.*;
28 import java.beans.*;
29
30 ///////////////////////////////////////////////////////////////////////////
31 /**
32 * An IRC channel class that includes methods for joining, parting,
33 * kicking, banning, adding/removing channel listeners and property
34 * change support.
35 * @author David M. Johnson
36 */
37 public class Channel implements Serializable {
38
39 private transient IChatEngine _engine = null;
40 private transient Vector _listeners = new Vector();
41 private transient boolean _isConnected = false;
42 private String _name = null;
43 private String _topic = new String();
44 private int _userCount = 0;
45 static final long serialVersionUID = 2529627895164114595L;
46
47 private PropertyChangeSupport _propChangeSupport = null;
48
49 /** For internal chat engine use only. */
50 private _ChannelMux _mux = new _ChannelMux();
51
52 //------------------------------------------------------------------
53 /** Construct channel with name alone. */
54 public Channel(String name) {
55 _name = name;
56 _propChangeSupport = new PropertyChangeSupport(this);
57 }
58 //------------------------------------------------------------------
59 /** Construct channel with chat engine. */
60 public Channel(String name, IChatEngine engine) {
61 this(name);
62 _engine = engine;
63 }
64 //------------------------------------------------------------------
65 /** Channel with name, topic, user count and a chat engine. */
66 public Channel(String name, String topic, int ucount, IChatEngine engine) {
67 this(name);
68 _topic = topic;
69 _userCount = ucount;
70 _engine = engine;
71 }
72 //==================================================================
73 //
74 // Thread safe notification architecture
75 //
76 interface _ChannelEventNotifier {
77 public void notify(ChannelListener listener);
78 }
79 private synchronized void notifyListeners(_ChannelEventNotifier notifier) {
80 for (int i=0; i<_listeners.size(); i++) {
81 ChannelListener listener = (ChannelListener)_listeners.elementAt(i);
82 notifier.notify(listener);
83 }
84 }
85 /** Channel listener support. */
86 public synchronized void addChannelListener(ChannelListener listener) {
87 _listeners.addElement(listener);
88 }
89 /** Channel listener support. */
90 public synchronized void removeChannelListener(ChannelListener listener) {
91 _listeners.removeElement(listener);
92 }
93 //==================================================================
94 /** Property change support. */
95 public void addPropertyChangeListener(PropertyChangeListener listener) {
96 _propChangeSupport.addPropertyChangeListener(listener);
97 }
98 //------------------------------------------------------------------
99 /** Property change support. */
100 public void removePropertyChangeListener(PropertyChangeListener listener) {
101 _propChangeSupport.removePropertyChangeListener(listener);
102 }
103 //------------------------------------------------------------------
104 // Setters and getters...
105
106 /** True if channel is connected/joined. */
107 public boolean isConnected() {
108 return _isConnected;
109 }
110 /** Set connection status. */
111 public void setConnected(boolean value) {
112 _isConnected = value;
113 }
114 //------------------------------------------------------------------
115 /** Get the channel's chat engine, which may be null. */
116 public IChatEngine getChatEngine() {
117 return _engine;
118 }
119 //------------------------------------------------------------------
120 /** Get channel's IRCConnectionListener, for internal use only. */
121 IRCConnectionListener getChannelMux() {
122 if (_mux == null) {
123 _mux = new _ChannelMux();
124 }
125 return _mux;
126 }
127 //------------------------------------------------------------------
128 /** Connect/join this channel, does nothing if channel has no chat engine. */
129 public void connect() {
130 if (_engine != null) {
131 setConnected(true);
132 _engine.sendJoin(this);
133
134 final ChannelEvent event = new ChannelEvent(this);
135 notifyListeners(new _ChannelEventNotifier() {
136 public void notify(ChannelListener listener)
137 {listener.onConnect(event);}
138 });
139 }
140 }
141 //------------------------------------------------------------------
142 /** Disconnect/part this channel, does nothing if channel has no chat engine. */
143 public void disconnect() {
144 if (_engine != null) {
145 _engine.sendPart(this);
146 setConnected(false);
147
148 final ChannelEvent event = new ChannelEvent(this);
149 notifyListeners(new _ChannelEventNotifier() {
150 public void notify(ChannelListener listener)
151 {listener.onDisconnect(event);}
152 });
153 }
154 }
155 //------------------------------------------------------------------
156 /** Get name of channel (e.g. "#java" or "#raleigh" */
157 public String getName() {
158 return _name;
159 }
160 //------------------------------------------------------------------
161 /**
162 * Set the chat engine to be used by this view. And: use that chat
163 * engine to create a new chat view for this channel.
164 */
165 public void setChatEngine(IChatEngine engine) {
166 _engine = engine;
167 }
168 //------------------------------------------------------------------
169 /**
170 * Set channel name, with property change support. Property
171 * change event will include new and old values.
172 */
173 public void setName(String name) {
174 String old = _name;
175 _name = name;
176 _propChangeSupport.firePropertyChange("Name",old,_name);
177 }
178 //------------------------------------------------------------------
179 /** Get channe's topic. */
180 public String getTopic() {
181 return _topic;
182 }
183 //------------------------------------------------------------------
184 /**
185 * Set channel topic, with property change support. Property
186 * change event will include new and old values.
187 */
188 public void setTopic(String topic) {
189 String old = _topic;
190 _topic = topic;
191 _propChangeSupport.firePropertyChange("Topic",old,_topic);
192 }
193 //------------------------------------------------------------------
194 /** Number of users currently on channel. */
195 public int getUserCount() {
196 return _userCount;
197 }
198 //------------------------------------------------------------------
199 /**
200 * Set channel user count, with property change support. Property change
201 * event will include new and old values as java.lang.Integer objects.
202 */
203 public void setUserCount(int count) {
204 int old = _userCount;
205 _userCount = count;
206 _propChangeSupport.firePropertyChange("UserCount",
207 new Integer(old),new Integer(_userCount));
208 }
209 //------------------------------------------------------------------
210 /** String representation is channel name. */
211 public String toString() {
212 return _name;
213 }
214 //------------------------------------------------------------------
215 /** Request that this channel be activated, given-focus or
216 * brought-to-front. */
217 public void activate() {
218 final ChannelEvent event = new ChannelEvent(this);
219 notifyListeners(new _ChannelEventNotifier() {
220 public void notify(ChannelListener listener) {
221 listener.onActivation(event);
222 }
223 });
224 }
225 //-------------------------------------------------------------------
226 private void readObject(java.io.ObjectInputStream in)
227 throws IOException, ClassNotFoundException {
228
229 try {in.defaultReadObject();}
230 catch (NotActiveException e) {e.printStackTrace();}
231 _propChangeSupport = new PropertyChangeSupport(this);
232 _listeners = new Vector();
233 }
234 //------------------------------------------------------------------
235 /** Send an action to this channel. */
236 public void sendAction(String msg) {
237 _engine.sendMessage("\001ACTION "+msg+"\001",_name);
238 }
239 //------------------------------------------------------------------
240 /** Ban a user from this channel. */
241 public void sendBan(String nick) {
242 _engine.sendCommand("MODE "+_name+" +b "+nick);
243 }
244 //------------------------------------------------------------------
245 /** Send an arbitrary command to the chat server. */
246 public void sendCommand(String cmd) {
247 _engine.sendCommand(cmd);
248 }
249 //------------------------------------------------------------------
250 /** Take operator rights from a user. */
251 public void sendDeop(String nick) {
252 _engine.sendCommand("MODE "+_name+" -o "+nick);
253 }
254 //------------------------------------------------------------------
255 /** Join this channel, requires a chat engine. Before you call
256 * this method, make sure you have set the chat engine for this
257 * channel. */
258 public synchronized void sendJoin() {
259 if (!_isConnected) {
260 _isConnected = true;
261 _engine.sendJoin(this);
262 }
263 }
264 //------------------------------------------------------------------
265 /** Kick a user from the channel. */
266 public void sendKick(String nick) {
267 _engine.sendCommand("KICK "+_name+" "+nick);
268 }
269 //------------------------------------------------------------------
270 /** Send private message to server.
271 * @deprecated Use Channel.privMsg() instead. */
272 public void sendMessage(String str) {
273 _engine.sendMessage(str,_name);
274 }
275 //------------------------------------------------------------------
276 /** Give operator rights to a user. */
277 public void sendOp(String nick) {
278 _engine.sendCommand("MODE "+_name+" +o "+nick);
279 }
280 //------------------------------------------------------------------
281 /** Part (leave) this channel. */
282 public void sendPart() {
283 _engine.sendPart(_name);
284 _isConnected = false;
285
286 final ChannelEvent event = new ChannelEvent(this);
287 notifyListeners(new _ChannelEventNotifier() {
288 public void notify(ChannelListener listener) {
289 listener.onDisconnect(event);
290 }
291 });
292 }
293 //------------------------------------------------------------------
294 /** Request version information for a user. */
295 public void sendVersion(String nick) {
296 _engine.sendVersion(nick);
297 }
298
299 //////////////////////////////////////////////////////////////////////
300
301 private class _ChannelMux extends IRCConnectionAdapter {
302
303 //------------------------------------------------------------------
304 public void onAction(String user, String channel, String txt) {
305
306 final ChannelEvent event = new ChannelEvent(Channel.this,txt);
307 notifyListeners(new _ChannelEventNotifier() {
308 public void notify(ChannelListener listener)
309 {listener.onAction(event);}
310 });
311 }
312 //------------------------------------------------------------------
313 public void onBan(String banned, String chan, String banner) {
314
315 final ChannelEvent event = new ChannelEvent(
316 Channel.this,banner,"",banned,"","");
317
318 notifyListeners(new _ChannelEventNotifier() {
319 public void notify(ChannelListener listener)
320 {listener.onBan(event);}
321 });
322
323 // Was it something I said?
324 if (banned.equals(_engine.getNick())) {
325 _engine.fireStatusEvent("\nYou were banned from "+_name+"\n");
326 disconnect();
327 }
328 }
329 //------------------------------------------------------------------
330 public void onDisconnect() {
331 }
332 //------------------------------------------------------------------
333 public void onJoin(String user, String nick, String chan, boolean create)
334 {
335 final ChannelEvent event =
336 new ChannelEvent(Channel.this,nick,user,"");
337
338 notifyListeners(new _ChannelEventNotifier() {
339 public void notify(ChannelListener listener)
340 {listener.onJoin(event);}
341 });
342 }
343 //------------------------------------------------------------------
344 public void onJoins(String users, String chans) {
345
346 final ChannelEvent event = new ChannelEvent(Channel.this,users);
347 notifyListeners(new _ChannelEventNotifier() {
348 public void notify(ChannelListener listener)
349 {listener.onJoins(event);}
350 });
351 }
352 //------------------------------------------------------------------
353 public void onKick(String kicked, String chan, String kicker, String txt)
354 {
355
356 final ChannelEvent event
357 = new ChannelEvent(Channel.this,kicker,"",kicked,"",txt);
358
359 notifyListeners(new _ChannelEventNotifier() {
360 public void notify(ChannelListener listener)
361 {listener.onAction(event);}
362 });
363
364 // Was it something I said?
365 if (kicked.equals(_engine.getNick())) {
366 _engine.fireStatusEvent("\nYou were kicked from "
367 +_name+"("+(String)event.getValue()+")\n");
368 disconnect();
369 }
370 }
371 //------------------------------------------------------------------
372 public void onTopic(String channel, String txt) {
373 setTopic(txt);
374 }
375 //------------------------------------------------------------------
376 public void onMessage(String txt) {
377 }
378 //------------------------------------------------------------------
379 public void onPrivateMessage(String orgnick, String chan, String txt) {
380
381 final ChannelEvent event =
382 new ChannelEvent(Channel.this,orgnick,"",txt);
383
384 notifyListeners(new _ChannelEventNotifier() {
385 public void notify(ChannelListener listener)
386 {listener.onMessage(event);}
387 });
388 }
389 //------------------------------------------------------------------
390 public void onNick(String user, String oldnick, String newnick) {
391
392 final ChannelEvent event =
393 new ChannelEvent(Channel.this,oldnick,user,newnick);
394
395 notifyListeners(new _ChannelEventNotifier() {
396 public void notify(ChannelListener listener)
397 {listener.onNick(event);}
398 });
399 }
400 //------------------------------------------------------------------
401 public void onPart(String user, String nick, String chan) {
402
403 final ChannelEvent event =
404 new ChannelEvent(Channel.this,nick,user,"");
405
406 notifyListeners(new _ChannelEventNotifier() {
407 public void notify(ChannelListener listener)
408 {listener.onPart(event);}
409 });
410 }
411 //------------------------------------------------------------------
412 public void onOp(String oper, String chan, String oped) {
413
414 final ChannelEvent event =
415 new ChannelEvent(Channel.this,oper,"",oped,"","");
416
417 notifyListeners(new _ChannelEventNotifier() {
418 public void notify(ChannelListener listener)
419 {listener.onOp(event);}
420 });
421 }
422 //------------------------------------------------------------------
423 public void onQuit(String user, String nick, String txt) {
424
425 final ChannelEvent event = new ChannelEvent(Channel.this,nick,"",txt);
426 notifyListeners(new _ChannelEventNotifier() {
427 public void notify(ChannelListener listener)
428 {listener.onQuit(event);}
429 });
430 }
431 }
432 }
433