cgruber / jcommander-inject

Guice integration with jCommander

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

JCommander-Guice

JCommander is a command-line parameter parsing framework by CŽdric Beust. It lets you create annotated parameter objects, and handles parsing, type coercion, and various kinds of error reporting for the library user.

JCommander-Guice is an integration between JCommander and Guice - a sort of flag-binder.
JCommander-Guice acts as a Module builder, allowing you to simply pass in the JCommander-style annotated parameter objects, an optional prefix, and the args String[]. JCommanderModuleBuilder then invokes the JCommander candy goodness, and creates a Module which binds each parameter to @Named-qualified, strongly typed values in the injector. This permits you to simply inject the parameter values where you need them.

Here is a quick example:

public class AppParameters {
  @Parameter
  public List<String> parameters = Lists.newArrayList();

  @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity")
  public Integer verbose = 1;

  @Parameter(names = "-groups", description = "Comma-separated list of group names to be run")
  public String groups;

  @Parameter(names = "-debug", description = "Debug mode")
  public boolean debug = false;
}

and how you use it:

// created just for an injection example.
class MyClass {
  final Boolean debug;
  final Integer debugVerbosity;
  final MyOtherClass other;
  @Inject MyClass(
    @Named("debug") Boolean debug,
    @Named("verbose") Integer debugVerbosity,
    MyOtherClass other
  ) {
    this.debug = debug;
    this.debugVerbosity = debugVerbosity;
    this.other = other;
  }
}

// Or field injection, whatevz...
class MyOtherClass {
  @Inject @Named("groups") String groups;
}

class MyModule implements Module {
  public void configure(Binder binder) {
    binder.bind(MyClass.class);
    binder.bind(MyOtherClass.class);
  }
}

And bind it like this

Assume main() args: "-groups foo -verbose -verbose -debug a b c";
Injector i = Guice.createInjector(
    JCommanderModuleBuilder.bindParameters(AppParameters.class).withArguments(args).build(),
    new MyModule());
MyClass myClass = i.getInstance(MyClass.class);

// Testing this should result in
assertNotNull(myClass);
assertTrue(myClass.debug);
assertNotNull(myClass.other);
assertEquals("foo", myClass.other.groups);

If you want, you can add a prefix:

// created just for an injection example.
public class MyClass {
  @Inject @Named("cli.debug") Boolean debug;
  @Inject @Named("cli.verbose") Integer debugVerbosity;
  @Inject MyOtherClass other;
}

public class MyOtherClass {
  @Inject @Named("cli.groups") String groups;
}

And bind it like so:

// Assume: "-groups foo -verbose -verbose -debug a b c"
public static main(String[] args) {
Injector i = Guice.createInjector(
  JCommanderModuleBuilder.bindParameters(AppParameters.class)
      .withPrefix("cli.").withArguments(args).build(),
);

You can also directly inject the parameter objects.

Assume main() args: "-groups foo -verbose -verbose -debug a b c";
Injector i = Guice.createInjector(
    JCommanderModuleBuilder.bindParameters(AppParameters.class).withArguments(args).build(),
    new MyModule());
// Fetching from injector - better to inject directly.
AppParameters myClass = i.getInstance(AppParameters.class);

// Testing this should result in
assertNotNull(myClass);

About

Guice integration with jCommander

License:Apache License 2.0


Languages

Language:Java 100.0%