See https://issues.apache.org/jira/browse/KARAF-2761

The idea is to simplify writing commands as much as possible.
With the recent @Completer annotation, things are already much easier to
deal with, but writing commands without blueprint is a real pain.

I've committed a simple java DSL to help around that, so you have an
example at
https://git-wip-us.apache.org/repos/asf?p=karaf.git;a=blob;f=scr/command/src/main/java/org/apache/karaf/scr/command/Commands.java;h=70533e5640e5ab0492b67df71a9a028a7895135e;hb=40140e4f0c0745a41c1a4579f529f07e5819d785#l39
So far the SCR commands, it's a clear win.

I'm also considering using it for blueprint based commands, but I haven't
had any time to experiment yet.   One limitation of blueprint is that
there's no "abstract" definitions, so no way to make things common to all
commands definitions in a given bundle.
Let's look at a common use case:

https://git-wip-us.apache.org/repos/asf?p=karaf.git;a=blob;f=jndi/command/src/main/resources/OSGI-INF/blueprint/jndi-command.xml;h=d9b9f148ca2bc3be6e6dcd574840ed19576f11da;hb=HEAD

The only real interesting things in the above xml is the class names of
commands and completers.  I think reusing the above DSL, the blueprint
would look like

<reference id="jndiService" interface="org.apache.karaf.jndi.JndiService" />
<bean class="org.apache.karaf.jndi.command.Commands" init-method="init"
destroy-method="unregister">
  <property name="context" ref="blueprintBundleConext" />
 <property name="jndiService" ref="jndiService" />
</bean>

and then, the java code:

public class Commands extends org.apache.karaf.shell.commands.Commands {
  private JndiService jndiService;
  public void init() {
    completer(new ContextsCompleter(jndiService));
    completer(new NamesCompleter(jndiService));
    completer(new ServiceIdsCompleter(getContext()));
    command(AliasCommand.class);
    command(BindCommand.class);
    command(ContextsCommand.class);
    command(CreateCommand.class);
    command(DeleteCommand.class);
    command(NamesCommand.class);
    command(UnbindCommand.class);
    register();
  }
  public CommandBuilder command(Class<? extends Action> actionClass) {
    return super.command(actionClass)
              .properties(jndiService);
  }
  public void setJndiService(JndiService jndiService) {
    this.jndiService = jndiService;
  }
}

I haven't tried the above code yet, so there may be slight typos, but that
gives you an idea of what it would look like.
Thoughts ?

Guillaume

Reply via email to