0

I am working on a Spring Shell project. The tool is a command line tool to manipulate data in a database. There are commands like add user (which adds a record to a table in database). In order to execute any commands the user of the tool has to be connected to the database. I would like to be able to run this all in one line. The user of my tool should be able to write a command like the following.

--database connection string xyz --username abc --password mno add user --username bob --role AA_ADMIN --company Microsoft

Here the three parameters database connection string, username and password are required to run the add user command.

Below I have included some sample code it is from the spring shell reference docs

package commands;

import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
import org.springframework.stereotype.Component;

@Component
public class UserManipulation implements CommandMarker {

    private boolean simpleCommandExecuted = false;

@CliAvailabilityIndicator({"hw simple"})
public boolean isSimpleAvailable() {
    //always available
    return true;
}

@CliAvailabilityIndicator({"hw complex", "hw enum"})
public boolean isComplexAvailable() {
    if (simpleCommandExecuted) {
        return true;
    } else {
        return false;
    }
}

@CliCommand(value = "hw simple", help = "Print a simple hello world message")
public String simple(
        @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message,
        @CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello", specifiedDefaultValue="At work") final String location) {
    simpleCommandExecuted = true;
    return "Message = [" + message + "] Location = [" + location + "]";
}

@CliCommand(value = "hw complex", help = "Print a complex hello world message")
public String hello(
        @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message,
        @CliOption(key = { "name1"}, mandatory = true, help = "Say hello to the first name") final String name1,
        @CliOption(key = { "name2" }, mandatory = true, help = "Say hello to a second name") final String name2,
        @CliOption(key = { "time" }, mandatory = false, specifiedDefaultValue="now", help = "When you are saying hello") final String time,
        @CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello") final String location) {
    return "Hello " + name1 + " and " + name2 + ". Your special message is "  + message + ". time=[" + time + "] location=[" + location + "]";
}

@CliCommand(value = "hw enum", help = "Print a simple hello world message from an enumerated value")
public String eenum(
        @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final MessageType message){
    return "Hello.  Your special enumerated message is " + message;
}

enum MessageType {
    Type1("type1"),
    Type2("type2"),
    Type3("type3");

    private String type;

    private MessageType(String type){
        this.type = type;
    }

    public String getType(){
        return type;
    }
}

}

So currently, hw simple is a command that is required to be executed before running hw complex or hw enum command. I do not want hw simple to be a command instead it the message parameter within the hw simple command should be a parameter that is required as a prerequisite to run hw complex or hw enum. So for example the command that I would like to run is.

--message hw complex --message abc --name1 def --name2 ghi --time 7:98 --location: Seattle

Does anyone know how to do this? If it is not possible to do this I would like to hear that or any alternative ideas if possible.

user3108671
  • 83
  • 1
  • 2
  • 10

1 Answers1

2

You have 2 options here:

  • either make those 3 additional parameters (database, username, password) parameters of each and every command that require them (note that in your particular example, you would need to rename one of those username parameters [the one to connect to the DB, or the one that represents the user to add] as you can't have 2 parameters with the same name obviously).
  • Use the @CliAvailabilityIndicator approach, similar to what is described in the example, where a first command (maybe named use or connect) first tests the connection with the 3 given parameters and stores them somewhere, so that any further "real" command (such as add user) can use those values.

Also note that you can actually use a combination of the two (i.e. use solution 2 to provide defaults, that may be overridden on a case by case basis by solution 1).

Lastly, please note that you'll never be able to have something like what you describe at the beginning of your question, as command names must be at the beginning and they can't contain -- (options do)

ebottard
  • 1,997
  • 2
  • 12
  • 14