Anatomy of a Gogo command
In the built-in Equinox console commands are provided by classes extending the
CommandProvider
interface. All commands should be public
methods, starting with underscore and accepting as an argument a CommandInterpreter
object. A little bit restricting, isn't it? Well, now comes the new shell, with the Gogo-type commands, which have none of these restrictions.Gogo commands are provided by an arbitrary class (no interfaces to implemet!). The commands should be
public
methods of the class and they may take arbitrary arguments. The command providers are registered as services with two specific properties:osgi.command.scope
- specifies the scope of the commandsosgi.command.function
- lists the names of all commands in the provider (i.e., the names of the public methods in the class)
pulblic class HelloCommand {
public void sayHello() {
System.out.println("Hello world!");
}
}
The code to register this command is:
...
Dictionary<String, Object> properties = new Hashtable();
properties.put("osgi.command.scope", "myscope");
properties.put("osgi.command.function", new String[] {"sayHello"});
context.register(HelloCommand.class, new HelloCommand(), properties);
...
In this way you can register existing classes with public methods as command providers. Sometimes this could be very useful.
Converters and Formatters
As I mentioned, the commands may accept arguments of arbitrary types. Probably you wonder how the strings, read from the input stream, are converted to the command argument type? This is possible because of the special converters which the Gogo shell introduces.
The converter is a class which knows how to convert the value, read from the command line, to the actual argument. For example, your command may accept a
Bundle
object as an argument. Assume you want to call the command with the bundle id or the bundle symbolic name. You write a converter, which looks up the Bundle
object in the BundleContext
by the id, or in the PackageAdmin
service by its symbolic name, and returns the Bundle
object. The converters are registered as services. A converter should implement the interface
org.apache.felix.service.command.Converter
. The interface has two methods - convert
and format
. When the Gogo shell executes a command, it calls all registered converters, passing the input arguments to their convert
methods. It calls the command with whichever converted object matches its argument type.The output of a Gogo command can be an object of arbitrary type. The shell itself cannot know how to display all possible objects. So Gogo uses again the converters, but their
format
method. For example, your command may return a Dictionary
object. You may register a converter, which knows exactly how to format and output the values in the Dictionary
. After Gogo executes the command and gets the result, it calls all registered converters on it.You may register a converter implementation which implements only the
convert
method, only the format
method, or both - it depends on your command. Gogo provides some default converters, so it is not always necessary to provide your own.Customizing the Tab Completion
As explained in the previous post, the new shell provides tab completion for commands names, variables names and files names. It is possible that the command has specific input and in this case it would have a better knowledge how to complete it. For this case the shell supports custom completers. A custom completer should implement the interface
org.eclipse.equinox.console.common.Completer
. It has one method - getCandidates
, which gets as an argument the whole command line and the current position of the cursor in it, and returns a map with all completion candidates. The keys are the candidates, and the values are the start positions for the completions. The completers are registered as services.
Няма коментари:
Публикуване на коментар