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

Reply via email to