source: trunk/JavaHelperLib/src/de/ugoe/cs/util/console/CommandExecuter.java @ 216

Last change on this file since 216 was 186, checked in by sherbold, 13 years ago
  • modified CommandExecuter? and Console make use of the command notification for observers
File size: 4.6 KB
Line 
1package de.ugoe.cs.util.console;
2
3import java.security.InvalidParameterException;
4import java.util.ArrayList;
5import java.util.List;
6
7/**
8 * <p>
9 * Executes commands. The commands have to implement the {@link Command}
10 * interface and be in packages registered using addCommandPackage().
11 * Additionally, default commands are implemented in the
12 * de.ugoe.cs.util.console.defaultcommands package.
13 * </p>
14 * <p>
15 * This class is implemented as a <i>Singleton</i>.
16 * </p>
17 *
18 * @author Steffen Herbold
19 * @version 1.0
20 */
21public class CommandExecuter {
22
23        /**
24         * <p>
25         * Handle of the CommandExecuter instance.
26         * </p>
27         */
28        private final static CommandExecuter theInstance = new CommandExecuter();
29
30        /**
31         * <p>
32         * Prefix of all command classes.
33         * </p>
34         */
35        private static final String cmdPrefix = "CMD";
36
37        /**
38         * <p>
39         * Name of the package for default commands.
40         * </p>
41         */
42        private static final String defaultPackage = "de.ugoe.cs.util.console.defaultcommands";
43
44        /**
45         * <p>
46         * List of packages in which commands may be defined. The exec methods trys
47         * to load command from these packages in the order they have been added.
48         * </p>
49         * <p>
50         * The de.ugoe.cs.util.console.defaultcommands package has always lowest
51         * priority, unless it is specifically added.
52         * </p>
53         */
54        private List<String> commandPackageList;
55
56        /**
57         * <p>
58         * Returns the instance of CommandExecuter. If no instances exists yet, a
59         * new one is created.
60         * </p>
61         *
62         * @return the instance of CommandExecuter
63         */
64        public static synchronized CommandExecuter getInstance() {
65                return theInstance;
66        }
67
68        /**
69         * <p>
70         * Creates a new CommandExecuter. Private to prevent multiple instances
71         * (Singleton).
72         * </p>
73         */
74        private CommandExecuter() {
75                commandPackageList = new ArrayList<String>();
76        }
77
78        /**
79         * <p>
80         * Adds a package that will be used by {@link #exec(String)} to load command
81         * from.
82         * </p>
83         *
84         * @param pkg
85         *            package where commands are located
86         */
87        public void addCommandPackage(String pkg) {
88                commandPackageList.add(pkg);
89        }
90
91        /**
92         * <p>
93         * Executes the command defined by string. A command has the following form
94         * (mix of EBNF and natural language):
95         * </p>
96         * <code>
97         * &lt;command&gt; := &lt;commandname&gt;&lt;whitespace&gt;{&lt;parameter&gt;}<br>
98         * &lt;commandname&gt; := String without whitespaces. Has to be a valid Java class name<br>
99         * &lt;parameter&gt; := &lt;string&gt;|&lt;stringarray&gt;<br>
100         * &lt;string&gt; := &lt;stringwithoutwhitespaces&gt;|&lt;stringwithwhitespaces&gt;
101         * &lt;stringwithoutwhitespaces&gt; := a string without whitespaces<br>
102         * &lt;stringwithoutwhitespaces&gt; := a string, that can have whitespaces, but must be in double quotes<br>
103         * &lt;stringarray&gt; := "["&lt;string&gt;{&lt;whitespace&gt;&lt;string&gt;"]"
104         * </code>
105         *
106         * @param command
107         *            the command as a string
108         */
109        public void exec(String command) {
110                Console.commandNotification(command);
111                Command cmd = null;
112                CommandParser parser = new CommandParser();
113                parser.parse(command);
114                for (int i = 0; cmd == null && i < commandPackageList.size(); i++) {
115                        cmd = loadCMD(commandPackageList.get(i) + "." + cmdPrefix
116                                        + parser.getCommandName());
117                }
118                if (cmd == null) { // check if command is available as default command
119                        cmd = loadCMD(defaultPackage + "." + cmdPrefix
120                                        + parser.getCommandName());
121                }
122                if (cmd == null) {
123                        Console.println("Unknown command");
124                } else {
125                        try {
126                                cmd.run(parser.getParameters());
127                        } catch (InvalidParameterException e) {
128                                cmd.help();
129                        }
130                }
131        }
132
133        /**
134         * <p>
135         * Helper method that loads a class and tries to cast it to {@link Command}.
136         * </p>
137         *
138         * @param className
139         *            qualified name of the class (including package name)
140         * @return if class is available and implement {@link Command} and instance
141         *         of the class, null otherwise
142         */
143        private Command loadCMD(String className) {
144                Command cmd = null;
145                try {
146                        Class<?> cmdClass = Class.forName(className);
147                        cmd = (Command) cmdClass.newInstance();
148                } catch (NoClassDefFoundError e) {
149                        String[] splitResult = e.getMessage().split("CMD");
150                        String correctName = splitResult[splitResult.length - 1].replace(
151                                        ")", "");
152                        Console.traceln("Did you mean " + correctName + "?");
153                } catch (ClassNotFoundException e) {
154                } catch (IllegalAccessException e) {
155                } catch (InstantiationException e) {
156                } catch (ClassCastException e) {
157                        Console.traceln(className + "found, but does not implement Command");
158                }
159                return cmd;
160        }
161}
Note: See TracBrowser for help on using the repository browser.