f00f.net.irc.martyr
Class IRCConnection

java.lang.Object
  extended by f00f.net.irc.martyr.IRCConnection

public class IRCConnection
extends java.lang.Object

IRCConnection is the core class for Martyr. IRCConnection manages the socket, giving commands to the server and passing results to the parse engine. It manages passing information out to the application via the command listeners and state listeners. IRCConnection has no IRC intelligence of its own, that is left up to the classes on the command and state listener lists. A number of listeners that do various tasks are provided as part of the framework.

Please read this entirely before using the framework. Or what the heck, try out the example below and see if it works for ya.

States and State Listeners

IRCConnection is always in one of three states. UNCONNECTED, UNREGISTERED or REGISTERED. It keeps a list of listeners that would like to know when a state change occurs. When a state change occurs each listener in the list, in the order they were added, is notified. If a listener early up on the list causes something to happen that changes the state before your listener gets notified, you will be notified of the state change even though the state has changed. You will be notified again of the new state. That is, state change notifications will always be in order, but they may not always reflect the "current" state.

Commands and Command Listeners

IRCConnection also keeps a list of listeners for when a command arrives from the server. When a command arrives, it is first parsed into an object. That object is then passed around to all the listeners, again, in order. Commands can be received and the socket closed before the commands are actually send to the listeners, so beware that even though you receive a command, you may not always be guaranteed to have an open socket to send a response back on. A consumer of the command should never modify the command object. If you try to send a command to a closed socket, IRCConnection will silently ignore your command. Commands should always be received in order by all listeners, even if a listener higher up in the list sends a response to the server which elicits a response back from the server before you've been told of the first command.

Connecting and staying connected

The AutoReconnect class can connect you and will try to stay connected. Using AutoReconnect to connect the first time is recommended, use the go(server,port) method once you are ready to start.

Registration On The Network

The AutoRegister class can register you automatically on the network. Otherwise, registration is left up to the consumer. Registration should occur any time the state changes to UNREGISTERED. The consumer will know this because it has registered some class as a state observer.

Auto Response

Some commands, such as Ping require an automatic response. Commands that fall into this category can be handled by the AutoResponder class. For a list of what commands AutoResponder auto responds to, see the source.

Joining and Staying Joined

You can use the AutoJoin class to join a channel and stay there. AutoJoin will try to re-join if kicked or if the connection is lost and the server re-connects. AutoJoin can be used any time a join is desired. If the server is not connected, it will wait until the server connects. If the server is connected, it will try to join right away.

Example Usage

You will probably want to at least use the AutoRegister and AutoResponder classes. Example:

Note that in the example, the first line is optional. IRCConnection can be called with its default constructor. See note below about why this is done. IRCConnection will instantiate its own ClientState object if you do not provide one.

 ClientState clientState = new MyAppClientState();
 IRCConnection connection = new IRCConnection( clientState );

 // AutoRegister and AutoResponder both add themselves to the
 // appropriate observerables.  Both will remove themselves with the
 // disable() method.
 
 AutoRegister autoReg
   = new AutoRegister( "repp", "bdamm", "Ben Damm", connection );
 AutoReconnect autoRecon = new AutoReconnect( connection );
 AutoResponder autoRes = new AutoResponder( connection );

 // Very important that the objects above get added before the connect.
 // If done otherwise, AutoRegister will throw an
 // IllegalStateException, as AutoRegister can't catch the
 // state switch to UNREGISTERED from UNCONNECTED.

 autoRecon.go( server, port );
 

Client State

The ClientStateMonitor class tells commands to change the client state when they are received. ClientStateMonitor is automatically added to the command queue before any other command, so that you can be guaranteed that the ClientState is updated before any observer sees a command.

So, how does an application know when a channel has been joined, a user has joined a channel we are already on, etc? How does the application get fine-grained access to client state change info? This is a tricky question, and the current solution is to sublcass the clientstate.ClientState and clientstate.Channel classes with your own, overriding the setXxxxXxxx methods. Each method would call super.setXxxXxxx and then proceed to change the application as required.

Startup

IRCConnection starts in the UNCONNECTED state and makes no attempt to connect until the connect(...) method is called.

IRCConnection starts a single thread at construction time. This thread simply waits for events. An event is a disconnection request or an incoming message. Events are dealt with by this thread. If connect is called, a second thread is created to listen for input from the server (InputHandler).

See Also:
A_FAQ, ClientState, AutoRegister, AutoResponder, State

Constructor Summary
IRCConnection()
           
IRCConnection(ClientState clientState)
           
 
Method Summary
 void addCommandObserver(java.util.Observer observer)
           
 void addStateObserver(java.util.Observer observer)
           
 void connect(java.net.Socket customSocket, java.lang.String server)
          This allows the developer to provide a pre-connected socket, ready for use.
 void connect(java.lang.String server, int port)
          Performs a standard connection to the server and port.
 void disconnect()
          Orders the socket to disconnect.
 ClientState getClientState()
           
protected  InCommand getCommandObject(java.lang.String prefix, java.lang.String identifier, java.lang.String params)
          Given the three parts of an IRC command, generates an object to represent that command.
 CommandSender getCommandSender()
           
 CronManager getCronManager()
           
 java.net.InetAddress getLocalAddress()
           
 java.lang.String getLocalhost()
          Deprecated. Pending removal due to unspecified behaviour, use getLocalAddress instead.
 java.lang.String getRemotehost()
           
 State getState()
           
protected  void handleSocketCloseException(java.io.IOException ioe)
           
protected  void handleUnparsableCommand(java.lang.String wholeString, java.lang.Exception e)
           
 void injectCommand(java.lang.String fakeCommand)
          Inserts into the event queue a command that was not directly received from the server.
