The DSL will make it easier to write the command. So it is quite
convenient in the start.
The downside I see is that it will create quite strong coupling between
someone creating the service and the karaf impl. So it might be
difficult when we do karaf 4 which might introduce a lot of changes in
the implementation.
I think it would be better if we find a way that allows the implementer
of a command to simply implement an interface, use some annotations and
export the command as a service. Basically we are almost there already.
The user code already only depends on the interface Action and some
annotations.
I know we currently have the problem that e.g. in BlueprintCommand we
create a new instance of the Action. Perhaps we could avoid that.
How about this:
The user simply exports his Action object as a service.
We pick it up in the shell bundle and simply use it in a synchronized
fashion on command execution at a time. We can then prepare the command
(fill in the arguments and execute it) and execute it without creating a
new instance.
Best regards
Christian
On 14.02.2014 17:47, Guillaume Nodet wrote:
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
--
Christian Schneider
http://www.liquid-reality.de
Open Source Architect
http://www.talend.com