The interface and the 3 annotations are not tied to blueprint. The wrapper command is mostly unaware of blueprint but for the conversion of arguments (as blueprint as some very nice converter specified), but this part could be made abstract and have two implementations, one being able to leverage blueprint and another one that would be without additional requirement.
On Thu, Jul 2, 2009 at 15:53, Richard S. Hall<[email protected]> wrote: > On 7/2/09 2:24 AM, Guillaume Nodet wrote: >> >> For Karaf, I've been working on a prototype to be able to support more >> powerful commands in gogo. >> The problem with the current way (i.e. one function == one method) is >> that it's quite difficult to >> * display help for a command >> * have optional arguments >> So what I've done, and this would also benefit Karaf, is based on what >> gshell is doing for commands. >> It's based on the following interfaces: >> >> public interface Action >> { >> Object execute(CommandSession session) throws Exception; >> } >> >> @Retention(RetentionPolicy.RUNTIME) >> @Target({ElementType.TYPE}) >> public @interface Command >> { >> String scope(); >> >> String name(); >> >> String description() default ""; >> } >> >> @Retention(RetentionPolicy.RUNTIME) >> @Target({ElementType.FIELD, ElementType.METHOD}) >> public @interface Argument >> { >> String name() default "VAL"; >> >> String description() default ""; >> >> boolean required() default false; >> >> int index() default 0; >> >> boolean multiValued() default false; >> } >> >> @Retention(RetentionPolicy.RUNTIME) >> @Target({ElementType.FIELD, ElementType.METHOD}) >> public @interface Option >> { >> String name(); >> >> String[] aliases() default {}; >> >> String description() default ""; >> >> boolean required() default false; >> >> boolean multiValued() default false; >> >> } >> >> >> So a given command would look like: >> >> @Command(scope = "my", name = "action") >> public class MyAction implements Action { >> >> @Option(name = "-s", aliases = { "--start" }) >> boolean start; >> >> �...@argument(name = "ids", required = true, multivalued = true) >> List<Integer> ids; >> >> public Object execute(CommandSession session) { >> ... >> } >> } >> >> >> This action has to be wrapped inside a command (implementing the >> Function interface) and which will be able to create a new instance of >> the action, parse the arguments, populate it, and call it. >> In addition the wrapper will detect the use of "-h" or "--help" >> arguments and compute / display the help on the console if requested. >> >> Curerntly, what I've done is leveraging blueprint, so I have a custom >> namespace (same as we had in karaf/gshell) >> >> <command-bundle >> xmlns="http://felix.apache.org/karaf/xmlns/gshell/v1.0.0"> >> <command name="osgi/list"> >> <action >> class="org.apache.felix.karaf.gshell.osgi.ListBundles"> >> <property name="blueprintListener" >> ref="blueprintListener"/> >> </action> >> </command> >> </command-bundle> >> >> This will create a command and register it in the OSGi registry so >> that it will be available in the shell. >> > > The above sounds interesting, but I would hope that using Blueprint would be > optional. > > Of course, to some degree, if Gogo becomes the reference impl for the OSGi > Shell, we run a risk of creating non-spec'ed features that could confuse > people. However, right now we have an opportunity to shape what happens with > the RFC... > > -> richard > >> I haven't implemented completers yet, but that's next on my todo list. >> >> So the question is: should this be part of gogo or do we keep that for >> karaf ? >> I have the same question for the console: I've started working on an >> advanced console (leveraging jline as we did in karaf / gshell). >> >> > -- Cheers, Guillaume Nodet ------------------------ Blog: http://gnodet.blogspot.com/ ------------------------ Open Source SOA http://fusesource.com
