1

I am trying to make a CLI with user input to choose from the options available. I am using a switch and while loop to ensure that it can go back to main menu after choosing an option. The problem is that after a user is successfully logged in, it will go to case 4, but it repeats (infinitely) case 4 and I am not sure why.

Here is the code:

public class MainApplication {

    private static User userLoggedIn;
    private static Device deviceLoggedIn;
    private static PrivateKey privateKey;
    private static AbePrivateKey secretKey;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
//      CpabeDAO.em.getTransaction().begin();

        System.out.println("Welcome to CPABE Cloud");

        int test = 0;
        while (true){
            switch(test){
            case 0: //Greeting for the user. User now chooses the option.
                System.out.println("Please choose the option by typing the option number:");
                System.out.println("(1) Login");
                System.out.println("(2) Register User");
                System.out.println("(3) Exit");
                int input = scanner.nextInt();
                if(input < 0 ||  input > 3){
                    System.out.println("Unrecognized input.");
                    test = 0;
                }
                else {
                    test = input;
                }
                break;
            case 1:
                System.out.println("Login");
                List<User> userRetrieve = login();
                //check if it is successfully logged in
                boolean loggedIn = (userRetrieve.size() == 0);
                if(!loggedIn) {
                    for(User user : userRetrieve) {
                        userLoggedIn = user;
                    }
                    //Retrieve private key & secret key from cpabe dir, if it is not stored then register new device. After that go to case 4, which is the main menu;
                    test = 4;
                }
                else{ 
                    System.out.println("Your username or password is incorrect. Please choose what to do next:");
                    System.out.println("(1) Login");
                    System.out.println("(2) Back to main menu");
                    int input2 = scanner.nextInt();
                    if(input2 == 1){
                        test = 1;
                    }
                    else if(input2 == 2){
                        test = 0;
                    }
                }
                break;
            case 2:
                System.out.println("Register User");                        

                userLoggedIn = UserRegistration.registerUser();
                 DeviceRegistration.registerNewDeviceforNewUser(userLoggedIn);

                test = scanner.nextInt();   
                break;
            case 3:
                System.out.println("Exit");
                System.out.println("Press 0 to go back to menu");
                test = scanner.nextInt();           
                break;
            case 4: //the main menu. user can have full functionalities after logging in or registering.
                System.out.println("Welcome " + userLoggedIn.getFirstname());
                System.out.println("Please select the option by typing the option number:");
                break;
             default :
                System.out.println("Invalid input. Please insert the correct input.");
                test = 0;
            }
        }
    }

    private static List<User> login(){
        Scanner scanner = new Scanner(System.in);
        System.out.println("Please enter your username:");
        String username = scanner.nextLine();
        System.out.println("Please enter your password:");
        String password = scanner.nextLine();       
        String hashPassword = Encryption.generateHash(password.getBytes());
        Query q = CpabeDAO.em.createQuery("SELECT u FROM User u WHERE u.username = '" + username + "' and u.hashPassword = '" + hashPassword + "'");
        List<User> userRetrieve = q.getResultList();
        scanner.close();
        return userRetrieve;
    }

What I want to achieve is that after user is successfully logged in then the system will go to case 4, which is the main menu, and wait for user's input but instead it keeps repeating the case 4.

Ihsan Haikal
  • 1,085
  • 4
  • 16
  • 42
  • 4
    You are in fact using an infinite loop. `break` in your case will just break switch block and not `while` loop. – Abubakkar Feb 20 '17 at 15:00
  • @Abubakkar But what I imagined is that after successfully logged in then it should go to case 4 and stops the program, but instead it keeps looping on the case 4. – Ihsan Haikal Feb 20 '17 at 15:08
  • @IhsanHaikal and where in your code do you do anything that would "stop the program"? – OH GOD SPIDERS Feb 20 '17 at 15:13
  • @911DidBush well what I mean by "stop the program" is that it will print case 4 and wait for user's input that will go to another case. – Ihsan Haikal Feb 20 '17 at 15:15
  • 1
    @IhsanHaikal well, then you should have written your programm to reset test to `int test = 0;` inside your while loop. Currently once it is set to 4, it has not way of ever getting set to something else. – OH GOD SPIDERS Feb 20 '17 at 15:18
  • @911DidBush I already put int test = 0 inside the while loop but then it will never goes from case 0 for any option that I choose. – Ihsan Haikal Feb 20 '17 at 15:24
  • 1
    You are missing the `test = scanner.nextInt();` in case 4 – TryingToImprove Feb 20 '17 at 15:35
  • @TryingToImprove I already have it but not including it as it will give me Exception in thread "main" java.util.NoSuchElementException in case 4 – Ihsan Haikal Feb 20 '17 at 15:37

1 Answers1

1

As @Abubakkar said, you can't break your loop from a switch. Also you stay in the fourth case because you never change the test value, you never ask for another value from the scanner, so it stay at 4. You should put it back to 0 directly from the switch if you want to go back in your menu. You could do that:

    boolean firstMenu = true;
    boolean secondmenu = false;
    while(firstMenu){
        [...]
        case 4: //the main menu. user can have full functionalities after logging in or registering.
            System.out.println("Welcome " + userLoggedIn.getFirstname());
            System.out.println("Please select the option by typing the option number:");
            firstMenu = false;
            secondMenu = true;
            break;
        }
        [...]
    }
    while(secondMenu){
        [Your second menu]
    }

See This, it could help you to go out from the loop, the first and the second answer are great options to fix your problem :)

Community
  • 1
  • 1
Laurent-P
  • 145
  • 1
  • 9
  • What I think is that after log in then it will go to case 4. Case 4 basically is the main menu after user has logged in then it will wait for another user's input then go to other cases. Case 0 basically is the greeting for the user and choose whether user wants to login or register. Maybe I am not getting your idea right, but I dont want go out of the loop itself but continue working on the loop to retrieve user's input. – Ihsan Haikal Feb 20 '17 at 15:31
  • 1
    Then maybe you should go out of the first loop to "open" a new menu in another loop? – Laurent-P Feb 20 '17 at 15:36
  • Could you give an example based on my question? I dont understand what you mean by that. – Ihsan Haikal Feb 20 '17 at 15:38
  • I changed my answer, did you understand what I mean now? – Laurent-P Feb 20 '17 at 15:48
  • I understand now what you mean, so the switch case will be on the [...] right? But what if on the second menu you want to go back to first menu (in case of log out) and it will go to case 0 in the first menu? – Ihsan Haikal Feb 20 '17 at 15:54
  • never mind that, thanks to your answer now this resolves my question. Thanks! – Ihsan Haikal Feb 20 '17 at 16:29