summaryrefslogtreecommitdiffstats
path: root/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java
diff options
context:
space:
mode:
Diffstat (limited to 'EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java')
-rw-r--r--EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java174
1 files changed, 174 insertions, 0 deletions
diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java
new file mode 100644
index 000000000..97f305241
--- /dev/null
+++ b/EssentialsUpdate/src/f00f/net/irc/martyr/commands/AbstractInCommand.java
@@ -0,0 +1,174 @@
+package f00f.net.irc.martyr.commands;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import f00f.net.irc.martyr.CommandRegister;
+import f00f.net.irc.martyr.InCommand;
+import f00f.net.irc.martyr.State;
+import f00f.net.irc.martyr.clientstate.ClientState;
+
+/**
+ * Defines a generic command. Most commands will simply have to
+ * override the getIrcIdentifier method and implement the parse and
+ * render methods using convenience methods.
+ */
+public abstract class AbstractInCommand implements InCommand
+{
+
+ protected Map<String,String> attributes = new HashMap<String,String>();
+
+ protected AbstractInCommand()
+ {
+ }
+
+ protected AbstractInCommand( String[] attributeNames )
+ {
+ for (String attributeName : attributeNames) {
+ attributes.put(attributeName, null);
+ }
+ }
+
+ public String getAttribute( String key )
+ {
+ return attributes.get( key );
+ }
+
+ public Iterator getAttributeKeys()
+ {
+ return Collections.unmodifiableSet( attributes.keySet() ).iterator();
+ }
+
+ protected void setAttribute( String key, String value )
+ {
+ attributes.put( key, value );
+ }
+
+ private String sourceString;
+
+ /**
+ * Some commands, when received by the server, can only occur in one
+ * state. Thus, when this command is received, the protocol should
+ * assume that it is that state. A command can use the 'unknown'
+ * state to indicate it can be received in any state (for example,
+ * ping). Most commands will occur in the REGISTERED state, so for a
+ * few exeptions, commands can leave this alone.
+ */
+ public State getState()
+ {
+ return State.REGISTERED;
+ }
+
+ /**
+ * Every command should know how to register itself (or not) with the
+ * command parsing engine. If a command is available under mutiple
+ * identifiers, then this method can be overridden and the addCommand
+ * method can be called multiple times.
+ */
+ public void selfRegister( CommandRegister commandRegister )
+ {
+ commandRegister.addCommand( getIrcIdentifier(), this );
+ }
+
+ /**
+ * Parses a string and produces a formed command object, if it can.
+ * Should return null if it cannot form the command object.
+ */
+ public abstract InCommand parse( String prefix, String identifier, String params );
+
+ /**
+ * By default, commands do not update the client state.
+ */
+ public boolean updateClientState( ClientState state )
+ {
+ return false;
+ }
+
+ /**
+ * Utility method to make parsing easy. Provides parameter n, where
+ * n=0 is the first parameter. Parses out the : and considers
+ * anything after a : to be one string, the final parameter.
+ *
+ * If the index doesn't exist, returns null. Should it throw
+ * IndexOutOfBoundsException? No, some commands may have optional
+ * fields.
+ *
+ * @param params String with parameters in it
+ * @param num Position number of parameter to be requested
+ * @return Parameter specified by id in params string
+ */
+ public String getParameter( String params, int num )
+ {
+ int colonIndex = params.indexOf( " :" );
+ colonIndex++; // Skip the space, we just needed it to be sure it's really a "rest of line" colon
+ String textParam = null;
+ String spaceParams;
+
+ if( colonIndex < 0 )
+ {
+ spaceParams = params;
+ }
+ else if( colonIndex == 0 )
+ {
+ if( num == 0 )
+ return params.substring( 1, params.length() );
+ else
+ return null;
+ // throw exception?
+ }
+ else
+ {
+ // colon index > 0, so we have at least one parameter before
+ // the final parameter.
+ spaceParams = params.substring( 0, colonIndex ).trim();
+ textParam = params.substring( colonIndex + 1, params.length() );
+ }
+
+ StringTokenizer tokens = new StringTokenizer( spaceParams, " " );
+
+ while( tokens.hasMoreTokens() && num > 0 )
+ {
+ // strip off tokensi
+ --num;
+ tokens.nextToken();
+ }
+
+ if( num == 0 && tokens.hasMoreTokens() )
+ return tokens.nextToken();
+ if( num == 0 && !tokens.hasMoreTokens() )
+ return textParam;
+
+
+ return null;
+ // throw exception?
+ }
+
+ public int getIntParameter( String params, int paramnum, int defaultNum )
+ {
+ try
+ {
+ return Integer.parseInt( getParameter( params, paramnum ) );
+ }
+ catch( NumberFormatException nfe )
+ {
+ return defaultNum;
+ }
+
+ }
+
+ public void setSourceString( String source )
+ {
+ this.sourceString = source;
+ }
+
+ public String getSourceString()
+ {
+ return sourceString;
+ }
+
+}
+
+