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

Last change on this file since 175 was 175, checked in by sherbold, 13 years ago
  • code documentation and formatting
File size: 4.5 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                Command cmd = null;
111                CommandParser parser = new CommandParser();
112                parser.parse(command);
113                for (int i = 0; cmd == null && i < commandPackageList.size(); i++) {
114                        cmd = loadCMD(commandPackageList.get(i) + "." + cmdPrefix
115                                        + parser.getCommandName());
116                }
117                if (cmd == null) { // check if command is available as default command
118                        cmd = loadCMD(defaultPackage + "." + cmdPrefix
119                                        + parser.getCommandName());
120                }
121                if (cmd == null) {
122                        Console.println("Unknown command");
123                } else {
124                        try {
125                                cmd.run(parser.getParameters());
126                        } catch (InvalidParameterException e) {
127                                cmd.help();
128                        }
129                }
130        }
131
132        /**
133         * <p>
134         * Helper method that loads a class and tries to cast it to {@link Command}.
135         * </p>
136         *
137         * @param className
138         *            qualified name of the class (including package name)
139         * @return if class is available and implement {@link Command} and instance
140         *         of the class, null otherwise
141         */
142        private Command loadCMD(String className) {
143                Command cmd = null;
144                try {
145                        Class<?> cmdClass = Class.forName(className);
146                        cmd = (Command) cmdClass.newInstance();
147                } catch (NoClassDefFoundError e) {
148                        String[] splitResult = e.getMessage().split("CMD");
149                        String correctName = splitResult[splitResult.length - 1].replace(
150                                        ")", "");
151                        Console.traceln("Did you mean " + correctName + "?");
152                } catch (ClassNotFoundException e) {
153                } catch (IllegalAccessException e) {
154                } catch (InstantiationException e) {
155                } catch (ClassCastException e) {
156                        Console.traceln(className + "found, but does not implement Command");
157                }
158                return cmd;
159        }
160}
Note: See TracBrowser for help on using the repository browser.