-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6e85dfd
commit 057efa2
Showing
17 changed files
with
420 additions
and
108 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
src/main/java/de/cofinpro/cars/controller/AbstractMenuController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package de.cofinpro.cars.controller; | ||
|
||
|
||
import de.cofinpro.cars.io.ConsolePrinter; | ||
import de.cofinpro.cars.io.NamedItem; | ||
|
||
import java.util.List; | ||
import java.util.Scanner; | ||
|
||
/** | ||
* Abstract controller class for menu looping over enum based menu actions, that takes the enum E as type parameter. | ||
* Since this class provides methods for handling integer-choice based menus including the action loop and calling | ||
* the menu item's action, new menus can be added very easily. The customization is done by abstract framework methods. | ||
*/ | ||
abstract class AbstractMenuController<E extends Enum<E>> { | ||
|
||
protected final ConsolePrinter printer; | ||
protected final Scanner scanner; | ||
|
||
protected AbstractMenuController(ConsolePrinter consolePrinter, Scanner scanner) { | ||
this.printer = consolePrinter; | ||
this.scanner = scanner; | ||
} | ||
|
||
/** | ||
* abstract getter to implement in subclass. | ||
* @return the menu text to display when prompting for a user choice | ||
*/ | ||
protected abstract String getMenuText(); | ||
|
||
/** | ||
* abstract action getter for choice to implement in subclass. | ||
* @param choice user's choice as enum constant of type parameter E | ||
* @return the action to run for the user's choice | ||
*/ | ||
protected abstract Runnable getMenuAction(E choice); | ||
|
||
/** | ||
* abstract getter with which subclasses must tell this controller, which is the menu option to leave the menu | ||
*/ | ||
protected abstract E getExitChoice(); | ||
|
||
/** | ||
* entry point method doing the menu loop and triggering the actions chosen. | ||
*/ | ||
public void run() { | ||
var choice = getMenuChoice(); | ||
while (choice != getExitChoice()) { | ||
getMenuAction(choice).run(); | ||
choice = getMenuChoice(); | ||
} | ||
} | ||
|
||
protected int chooseFromList(List<? extends NamedItem> items, String itemType) { | ||
if (items.isEmpty()) { | ||
printer.printInfo("The {} list is empty!\n", itemType); | ||
return 0; | ||
} | ||
printItemsMenu(items, itemType); | ||
var choice = Integer.parseInt(scanner.nextLine()); | ||
printer.printInfo(""); | ||
return choice; | ||
} | ||
|
||
private void printItemsMenu(List<? extends NamedItem> items, String itemType) { | ||
printer.printInfo("Choose a {}:", itemType); | ||
printer.printEnumeratedList(items); | ||
printer.printInfo("0. Back"); | ||
} | ||
|
||
/** | ||
* user interaction method, that displays the menu and prompts for the users integer choice. | ||
* @return the choice as enum constant of the enum type parameter. | ||
*/ | ||
private E getMenuChoice() { | ||
printer.printInfo(getMenuText()); | ||
var menuOptions = getExitChoice().getDeclaringClass().getEnumConstants(); | ||
var choice = menuOptions[Integer.parseInt(scanner.nextLine())]; | ||
printer.printInfo(""); | ||
return choice; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
src/main/java/de/cofinpro/cars/controller/CustomerMenu.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package de.cofinpro.cars.controller; | ||
|
||
import de.cofinpro.cars.io.ConsolePrinter; | ||
import de.cofinpro.cars.persistence.Customer; | ||
import de.cofinpro.cars.service.CarService; | ||
import de.cofinpro.cars.service.CompanyService; | ||
import de.cofinpro.cars.service.CustomerService; | ||
import lombok.Setter; | ||
import org.springframework.stereotype.Controller; | ||
|
||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Scanner; | ||
|
||
@Controller | ||
public class CustomerMenu extends AbstractMenuController<CustomerMenu.Choice> { | ||
|
||
public static final String NO_CAR_RENT = "You didn't rent a car!\n"; | ||
private final CustomerService customerService; | ||
private final CompanyService companyService; | ||
private final CarService carService; | ||
@Setter | ||
private Customer customer; | ||
|
||
protected CustomerMenu(ConsolePrinter consolePrinter, | ||
Scanner scanner, | ||
CustomerService customerService, | ||
CompanyService companyService, | ||
CarService carService) { | ||
super(consolePrinter, scanner); | ||
this.customerService = customerService; | ||
this.companyService = companyService; | ||
this.carService = carService; | ||
} | ||
|
||
@Override | ||
protected String getMenuText() { | ||
return """ | ||
1. Rent a car | ||
2. Return a rented car | ||
3. My rented car | ||
0. Back"""; | ||
} | ||
|
||
@Override | ||
protected Runnable getMenuAction(Choice choice) { | ||
return Map.<Choice, Runnable>of( | ||
Choice.RENT, this::rentCar, | ||
Choice.RETURN, this::returnCar, | ||
Choice.SHOW, this::showCar | ||
).get(choice); | ||
} | ||
|
||
@Override | ||
protected Choice getExitChoice() { | ||
return Choice.EXIT; | ||
} | ||
|
||
private void rentCar() { | ||
if (Objects.nonNull(customer.getRentedCar())) { | ||
printer.printInfo("You've already rented a car!\n"); | ||
return; | ||
} | ||
var companies = companyService.getCompanies(); | ||
var index = chooseFromList(companies, "company"); | ||
var companySelected = companies.get(index - 1); | ||
var cars = carService.getAvailableCars(companySelected.getId()); | ||
index = chooseFromList(cars, "car"); | ||
if (index > 0) { | ||
var car = cars.get(index - 1); | ||
customerService.rentCar(customer, car); | ||
printer.printInfo("You rented '{}'\n", car.getName()); | ||
} | ||
} | ||
|
||
private void returnCar() { | ||
if (Objects.isNull(customer.getRentedCar())) { | ||
printer.printInfo(NO_CAR_RENT); | ||
return; | ||
} | ||
customerService.returnCar(customer); | ||
printer.printInfo("You've returned a rented car!\n"); | ||
} | ||
|
||
private void showCar() { | ||
if (Objects.isNull(customer.getRentedCar())) { | ||
printer.printInfo(NO_CAR_RENT); | ||
return; | ||
} | ||
printer.printInfo("Your rented car:"); | ||
printer.printInfo(customer.getRentedCar().getName()); | ||
printer.printInfo("Company:"); | ||
printer.printInfo("{}\n", customer.getRentedCar().getCompany().getName()); | ||
} | ||
|
||
protected enum Choice { | ||
EXIT, | ||
RENT, | ||
RETURN, | ||
SHOW | ||
} | ||
} |
Oops, something went wrong.