简体   繁体   中英

Code Structure for Parsing Command line Arguments in Java

I have a question regarding structuring of code.

I have let us say three types of packages A,B and C.

Now, classes in package A contains classes which contain the main() function. These classes need some command line arguments to run.

In package B, there are classes which contains some public variables, which need to be configured, at different times. For example before calling function A, the variable should be set or reset, the output differs according to this variable.

In package C, uses the classes in package B to perform some tasks. They do configure their variables as said before. Not only when the object is created, but also at intermediate stage.

Package A also has classes which in turn use classes from package B and package C. In order to configure the variables in classes of B and C, class in package A containing the main() function, reads command line arguments and passes the correct values to respective class.

Now, given this scenario, I want to use Apache Commons CLI parser.

I am unable to understand how exactly I should write my code to be structured in an elegant way. What is a good design practice for such scenario.

Initially I wrote a class without Apache to parse the command line arguments.

Since I want a suggestion on design issue, I will give an excerpt of code rather than complete code.

public class ProcessArgs 
{
     private String optionA= "default";
     private String optionB= "default";
     private String optionC= "default";

     public void printHelp ()
     {
         System.out.println ("FLAG : DESCRIPTION : DEFAULT VALUE");
         System.out.println ("-A <Option A> : Enable Option A : " + optionA);
         System.out.println ("-B <Option B> : Enable Option B : " + optionB);
         System.out.println ("-C <Option C> : Enable Option C : " + optionC); 
     }

     public void printConfig()
     {
         System.out.println ("Option A " + optionA);
         System.out.println ("Option B " + optionB);
         System.out.println ("Option C " + optionC);
     }

     public void parseArgs (String[] args)
     {
        for (int i=0;i<args.length;i++)
        {
        if (args[i].equalsIgnoreCase ("-A"))
           optionA = args[++i];
        else if (args[i].equalsIgnoreCase ("-B"))
           optionB = args[++i];
        else if (args[i].equalsIgnoreCase ("-C"))
           optionC = args[++i];
        else
           throw new RuntimeException ("Wrong Argument : " + args[i] + " :: -h for Help.");
    }
     }
}

Points to note -

  • I already have 50+ command line options and they are all in one place.
  • Every class uses only a group of command line options.

I tried to write an interface, somehow but I am unsuccessful. I am not sure if this is a good way to do it or not. I need some design guidelines.

Here is the code which I wrote -

public interface ClassOptions 
{
    Options getClassOptions();
    void setClassOptions(Options options);
}

public class Aclass implements ClassOptions
{
    private String optionA="defaultA";
    private String optionB="defaultB";

    public Options getClassOptions()
    {
        Options options = new Options();    

        options.addOption("A", true, "Enable Option A");
        options.addOption("B", true, "Enable Option B");        

        return options;
    }

    public void setClassOptions(Options options, String args[])
    {
        CommandLineParser parser = new BasicParser();
        CommandLine cmd=null;
        try 
        {
            cmd = parser.parse( options, args);
        } catch (ParseException e) 
        {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            System.out.println("ignored option");
        }

        if(cmd.hasOption("A"))
            optionA = "enabled";

        if(cmd.hasOption("B"))
            optionB = "enabled";    
    }
}

I think the problems in such writing of code are -

  • There are different types of arguments like int, double, string, boolean. How to handle them all.
  • getClassOption() and setClassOption() both contain the arguments "A", "B" for example. This code is prone to errors made while writing code, which I would like to eliminate.
  • I think the code is getting repetitive here, which could be encapsulated somehow in another class.
  • Not all the arguments are required, but can be ignored.

Thank You !

I would recommend to you JCommander.

I think it's a really good Argument Parser for Java.

You define all the Argument stuff within annotations and just call JCommander to parse it. On top of that it also (based on your annotations) can print out the corresponding help page. You don't have to take care about anything.

I believe you will love it! :)

Take a look at it: http://jcommander.org/ There are a lot of examples and such!

Good Luck! :)

simple example for command line argument

class CMDLineArgument
{
    public static void main(String args[])
    {
    int length=args.length();
    String array[]=new String[length];
    for(int i=0;i<length;i++)
    {
        array[i]=args[i];
    }
    for(int i=0;i<length;i++)
    {
        System.out.println(array[i]);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM