0

I just discovered args4j, soooo nice to use coming from commons-cli!

I am implementing a sub-command handler where each of the sub-commands will need to access a session object obtained through logging on using credentials common to all sub-commands. If I create the session in the main class, the sub-commands won't have access. I can create the session in the individual sub-commands but to do that I need access to the full arguments.

/**
 * Sample program from args4j site (modified)
 * @author
 *      Kohsuke Kawaguchi (kk@kohsuke.org)
 */
public class SampleMain {
    // needed by all subcommands
    Session somesession;

    @Option(name="-u",usage="user")
    private String user = "notsetyet";

    @Option(name="-p",usage="passwd")
    private String passwd = "notsetyet";

    @Argument(required=true,index=0,metaVar="action",usage="subcommands, e.g., {search|modify|delete}",handler=SubCommandHandler.class)
    @SubCommands({
      @SubCommand(name="search",impl=SearchSubcommand.class),
      @SubCommand(name="delete",impl=DeleteSubcommand.class),
    })
    protected Subcommand action;

    public void doMain(String[] args) throws IOException {
        CmdLineParser parser = new CmdLineParser(this);
        try {
            parser.parseArgument(args);
            // here I want to do my things in the subclasses 
            // but how will the subcommands get either:
            // a) the session object (which I could create in this main class), or
            // b) the options from the main command in order to create their own session obj
            action.execute();
        } catch( CmdLineException e ) {
            System.err.println(e.getMessage());
            return;
        }
    }
}

In short, how do I create a session applicable for all sub-commands?

It may not be an args4j thing, per se, maybe there's some type of design gap in my thinking regarding how subclasses get the proper context. Thank you!

EDIT: I guess I could just pass in the session object to the sub-class. E.g.:

action.execute(somesession);

Is that the best way?

AndyJ
  • 1,204
  • 3
  • 14
  • 28

1 Answers1

1

I found this in the documentation:

  • Any Options that you define in the Git class above can parse options that appear prior to the sub-command name. This is useful for defining global options that work across sub-commands.
  • The matching sub-command implementation gets instantiated with the default constructor, then a new CmdLineParser will be created to parse its annotations.

That's pretty cool so I guess the idea will be to pass in any new objects that I create at the main level and then annotate the additional sub-command options that I need.

public class DeleteCommand extends SubCommand {
    private Session somesession;

    @Option(name="-id",usage="ID to delete")
    private String id = "setme";
    public void execute(Session asession) {
        somesession = asession;
        // do my stuff
    }
}
AndyJ
  • 1,204
  • 3
  • 14
  • 28