RFC-147 Overview
The RFC-147 draft is not yet publicly available. It used to be called RFC-132, which can be found about 40% into
http://www.osgi.org/download/osgi-4.2-early-draft.pdf
This is an overview of its main features:
Standard way to implement and run commands for any OSGi 4.2 framework
Commands are registered via service attributes, you don't have to register a specific service. This allows commands to be registered by existing services, just by adding the new attributes:
Dictionary<String, Object> dict = new Hashtable<String, Object>();
dict.put(CommandProcessor.COMMAND_SCOPE, "shell");
dict.put(CommandProcessor.COMMAND_FUNCTION, new String[] {"sleep", "grep"});
context.registerService(name, service, dict);
Scope is used to provide a namespace for commands. The commands above can be invoked as "shell:sleep" and "shell:grep". If the scope is omitted (e.g. "sleep" and "grep") then the first matching command is invoked.
Commands can have any signature - arguments are coerced to call the best matching method using reflection. A CommandSession argument is inserted if required:
public void sleep(long millis) throws InterruptedException{
Thread.sleep(millis);
}
public void sleep(String[] args) throws Exception;
public boolean grep(CommandSession session, String[] args) throws Exception;
The CommandSession interface provides methods for executing commands and getting and setting session variables:
public interface org.osgi.service.command.CommandSession {
Object execute(CharSequence commandline) throws Exception;
Object get(String name);
void put(String name, Object value);
...
}
Easy to use interactively - no unnecessary syntax.
// simple command
// session variables
// execution quotes () - similar to bash backquotes
Provides lists, pipes and closures.
// lists - []
// pipes
// closures - {}
Leverages existing Java capabilities, via reflection.
// exception handling - console shows summary, but full context available
// add all public methods on java.lang.System as commands:
Easy to implement and test commands without needing OSGi.
Command implementations don't need to reference any OSGi interfaces. They can use System.in, System.out and System.err, just as you would in a trivial Java application. The ThreadIO service transparently manages the singleton System.out etc, so that each thread sees the appropriate stream:
public void cat(String[] args) throws Exception {
for (String arg : args)
IOUtil.copy(arg, System.out);
}
Normal commands can provide control primitives.
public void each(CommandSession session, Collection<Object> list, Function, closure) throws Exception {
for (Object x : list) {
closure.execute(session, null);
}
}