0

I have two enums, one for apps and one for environments. I want to be able to give the arguments for these in any order, so I can give either -app app1 app1 -env env1 env2 or -env env1 env2 -app app1 app2. Right now I can only do the first one. I would also like to be able to just say -app app1 app2 and it runs all the apps I list in all environments and the same for the environments but I'm more concerned about being able to give them in either order.

 for(int i = 0; i<args.length; i++)
            {
                if(args[i].equals("-app"))
                {
                    indexOfApp = i;
                }else if(args[i].equals("-env"))
                {
                    indexOfEnv = i;
                }
            }

            int countOfApp = -1;
            int countOfEnv = -1;

            if(indexOfApp != -1 && indexOfEnv != -1)
            {
                countOfApp = indexOfEnv - 1;
                countOfEnv = args.length - (indexOfEnv + 1);
            }


            System.out.println(countOfApp);

            System.out.println(countOfEnv);

            for(int appIndex = indexOfApp + 1; appIndex < countOfApp + 1; appIndex++){
                appList.add(args[appIndex]);

            }
                for(String item : appList )
                {
                    Application app = Application.valueOf(Application.class, item);
                    appList2.add(app);
                }
            for(int envIndex = indexOfEnv + 1; envIndex < args.length; envIndex++){
                envList.add(args[envIndex]);

            }
            for(String item : envList )
            {
             Environment env = Environment.valueOf(Environment.class, item);
                envList2.add(env);
            }

            }    System.out.println(appList); System.out.println(envList);
        Application.chooseAppTest(appList2, envList2);
mschenk74
  • 3,561
  • 1
  • 21
  • 34
John
  • 75
  • 1
  • 2
  • 11
  • 4
    Why not use a library? JOpt, Commons CLI, JCommander, Args4j, ... Most of these will provide what your looking for out of the box. – Robby Cornelissen Aug 04 '14 at 14:45
  • I found a pretty long list of command line argument parsers: http://stackoverflow.com/a/7829772/10077 – Fred Larson Aug 04 '14 at 14:46
  • @RobbyCornelissen I was told by my manager (I'm just an intern) that it would normally be better to use a library but using it now would make running it how they want to complicated. – John Aug 04 '14 at 14:47
  • I know it sounds dumb but I am supposed to reinvent the wheel here. – John Aug 04 '14 at 14:48

5 Answers5

1

It can be much more simple :

boolean isApp = false;
boolean isEnv = false;

for (int i = 0; i<args.length; i++) {
    if (args[i].equals ("-app")) {
        isApp = true;
        isEnv = false;
    } else if (args[i].equals ("-env")) {
        isEnv = true;
        isApp = false;
    } else if (isEnv) {
        envList.add(args[i]);
    } else if (isApp) {
        appList.add(args[i]);
    }
}
Eran
  • 387,369
  • 54
  • 702
  • 768
1

This solution is scalable because it's not harcoded:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    // this method does all the work
    static private String[] getArgs(String argArray[],String indicator){            
        String arguments="";
        for (String s: argArray){
            arguments = arguments + s +" ";
        }
        arguments = arguments.trim();
        Pattern p = Pattern.compile(indicator+" ([^\\-]*)");    
        Matcher m = p.matcher(arguments);
        String[] newArgs={};
        try {
            m.find();
            newArgs = m.group(1).split(" ");
        } catch (IllegalStateException e){              
        }               
        return newArgs;         
    }

    public static void main (String args[]){            
        System.out.println("ENVS");
        String[] e=getArgs(args,"-env");
        for (String s: e){
            System.out.println(s);
        }           
        System.out.println("APPS");
        e=getArgs(args,"-app");
        for (String s: e){
            System.out.println(s);
        }               
    }
}

Example outputs:

java Main -env env1 env2 env3 -app app1 app2
ENVS
env1
env2
APPS
app1
app2


java Main -app app1 app2 app3 app4 -env env1 env2
ENVS
env1
env2
APPS
app1
app2
app3
app4


java Main -app app1 app2
ENVS
APPS
app1
app2
Tulains Córdova
  • 2,559
  • 2
  • 20
  • 33
0

Implementing this yourself is pretty easy. Use the leading - as an indicator.
Try this code. I think this is what you want. This solution is very general too,
it will work even if you add other argument types later (not just -app and -env).

import java.util.HashMap;
import java.util.ArrayList;


public class Test006 {

