Parcourir la source

Added ExternalCommand interface

Made /mode, /names and /topic implement ExternalCommand
Added support for external commands to CommandParser
Fixes issue 452

git-svn-id: http://svn.dmdirc.com/trunk@3488 00569f92-eb28-0410-84fd-f71c24880f
tags/0.6
Chris Smith il y a 16 ans
Parent
révision
ca826194f6

+ 47
- 0
src/com/dmdirc/commandparser/commands/ExternalCommand.java Voir le fichier

@@ -0,0 +1,47 @@
1
+/*
2
+ * Copyright (c) 2006-2008 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+package com.dmdirc.commandparser.commands;
23
+
24
+import com.dmdirc.Server;
25
+import com.dmdirc.ui.interfaces.InputWindow;
26
+
27
+/**
28
+ * An external command is a channel command that can be executed from outside
29
+ * of the channel.
30
+ * 
31
+ * @author chris
32
+ */
33
+public interface ExternalCommand {
34
+    
35
+    /**
36
+     * Executes the command externally.
37
+     * 
38
+     * @param origin The window in which the command was typed
39
+     * @param server The server instance that this command is being executed on
40
+     * @param channel The name of the channel the command is being executed for
41
+     * @param isSilent Whether this command is silenced or not
42
+     * @param args Arguments passed to this command
43
+     */
44
+    public abstract void execute(InputWindow origin, Server server, String channel,
45
+            boolean isSilent, String... args);    
46
+
47
+}

+ 25
- 12
src/com/dmdirc/commandparser/commands/channel/Mode.java Voir le fichier

@@ -26,6 +26,7 @@ import com.dmdirc.Channel;
26 26
 import com.dmdirc.Server;
27 27
 import com.dmdirc.commandparser.commands.ChannelCommand;
28 28
 import com.dmdirc.commandparser.CommandManager;
29
+import com.dmdirc.commandparser.commands.ExternalCommand;
29 30
 import com.dmdirc.commandparser.commands.IntelligentCommand;
30 31
 import com.dmdirc.parser.ChannelInfo;
31 32
 import com.dmdirc.ui.input.AdditionalTabTargets;
@@ -38,40 +39,52 @@ import java.util.List;
38 39
  * The mode command allows the user to inspect and change channel modes.
39 40
  * @author chris
40 41
  */
