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

Last change on this file since 16 was 1, checked in by sherbold, 14 years ago
File size: 4.4 KB
Line 
1package de.ugoe.cs.util.console;
2
3import java.security.InvalidParameterException;
4import java.util.ArrayList;
5import java.util.List;
6
7
8/**
9 * <p>
10 * Executes commands. The commands have to implement the {@link Command}
11 * interface and be in packages registered using addCommandPackage().
12 * Additionally, default commands are implemented in the
13 * de.ugoe.cs.util.console.defaultcommands package.
14 * </p>
15 * <p>
16 * This class is implemented as a <i>Singleton</i>.
17 * </p>
18 *
19 * @author Steffen Herbold
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 defaultcommands package has always lowest priority, unless it is
51         * specificially 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 exec to load command from.
81         * </p>
82         *
83         * @param pkg
84         *            package where commands are located
85         */
86        public void addCommandPackage(String pkg) {
87                commandPackageList.add(pkg);
88        }
89
90        /**
91         * <p>
92         * Executes the command defined by string. A command has the following form
93         * (mix of EBNF and natural language):
94         * </p>
95         * <code>
96         * &lt;command&gt; := &lt;commandname&gt;&lt;whitespace&gt;{&lt;parameter&gt;}<br>
97         * &lt;commandname&gt; := String without whitespaces. Has to be a valid Java class name<br>
98         * &lt;parameter&gt; := &lt;string&gt;|&lt;stringarray&gt;<br>
99         * &lt;string&gt; := &lt;stringwithoutwhitespaces&gt;|&lt;stringwithwhitespaces&gt;
100         * &lt;stringwithoutwhitespaces&gt; := a string without whitespaces<br>
101         * &lt;stringwithoutwhitespaces&gt; := a string, that can have whitespaces, but must be in double quotes<br>
102         * &lt;stringarray&gt; := "["&lt;string&gt;{&lt;whitespace&gt;&lt;string&gt;"]"
103         * </code>
104         *
105         * @param command
106         *            the command as a string
107         */
108        public void exec(String command) {
109                Command cmd = null;
110                CommandParser parser = new CommandParser();
111                parser.parse(command);
112                for (int i = 0; cmd == null && i < commandPackageList.size(); i++) {
113                        cmd = loadCMD(commandPackageList.get(i)+"."+cmdPrefix+parser.getCommandName());
114                }
115                if (cmd == null) { // check if command is available as default command
116                        cmd = loadCMD(defaultPackage+"."+cmdPrefix+parser.getCommandName());
117                }
118                if (cmd == null) {
119                        Console.println("Unknown command");
120                } else {
121                        try {
122                                cmd.run(parser.getParameters());
123                        } catch (InvalidParameterException e) {
124                                cmd.help();
125                        }
126                }
127        }
128
129        /**
130         * Helper method that loads a class and tries to cast it to {@link Command}.
131         *
132         * @param className qualified name of the class (including package name)
133         * @return if class is available and implement {@link Command} and instance of the class, null otherwise
134         */
135        private Command loadCMD(String className) {
136                Command cmd = null;
137                try {
138                        Class<?> cmdClass = Class.forName(className);
139                        cmd = (Command) cmdClass.newInstance();
140                } catch (NoClassDefFoundError e) {
141                        String[] splitResult = e.getMessage().split("CMD");
142                        String correctName = splitResult[splitResult.length-1].replace(")", "");
143                        Console.traceln("Did you mean " + correctName + "?");
144                } catch (ClassNotFoundException e) {
145                } catch (IllegalAccessException e) {
146                } catch (InstantiationException e) {
147                } catch (ClassCastException e) {
148                        Console.traceln(className + "found, but does not implement Command");
149                }
150                return cmd;
151        }
152}
Note: See TracBrowser for help on using the repository browser.