static java.lang.String[] parseRawString(java.lang.String wholeString)
          Splits a raw IRC command into three parts, the prefix, identifier, and parameters.
 void removeCommandObserver(java.util.Observer observer)
           
 void removeStateObserver(java.util.Observer observer)
           
 void sendCommand(Command command)
          Deprecated. Use sendCommand( OutCommand cmd ) instead.
 void sendCommand(OutCommand command)
          Accepts a command to be sent.
 void setCommandSender(CommandSender sender)
           
 void setDaemon(boolean daemon)
          Sets the daemon status on the threads that IRCConnection creates.
 void setSendDelay(int sleepTime)
          Sets the time in milliseconds we wait after each command is sent.
 void shutdown(long timeout)
          Signal threads to stop, and wait for them to do so.
protected  void startEventThread()
          This method exists so that subclasses may perform operations before the event thread starts, but overriding this method.
 void stop()
          In the event you want to stop martyr, call this.
 java.lang.String toString()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

IRCConnection

public IRCConnection()

IRCConnection

public IRCConnection(ClientState clientState)
Method Detail

startEventThread

protected void startEventThread()
This method exists so that subclasses may perform operations before the event thread starts, but overriding this method.


stop

public void stop()
In the event you want to stop martyr, call this. This asks the event thread to finish the current event, then die.


connect

public void connect(java.lang.String server,
                    int port)
             throws java.io.IOException
Performs a standard connection to the server and port. If we are already connected, this just returns.

Parameters:
server - Server to connect to
port - Port to connect to
Throws:
java.io.IOException - if we could not connect

connect

public void connect(java.net.Socket customSocket,
                    java.lang.String server)
             throws java.io.IOException,
                    java.lang.IllegalStateException
This allows the developer to provide a pre-connected socket, ready for use. This is so that any options that the developer wants to set on the socket can be set. The server parameter is passed in, rather than using the customSocket.getInetAddr() because a DNS lookup may be undesirable. Thus, the canonical server name, whatever that is, should be provided. This is then passed on to the client state.

Parameters:
customSocket - Custom socket that we will connect over
server - Server to connect to
Throws:
java.io.IOException - if we could not connect
java.lang.IllegalStateException - if we are already connected.

disconnect

public void disconnect()

Orders the socket to disconnect. This doesn't actually disconnect, it merely schedules an event to disconnect. This way, pending incoming messages may be processed before a disconnect actually occurs.

No errors are possible from the disconnect. If you try to disconnect an unconnected socket, your disconnect request will be silently ignored.


setDaemon

public void setDaemon(boolean daemon)
Sets the daemon status on the threads that IRCConnection creates. Default is true, that is, new InputHandler threads are daemon threads, although the event thread is always a daemon. The result is that as long as there is an active connection, the program will keep running.

Parameters:
daemon - Set if we are to be treated like a daemon

shutdown

public void shutdown(long timeout)
Signal threads to stop, and wait for them to do so.

Parameters:
timeout - *2 msec to wait at most for stop.

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

addStateObserver

public void addStateObserver(java.util.Observer observer)

removeStateObserver

public void removeStateObserver(java.util.Observer observer)

addCommandObserver

public void addCommandObserver(java.util.Observer observer)

removeCommandObserver

public void removeCommandObserver(java.util.Observer observer)

getState

public State getState()

getClientState

public ClientState getClientState()

sendCommand

public void sendCommand(Command command)
Deprecated. Use sendCommand( OutCommand cmd ) instead.

Parameters:
command - Command we will send
Throws:
java.lang.ClassCastException - if command is not an OutCommand.

sendCommand

public void sendCommand(OutCommand command)
Accepts a command to be sent. Sends the command to the CommandSender.

Parameters:
command - Command we will send

getCommandSender

public CommandSender getCommandSender()
Returns:
the first class in a chain of OutCommandProcessors.

setCommandSender

public void setCommandSender(CommandSender sender)
Parameters:
sender - sets the class that is responsible for sending commands.

getLocalhost

public java.lang.String getLocalhost()
Deprecated. Pending removal due to unspecified behaviour, use getLocalAddress instead.

Returns:
"localhost"

getLocalAddress

public java.net.InetAddress getLocalAddress()
Returns:
the local address to which the socket is bound.

getRemotehost

public java.lang.String getRemotehost()

setSendDelay

public void setSendDelay(int sleepTime)
Sets the time in milliseconds we wait after each command is sent.

Parameters:
sleepTime - Length of time to sleep between commands

getCronManager

public CronManager getCronManager()
Returns:
a class that can schedule timer tasks.
Since:
0.3.2

injectCommand

public void injectCommand(java.lang.String fakeCommand)
Inserts into the event queue a command that was not directly received from the server.

Parameters:
fakeCommand - Fake command to inject into incoming queue

parseRawString

public static java.lang.String[] parseRawString(java.lang.String wholeString)
Splits a raw IRC command into three parts, the prefix, identifier, and parameters.

Parameters:
wholeString - String to be parsed
Returns:
a String array with 3 components, {prefix,ident,params}.

getCommandObject

protected InCommand getCommandObject(java.lang.String prefix,
                                     java.lang.String identifier,
                                     java.lang.String params)
Given the three parts of an IRC command, generates an object to represent that command.

Parameters:
prefix - Prefix of command object
identifier - ID of command
params - Params of command
Returns:
An InCommand object for the given command object

handleUnparsableCommand

protected void handleUnparsableCommand(java.lang.String wholeString,
                                       java.lang.Exception e)

handleSocketCloseException

protected void handleSocketCloseException(java.io.IOException ioe)


Copyright © 2000-2007 Ben Damm, Daniel Henninger, et al.