    public static void main(String[] args) {
        System.out.println(args.length);

        HashMap<String, ArrayList<String>> mp = 
        new HashMap<String, ArrayList<String>>();

        String key = "";
        for (int i=0; i<args.length; i++){
            if (args[i].startsWith("-")){
                mp.put(args[i], new ArrayList<String>());
                key = args[i];
            }else{
                mp.get(key).add(args[i]);
            }
        }

        for (String k : mp.keySet()){
            System.out.println("---->" + k);
            for (String s : mp.get(k)){
                System.out.println("///" + s);
            }
        }
    }

}

OUTPUT:

C:\Programs\eclipse\workspace\_TEST>java -cp ./bin Test006 -app a1 a2 -env e1 e2
6
---->-env
///e1
///e2
---->-app
///a1
///a2

C:\Programs\eclipse\workspace\_TEST>java -cp ./bin Test006 -env e1 e2 -app a1 a2
6
---->-env
///e1
///e2
---->-app
///a1
///a2

C:\Programs\eclipse\workspace\_TEST>
peter.petrov
  • 38,363
  • 16
  • 94
  • 159
0

Last week someone gave you an answer to another version of this question, which you've asked three or four times now, that will do exactly what you want. I can't find it now (it may have been deleted), but it was essentially this code:

public static void main(String[] args) {
    List<String> apps = new ArrayList<>();
    List<String> envs = new ArrayList<>();
    List<String> destination = null;

    for (String arg : args) {
        if ("-app".equals(arg)) {
            destination = apps;
        } else if ("-env".equals(arg)) {
            destination = envs;
        } else if (destination == null) {
            System.out.printf("Invalid argument: %s%n", arg);
        } else {
            destination.add(arg);
        }
    }
}

I don't understand why you ignored this solution, since it does exactly what you want. (At that time, you were asking about splitting strings into arrays, for some strange reason.)

You could do this instead:

public static void main(String[] args) {
    List<Application> apps = new ArrayList<>();
    List<Environment> envs = new ArrayList<>();
    boolean appFlag = false;
    boolean envFlag = false;

    for (String arg : args) {
        if ("-app".equals(arg)) {
            appFlag = true;
            envFlag = false;
        } else if ("-env".equals(arg)) {
            envFlag = true;
            appFlag = false;
        } else if (appFlag) {
            apps.add(Application.valueOf(arg));
        } else if (envFlag) {
            envs.add(Environment.valueOf(arg));
        } else {
            System.out.printf("Invalid argument: %s%n", arg);
        }
    }
    Application.chooseAppTest(apps, envs);
}
David Conrad
  • 15,432
  • 2
  • 42
  • 54
  • I wasn't ignoring them. Obviously they didn't work like I needed them too. I promise I tried what people gave me and I tried tweaking them to do what I needed. I asked about splitting strings because that is how I was originally told to do this assignment. If you would've just helped me like this to begin with it wouldn't have been a problem. Thank you. – John Aug 04 '14 at 15:12
0

Here is what I would have done:

1. Create an enum - any additional parameter you want to add should just be added in this list

enum Args {

    ENV("-env"),

    APP("-app"),

    NONE("");

    String argCode;

    /**
     * @return the argCode
     */
    public String getArgCode() {
        return argCode;
    }

    Args(String argCode){
        this.argCode = argCode;
    }

    /**
     * @param str
     * @return
     */
    public static Args getArgs(String str){
        for (Args arg : Args.values()){
            if (arg.getArgCode().equalsIgnoreCase(str)){
                return arg;
            }
        }

        return NONE;
    }

}

2. Now have the following - these lines run to prepare a map with the parameter name as key and it's values as a list of values

public static void main(String[] args) {

    HashMap <String, ArrayList<String>> argMap = new HashMap<String, ArrayList<String>>();

    String argCode = null;

    for (String arg: args){
        Args a = Args.getArgs(arg);

        if (!a.equals(Args.NONE)){
            argCode = a.getArgCode();
            continue;
        }

        ArrayList<String> argList = argMap.get(argCode);

        if (argList == null){
            argList = new ArrayList<String>();

            argMap.put(argCode, argList);
        }

        argList.add(arg);
    }

    System.out.println(argMap.toString());

}

3. Below is the output: use the map to get the list of values

{-env=[env1, env2], -app=[app1, app1]}

Just in case you have another parameter added to the list say "-sample" just add to the list of enum as below:

    ENV("-env"),

    APP("-app"),

    Sample("-sample"),

    NONE("");

and the map will have this key value pair as well.

Following will also work:

-env env1 -app app1 -env env2 -app app2

If you don't want the above to work, check for repetition of keys in the main method. Hope the answer is helpful.

Anshuman
  • 831
  • 5
  • 18