41
-public final class Mode extends ChannelCommand implements IntelligentCommand {
42
-    
42
+public final class Mode extends ChannelCommand implements IntelligentCommand,
43
+        ExternalCommand {
44
+
43 45
     /** Creates a new instance of Mode. */
44 46
     public Mode() {
45 47
         super();
46
-        
48
+
47 49
         CommandManager.registerCommand(this);
48 50
     }
49
-    
51
+
50 52
     /** {@inheritDoc} */
51 53
     @Override
52 54
     public void execute(final InputWindow origin, final Server server,
53 55
             final Channel channel, final boolean isSilent, final String... args) {
54 56
         final ChannelInfo cChannel = channel.getChannelInfo();
55
-        
57
+
56 58
         if (args.length == 0) {
57 59
             sendLine(origin, isSilent, "channelModeDiscovered", cChannel.getModeStr(), cChannel);
58 60
         } else {
59 61
             server.getParser().sendLine("MODE " + cChannel + " " + implodeArgs(args));
60 62
         }
61 63
     }
62
-    
64
+
65
+    /** {@inheritDoc} */
66
+    @Override
67
+    public void execute(final InputWindow origin, final Server server,
68
+            final String channel, final boolean isSilent, final String ... args) {
69
+        if (args.length == 0) {
70
+            server.getParser().sendLine("MODE " + channel);
71
+        } else {
72
+            server.getParser().sendLine("MODE " + channel + " " + implodeArgs(args));
73
+        }
74
+    }
75
+
63 76
     /** {@inheritDoc} */
64 77
     @Override
65 78
     public String getName() {
66 79
         return "mode";
67 80
     }
68
-    
81
+
69 82
     /** {@inheritDoc} */
70 83
     @Override
71 84
     public boolean showInHelp() {
72 85
         return true;
73 86
     }
74
-    
87
+
75 88
     /** {@inheritDoc} */
76 89
     @Override
77 90
     public String getHelp() {
@@ -82,12 +95,12 @@ public final class Mode extends ChannelCommand implements IntelligentCommand {
82 95
     @Override
83 96
     public AdditionalTabTargets getSuggestions(final int arg, final List<String> previousArgs) {
84 97
         final AdditionalTabTargets res = new AdditionalTabTargets().excludeAll();
85
-        
98
+
86 99
         if (arg > 0) {
87 100
             res.include(TabCompletionType.CHANNEL_NICK);
88 101
         }
89
-        
102
+
90 103
         return res;
91
-    } 
92
-    
104
+    }
105
+
93 106
 }

+ 10
- 1
src/com/dmdirc/commandparser/commands/channel/Names.java Voir le fichier

@@ -26,6 +26,7 @@ import com.dmdirc.Channel;
26 26
 import com.dmdirc.Server;
27 27
 import com.dmdirc.commandparser.CommandManager;
28 28
 import com.dmdirc.commandparser.commands.ChannelCommand;
29
+import com.dmdirc.commandparser.commands.ExternalCommand;
29 30
 import com.dmdirc.commandparser.commands.IntelligentCommand;
30 31
 import com.dmdirc.ui.input.AdditionalTabTargets;
31 32
 import com.dmdirc.ui.interfaces.InputWindow;
@@ -37,7 +38,7 @@ import java.util.List;
37 38
  * 
38 39
  * @author chris
39 40
  */
40
-public class Names extends ChannelCommand implements IntelligentCommand {
41
+public class Names extends ChannelCommand implements IntelligentCommand, ExternalCommand {
41 42
     
42 43
     /**
43 44
      * Creates a new instance of Names.
@@ -54,6 +55,14 @@ public class Names extends ChannelCommand implements IntelligentCommand {
54 55
             final Channel channel, final boolean isSilent, final String... args) {
55 56
         server.getParser().sendLine("NAMES " + channel.getChannelInfo().getName());
56 57
     }
58
+    
59
+
60
+    /** {@inheritDoc} */
61
+    @Override
62
+    public void execute(final InputWindow origin, final Server server,
63
+            final String channel, final boolean isSilent, final String ... args) {
64
+        server.getParser().sendLine("NAMES " + channel);
65
+    }    
57 66
 
58 67
     /** {@inheritDoc} */
59 68
     @Override

+ 22
- 10
src/com/dmdirc/commandparser/commands/channel/ShowTopic.java Voir le fichier

@@ -26,6 +26,7 @@ import com.dmdirc.Channel;
26 26
 import com.dmdirc.Server;
27 27
 import com.dmdirc.commandparser.commands.ChannelCommand;
28 28
 import com.dmdirc.commandparser.CommandManager;
29
+import com.dmdirc.commandparser.commands.ExternalCommand;
29 30
 import com.dmdirc.parser.ChannelInfo;
30 31
 import com.dmdirc.ui.interfaces.InputWindow;
31 32
 
@@ -33,22 +34,22 @@ import com.dmdirc.ui.interfaces.InputWindow;
33 34
  * The show topic command shows the user the current topic.
34 35
  * @author chris
35 36
  */
36
-public final class ShowTopic extends ChannelCommand {
37
-    
37
+public final class ShowTopic extends ChannelCommand implements ExternalCommand {
38
+
38 39
     /** Creates a new instance of ShowTopic. */
39 40
     public ShowTopic() {
40 41
         super();
41
-        
42
+
42 43
         CommandManager.registerCommand(this);
43 44
     }
44
-    
45
+
45 46
     /** {@inheritDoc} */
46 47
     @Override
47 48
     public void execute(final InputWindow origin, final Server server,
48
-            final Channel channel, final boolean isSilent, final String... args) {       
49
+            final Channel channel, final boolean isSilent, final String... args) {
49 50
         if (args.length == 0) {
50 51
             final ChannelInfo cChannel = channel.getChannelInfo();
51
-            
52
+
52 53
             if (!cChannel.getTopic().isEmpty()) {
53 54
                 sendLine(origin, isSilent, "channelJoinTopic", cChannel.getTopic(),
54 55
                         cChannel.getTopicUser(), 1000 * cChannel.getTopicTime(), cChannel);
@@ -59,23 +60,34 @@ public final class ShowTopic extends ChannelCommand {
59 60
             channel.setTopic(implodeArgs(args));
60 61
         }
61 62
     }
62
-    
63
+
64
+    /** {@inheritDoc} */
65
+    @Override
66
+    public void execute(final InputWindow origin, final Server server,
67
+            final String channel, final boolean isSilent, final String ... args) {
68
+        if (args.length == 0) {
69
+            server.getParser().sendLine("TOPIC " + channel);
70
+        } else {
71
+            server.getParser().sendLine("TOPIC " + channel + " :" + implodeArgs(args));
72
+        }
73
+    }
74
+
63 75
     /** {@inheritDoc} */
64 76
     @Override
65 77
     public String getName() {
66 78
         return "topic";
67 79
     }
68
-    
80
+
69 81
     /** {@inheritDoc} */
70 82
     @Override
71 83
     public boolean showInHelp() {
72 84
         return true;
73 85
     }
74
-    
86
+
75 87
     /** {@inheritDoc} */
76 88
     @Override
77 89
     public String getHelp() {
78 90
         return "topic - displays the current topic\ntopic <newtopic> - sets the channel topic";
79 91
     }
80
-    
92
+
81 93
 }

+ 52
- 41
src/com/dmdirc/commandparser/parsers/CommandParser.java Voir le fichier

@@ -26,7 +26,9 @@ import com.dmdirc.Server;
26 26
 import com.dmdirc.actions.ActionManager;
27 27
 import com.dmdirc.actions.CoreActionType;
28 28
 import com.dmdirc.commandparser.CommandManager;
29
+import com.dmdirc.commandparser.CommandType;
29 30
 import com.dmdirc.commandparser.commands.Command;
31
+import com.dmdirc.commandparser.commands.ExternalCommand;
30 32
 import com.dmdirc.commandparser.commands.PreviousCommand;
31 33
 import com.dmdirc.config.IdentityManager;
32 34
 import com.dmdirc.ui.interfaces.InputWindow;
@@ -40,28 +42,28 @@ import java.util.Map;
40 42
  * Represents a generic command parser. A command parser takes a line of input
41 43
  * from the user, determines if it is an attempt at executing a command (based
42 44
  * on the character at the start of the string), and handles it appropriately.
43
- * 
45
+ *
44 46
  * @author chris
45 47
  */
46 48
 public abstract class CommandParser implements Serializable {
47
-    
49
+
48 50
     /**
49 51
      * A version number for this class. It should be changed whenever the class
50 52
      * structure is changed (or anything else that would prevent serialized
51 53
      * objects being unserialized with the new class).
52 54
      */
53 55
     private static final long serialVersionUID = 1;
54
-    
56
+
55 57
     /**
56 58
      * Commands that are associated with this parser.
57 59
      */
58 60
     private final Map<String, Command> commands;
59
-    
61
+
60 62
     /**
61 63
      * A history of commands that have been entered into this parser.
62 64
      */
63 65
     private final RollingList<PreviousCommand> history;
64
-    
66
+
65 67
     /** Creates a new instance of CommandParser. */
66 68
     public CommandParser() {
67 69
         commands = new Hashtable<String, Command>();
@@ -70,31 +72,31 @@ public abstract class CommandParser implements Serializable {
70 72
                     "commandhistory", 10));
71 73
         loadCommands();
72 74
     }
73
-    
75
+
74 76
     /** Loads the relevant commands into the parser. */
75 77
     protected abstract void loadCommands();
76
-    
78
+
77 79
     /**
78 80
      * Registers the specified command with this parser.
79
-     * 
81
+     *
80 82
      * @param command Command to be registered
81 83
      */
82 84
     public final void registerCommand(final Command command) {
83 85
         commands.put(command.getName().toLowerCase(), command);
84 86
     }
85
-    
87
+
86 88
     /**
87 89
      * Unregisters the specified command with this parser.
88
-     * 
90
+     *
89 91
      * @param command Command to be unregistered
90 92
      */
91 93
     public final void unregisterCommand(final Command command) {
92 94
         commands.remove(command.getName().toLowerCase());
93 95
     }
94
-    
96
+
95 97
     /**
96 98
      * Parses the specified string as a command.
97
-     * 
99
+     *
98 100
      * @param origin The window in which the command was typed
99 101
      * @param line The line to be parsed
100 102
      * @param parseChannel Whether or not to try and parse the first argument
@@ -105,50 +107,59 @@ public abstract class CommandParser implements Serializable {
105 107
         if (line.isEmpty()) {
106 108
             return;
107 109
         }
108
-        
110
+
109 111
         if (line.charAt(0) == CommandManager.getCommandChar()) {
110 112
             int offset = 1;
111 113
             boolean silent = false;
112
-            
114
+
113 115
             if (line.length() > offset && line.charAt(offset) == CommandManager.getSilenceChar()) {
114 116
                 silent = true;
115 117
                 offset++;
116 118
             }
117
-            
119
+
118 120
             final String[] args = line.split(" ");
119 121
             final String command = args[0].substring(offset);
120 122
             String[] comargs;
121
-            
123
+
122 124
             if (args.length >= 2 && parseChannel && origin != null
123 125
                     && origin.getContainer() != null
124 126
                     && origin.getContainer().getServer() != null
125 127
                     && origin.getContainer().getServer().isValidChannelName(args[1])
126 128
                     && CommandManager.isChannelCommand(command)) {
127 129
                 final Server server = origin.getContainer().getServer();
128
-                
130
+
129 131
                 if (server.hasChannel(args[1])) {
130
-                    
132
+
131 133
                     final StringBuilder newLine = new StringBuilder();
132 134
                     for (int i = 0; i < args.length; i++) {
133 135
                         if (i == 1) { continue; }
134 136
                         newLine.append(" ").append(args[i]);
135 137
                     }
136
-                    
138
+
137 139
                     server.getChannel(args[1]).getFrame().getCommandParser()
138 140
                             .parseCommand(origin, newLine.substring(1), false);
139
-                    
141
+
140 142
                     return;
141 143
                 } else {
142
-                    // Do something haxy involving external commands here...
144
+                    final Command actCommand = CommandManager.getCommand(
145
+                            CommandType.TYPE_CHANNEL, command);
146
+
147
+                    if (actCommand instanceof ExternalCommand) {
148
+                        comargs = new String[args.length - 2];
149
+                        System.arraycopy(args, 2, comargs, 0, args.length - 2);
150
+
151
+                        ((ExternalCommand) actCommand).execute(origin, server,
152
+                                args[1], silent, comargs);
153
+                        return;
154
+                    }
143 155
                 }
144 156
             }
145
-            
157
+
146 158
             comargs = new String[args.length - 1];
147
-            
148 159
             System.arraycopy(args, 1, comargs, 0, args.length - 1);
149
-            
160
+
150 161
             final String signature = command;
151
-            
162
+
152 163
             if (commands.containsKey(signature.toLowerCase())) {
153 164
                 addHistory(command, comargs);
154 165
                 executeCommand(origin, silent, commands.get(signature.toLowerCase()), comargs);
@@ -159,7 +170,7 @@ public abstract class CommandParser implements Serializable {
159 170
             handleNonCommand(origin, line);
160 171
         }
161 172
     }
162
-    
173
+
163 174
     /**
164 175
      * Adds a command to this parser's history.
165 176
      *
@@ -168,17 +179,17 @@ public abstract class CommandParser implements Serializable {
168 179
      */
169 180
     private void addHistory(final String command, final String... args) {
170 181
         final StringBuilder builder = new StringBuilder(command);
171
-        
182
+
172 183
         for (String arg : args) {
173 184
             builder.append(' ');
174 185
             builder.append(arg);
175 186
         }
176
-        
187
+
177 188
         synchronized(history) {
178 189
             history.add(new PreviousCommand(builder.toString()));
179 190
         }
180 191
     }
181
-    
192
+
182 193
     /**
183 194
      * Retrieves the most recent time that the specified command was used.
184 195
      * Commands should not include command or silence chars.
@@ -196,13 +207,13 @@ public abstract class CommandParser implements Serializable {
196 207
                 }
197 208
             }
198 209
         }
199
-        
210
+
200 211
         return res;
201 212
     }
202
-    
213
+
203 214
     /**
204 215
      * Parses the specified string as a command.
205
-     * 
216
+     *
206 217
      * @param origin The window in which the command was typed
207 218
      * @param line The line to be parsed
208 219
      */
@@ -210,20 +221,20 @@ public abstract class CommandParser implements Serializable {
210 221
             final String line) {
211 222
         parseCommand(origin, line, true);
212 223
     }
213
-    
224
+
214 225
     /**
215 226
      * Handles the specified string as a non-command.
216
-     * 
227
+     *
217 228
      * @param origin The window in which the command was typed
218 229
      * @param line The line to be parsed
219 230
      */
220 231
     public final void parseCommandCtrl(final InputWindow origin, final String line) {
221 232
         handleNonCommand(origin, line);
222 233
     }
223
-    
234
+
224 235
     /**
225 236
      * Executes the specified command with the given arguments.
226
-     * 
237
+     *
227 238
      * @param origin The window in which the command was typed
228 239
      * @param isSilent Whether the command is being silenced or not
229 240
      * @param command The command to be executed
@@ -231,7 +242,7 @@ public abstract class CommandParser implements Serializable {
231 242
      */
232 243
     protected abstract void executeCommand(final InputWindow origin,
233 244
             final boolean isSilent, final Command command, final String... args);
234
-    
245
+
235 246
     /**
236 247
      * Called when the user attempted to issue a command (i.e., used the command
237 248
      * character) that wasn't found. It could be that the command has a different
@@ -247,18 +258,18 @@ public abstract class CommandParser implements Serializable {
247 258
                     null, command, args);
248 259
         } else {
249 260
             final StringBuffer buff = new StringBuffer("unknownCommand");
250
-            
261
+
251 262
             ActionManager.processEvent(CoreActionType.UNKNOWN_COMMAND, buff,
252 263
                     origin.getContainer(), command, args);
253
-            
264
+
254 265
             origin.addLine(buff, command);
255 266
         }
256 267
     }
257
-    
268
+
258 269
     /**
259 270
      * Called when the input was a line of text that was not a command. This normally
260 271
      * means it is sent to the server/channel/user as-is, with no further processing.
261
-     * 
272
+     *
262 273
      * @param origin The window in which the command was typed
263 274
      * @param line The line input by the user
264 275
      */

Chargement…
Annuler
Enregistrer