diff --git a/README.md b/README.md index 491aece1..4a3568b5 100644 --- a/README.md +++ b/README.md @@ -1 +1,92 @@ -# java-racingcar-precourse \ No newline at end of file +# java-racingcar-precourse +*** +## 패키지 구조 +*** +``` +├── RacingGameApplication.java +├── config +│   └── constant +│   └── Rule.java +├── controller +│   └── RacingGameController.java +├── domain +│   ├── Car.java +│   └── Cars.java +├── exception +│   └── constant +│   └── ErrorMessage.java +├── util +│   └── RandomNumberGenerator.java +├── validator +│   ├── AttemptCountValidator.java +│   └── CarNameValidator.java +└── view + ├── InputView.java + ├── OutputView.java + └── constant + ├── InputMessage.java + └── OutputMessage.java +``` + +### config 패키지 +> 게임 설정과 관련된 파일이 위치합니다. +* `Rule.java` + * 레이싱 게임을 진행함에 있어 지켜야 할 규칙에 대해 상수로 정의합니다. + +### controller 패키지 +> Model과 View를 이어주는 Controller가 위치합니다. +* `RacingGameController.java` + * 레이싱 게임을 진행하기 위한 컨트롤러 + +### domain 패키지 +> 레이싱 게임을 구성하기 위한 도메인이 위치합니다. +* `Car.java` + * 레이싱 게임에 참여하는 한 대의 자동차를 의미합니다. + + +* `Cars.java` + * 레이싱 게임에 참여하는 자동차들의 집합을 의미합니다. + * 자동차의 집합 중 승자를 판단할 수 있습니다. + +### exception 패키지 +> 레이싱 게임 진행 중 발생하는 예외에 대한 정보가 위치합니다. +* `ErrorMessage.java` + * 게임 중 발생하는 예외 메시지에 대해 정의합니다. + +### util 패키지 +> 게임 진행에 필요한 유틸리티 클래스들이 위치합니다. +* `RandomNumberGenerator.java` + * 자동차를 움직이기 위한 난수를 발생시킵니다. + +### validator 패키지 +> 게임에 사용되는 검증기가 위치합니다. +* `AttemptCountValidator.java` + * 레이싱 실행 횟수에 대하여 검증합니다. + * 입력값이 숫자가 맞는지 검증합니다. + * 입력값이 양의 정수가 맞는지 검증합니다. + + +* `CarNameValidator.java` + * 자동차 이름에 대한 검증을 실시합니다. + * 이름이 존재하는지 검증합니다. + * 이름의 길이가 적절한지 검증합니다. + * 이름에 빈 문자열이 있는지 검증합니다. + * 이름 입력에 대해 중복이 존재하는지 검증합니다. + +### view 패키지 +> view 계층이 위치합니다. +* `InputView.java` + * 입력에 필요한 내용을 출력합니다. + * 적절한 입력이 발생할 때까지 사용자로부터 입력을 받습니다. + + +* `OutputView.java` + * 게임의 결과에 대해 출력합니다. + + +* `InputMessage.java` + * 입력에 필요한 메시지를 정의합니다. + + +* `OutputMessage.java` + * 출력에 필요한 메시지를 정의합니다. \ No newline at end of file diff --git a/src/main/java/game/RacingGameApplication.java b/src/main/java/game/RacingGameApplication.java new file mode 100644 index 00000000..e92c4ddd --- /dev/null +++ b/src/main/java/game/RacingGameApplication.java @@ -0,0 +1,18 @@ +package game; + +import game.controller.RacingGameController; +import game.view.InputView; +import game.view.OutputView; +import java.util.Scanner; + +public class RacingGameApplication { + + public static void main(String[] args) { + InputView inputView = new InputView(new Scanner(System.in)); + OutputView outputView = new OutputView(); + RacingGameController racingGameController = new RacingGameController(inputView, outputView); + + racingGameController.startGame(); + } + +} diff --git a/src/main/java/game/config/constant/Rule.java b/src/main/java/game/config/constant/Rule.java new file mode 100644 index 00000000..d42d16b1 --- /dev/null +++ b/src/main/java/game/config/constant/Rule.java @@ -0,0 +1,14 @@ +package game.config.constant; + +public class Rule { + + private Rule() { + } + + public static final String NAME_DELIMITER = ","; + public static final int MAX_NAME_LENGTH = 5; + public static final int MIN_NAME_LENGTH = 1; + public static final int MAX_RANDOM_VALUE = 9; + public static final int MOVEMENT_THRESHOLD = 4; + public static final String CAR_POSITION_MAKER = "-"; +} diff --git a/src/main/java/game/controller/RacingGameController.java b/src/main/java/game/controller/RacingGameController.java new file mode 100644 index 00000000..5088493c --- /dev/null +++ b/src/main/java/game/controller/RacingGameController.java @@ -0,0 +1,33 @@ +package game.controller; + +import game.domain.Cars; +import game.view.InputView; +import game.view.OutputView; +import game.view.constant.OutputMessage; +import java.util.List; + +public class RacingGameController { + + private InputView inputView; + private OutputView outputView; + + public RacingGameController(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void startGame() { + List carNames = inputView.enterCarNames(); + Cars cars = Cars.fromCarNames(carNames); + + int attemptCount = inputView.enterAttemptCount(); + System.out.println(OutputMessage.RESULT); + for (int i = 0; i < attemptCount; i++) { + cars.move(); + outputView.printResult(cars); + } + + outputView.printWinner(cars); + } + +} diff --git a/src/main/java/game/domain/Car.java b/src/main/java/game/domain/Car.java new file mode 100644 index 00000000..1242f635 --- /dev/null +++ b/src/main/java/game/domain/Car.java @@ -0,0 +1,69 @@ +package game.domain; + +import game.config.constant.Rule; +import game.validator.CarNameValidator; +import java.util.Objects; + +public class Car { + + private final String name; + private int position; + + public Car(String name) { + this(name, 0); + } + + public Car(String name, int position) { + CarNameValidator.validateNameLength(name); + this.name = name; + this.position = position; + } + + public String getName() { + return name; + } + + public int getPosition() { + return position; + } + + public int move(int randomValue) { + if(canMove(randomValue)) { + this.position++; + } + return this.position; + } + + private boolean canMove(int randomValue) { + return randomValue >= Rule.MOVEMENT_THRESHOLD; + } + + public boolean isWinner(int maxPosition) { + return position == maxPosition; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Car car = (Car) o; + return position == car.position && Objects.equals(name, car.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, position); + } + + @Override + public String toString() { + return "Car{" + + "name='" + name + '\'' + + ", position=" + position + + '}'; + } +} diff --git a/src/main/java/game/domain/Cars.java b/src/main/java/game/domain/Cars.java new file mode 100644 index 00000000..9dea55c0 --- /dev/null +++ b/src/main/java/game/domain/Cars.java @@ -0,0 +1,91 @@ +package game.domain; + +import game.config.constant.Rule; +import game.exception.constant.ErrorMessage; +import game.util.RandomNumberGenerator; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; + +public class Cars { + + private List carList; + + private Cars(List carList) { + this.carList = carList; + } + + public static Cars fromCarNames(List carNames) { + return new Cars(carNames.stream().map(Car::new).toList()); + } + + public static Cars fromCarList(List carList) { + return new Cars(carList); + } + + public void move() { + carList.forEach(car -> car.move(RandomNumberGenerator.getNumber(Rule.MAX_RANDOM_VALUE))); + } + + public Cars findWinners() { + int maxPosition = getMaxPosition(); + List winners = carList.stream() + .filter(car -> car.isWinner(maxPosition)) + .toList(); + return new Cars(winners); + } + + public int getMaxPosition() { + return carList.stream() + .map(Car::getPosition) + .max(Comparator.naturalOrder()) + .orElseThrow(() -> new NoSuchElementException(ErrorMessage.EMPTY_LIST.getMessage())); + } + + public List getCarNames() { + return carList.stream().map(Car::getName).toList(); + } + + public List getCarList() { + return Collections.unmodifiableList(carList); + } + + /** + * 리스트의 순서와 상관없이 내부 원소만 비교하여 동등성을 판단합니다 + * + * @param o 비교할 Cars 인스턴스 + * @return 동등여부 + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Cars cars = (Cars) o; + return new HashSet<>(carList).equals(new HashSet<>(cars.getCarList())); + } + + @Override + public int hashCode() { + return Objects.hash(carList); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("Cars = "); + carList.forEach(car -> + stringBuilder.append("(") + .append(car.getName()) + .append(", position: ") + .append(car.getPosition()) + .append(")")); + return stringBuilder.toString(); + } +} diff --git a/src/main/java/game/exception/constant/ErrorMessage.java b/src/main/java/game/exception/constant/ErrorMessage.java new file mode 100644 index 00000000..5c7bd50b --- /dev/null +++ b/src/main/java/game/exception/constant/ErrorMessage.java @@ -0,0 +1,22 @@ +package game.exception.constant; + +import static game.config.constant.Rule.*; + +public enum ErrorMessage { + + INVALID_NAME_LENGTH("[ERROR] %d ~ %d 글자를 벗어난 이름이 존재합니다!".formatted(MIN_NAME_LENGTH, MAX_NAME_LENGTH)), + DUPLICATE_NAME_FOUND("[ERROR] 중복된 이름이 존재합니다!"), + INVALID_NUMBER_INPUT("[ERROR] 숫자를 입력해주세요!"), + INVALID_ATTEMPT_COUNT_INPUT("[ERROR] 1 이상의 숫자를 입력해주세요!"), + EMPTY_LIST("[ERROR] 리스트가 비어 있습니다!"); + private final String message; + + ErrorMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + +} diff --git a/src/main/java/game/util/RandomNumberGenerator.java b/src/main/java/game/util/RandomNumberGenerator.java new file mode 100644 index 00000000..929e24ac --- /dev/null +++ b/src/main/java/game/util/RandomNumberGenerator.java @@ -0,0 +1,21 @@ +package game.util; + +import java.util.Random; + +public class RandomNumberGenerator { + + private static Random random = new Random(); + + private RandomNumberGenerator() { + } + + /** + * 파라미터로 전달받은 범위 안에서 무작위 음이 아닌 정수를 반환합니다. + * @param maxRange 난수의 최댓값 + * @return 음이 아닌 정수 + */ + public static int getNumber(int maxRange) { + return random.nextInt(maxRange + 1); + } + +} diff --git a/src/main/java/game/validator/AttemptCountValidator.java b/src/main/java/game/validator/AttemptCountValidator.java new file mode 100644 index 00000000..0ad9b99c --- /dev/null +++ b/src/main/java/game/validator/AttemptCountValidator.java @@ -0,0 +1,31 @@ +package game.validator; + +import game.exception.constant.ErrorMessage; + +/** + * 시도 횟수 입력에 대한 검증기 + */ +public class AttemptCountValidator { + + private AttemptCountValidator() { + } + + public static void validate(String attemptCountInput) { + validateNumberFormat(attemptCountInput); + validatePositiveNumber(attemptCountInput); + } + + private static void validateNumberFormat(String attemptCountInput) { + try { + Integer.parseInt(attemptCountInput); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(ErrorMessage.INVALID_NUMBER_INPUT.getMessage()); + } + } + + private static void validatePositiveNumber(String attemptCountInput) { + if (Integer.parseInt(attemptCountInput) <= 0) { + throw new IllegalArgumentException(ErrorMessage.INVALID_ATTEMPT_COUNT_INPUT.getMessage()); + } + } +} diff --git a/src/main/java/game/validator/CarNameValidator.java b/src/main/java/game/validator/CarNameValidator.java new file mode 100644 index 00000000..824952de --- /dev/null +++ b/src/main/java/game/validator/CarNameValidator.java @@ -0,0 +1,47 @@ +package game.validator; + +import static game.config.constant.Rule.*; + +import game.exception.constant.ErrorMessage; +import java.util.Arrays; + +public class CarNameValidator { + + private CarNameValidator() { + } + + public static void validate(String input) { + validateNameExists(input); + validateNameLength(input); + validateDuplication(input); + } + + private static void validateNameExists(String input) { + String[] names = input.split(NAME_DELIMITER); + if (names.length == 0) { + throw new IllegalArgumentException(ErrorMessage.INVALID_NAME_LENGTH.getMessage()); + } + } + + public static void validateNameLength(String input) { + String[] names = input.split(NAME_DELIMITER); + Arrays.stream(names) + .filter(name -> name.length() > MAX_NAME_LENGTH || name.isBlank()) + .findAny() + .ifPresent(name -> { + throw new IllegalArgumentException(ErrorMessage.INVALID_NAME_LENGTH.getMessage()); + }); + } + + private static void validateDuplication(String input) { + String[] names = input.split(NAME_DELIMITER); + long originalCount = names.length; + long uniqueCount = Arrays.stream(names).distinct().count(); + + if (originalCount != uniqueCount) { + throw new IllegalArgumentException(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); + } + } + +} + diff --git a/src/main/java/game/view/InputView.java b/src/main/java/game/view/InputView.java new file mode 100644 index 00000000..2e7ea63a --- /dev/null +++ b/src/main/java/game/view/InputView.java @@ -0,0 +1,53 @@ +package game.view; + +import game.config.constant.Rule; +import game.validator.AttemptCountValidator; +import game.validator.CarNameValidator; +import game.view.constant.InputMessage; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +public class InputView { + + private final Scanner scanner; + + public InputView(Scanner scanner) { + this.scanner = scanner; + } + + public List enterCarNames() { + String input = ""; + while (input.isBlank()) { + System.out.println(InputMessage.CAR_NAME); + input = scanner.nextLine(); + try { + CarNameValidator.validate(input); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + input = ""; + } + } + return Arrays.asList(input.split(Rule.NAME_DELIMITER)); + } + + /** + * 시도 횟수를 입력 받습니다. + * + * @return 시도 횟수 + */ + public int enterAttemptCount() { + String input = ""; + while (input.isBlank()) { + System.out.println(InputMessage.ATTEMPT_COUNT); + input = scanner.nextLine(); + try { + AttemptCountValidator.validate(input); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + input = ""; + } + } + return Integer.parseInt(input); + } +} diff --git a/src/main/java/game/view/OutputView.java b/src/main/java/game/view/OutputView.java new file mode 100644 index 00000000..5574f880 --- /dev/null +++ b/src/main/java/game/view/OutputView.java @@ -0,0 +1,25 @@ +package game.view; + +import game.config.constant.Rule; +import game.domain.Car; +import game.domain.Cars; +import game.view.constant.OutputMessage; +import java.util.List; + +public class OutputView { + + public void printResult(Cars cars) { + List carList = cars.getCarList(); + carList.forEach(car -> System.out.println(car.getName() + " : " + Rule.CAR_POSITION_MAKER.repeat(car.getPosition()))); + System.out.println(); + } + + public void printWinner(Cars cars) { + System.out.print(OutputMessage.WINNER); + Cars winners = cars.findWinners(); + String result = String.join(", ", winners.getCarNames()); + + System.out.println(result); + } + +} diff --git a/src/main/java/game/view/constant/InputMessage.java b/src/main/java/game/view/constant/InputMessage.java new file mode 100644 index 00000000..ef89fc63 --- /dev/null +++ b/src/main/java/game/view/constant/InputMessage.java @@ -0,0 +1,17 @@ +package game.view.constant; + +public enum InputMessage { + CAR_NAME("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)"), + ATTEMPT_COUNT("시도할 회수는 몇회인가요?"); + + private final String description; + + InputMessage(String description) { + this.description = description; + } + + @Override + public String toString() { + return description; + } +} diff --git a/src/main/java/game/view/constant/OutputMessage.java b/src/main/java/game/view/constant/OutputMessage.java new file mode 100644 index 00000000..331c6ea9 --- /dev/null +++ b/src/main/java/game/view/constant/OutputMessage.java @@ -0,0 +1,19 @@ +package game.view.constant; + +public enum OutputMessage { + + RESULT("실행 결과"), + WINNER("최종 우승자 : "); + + private final String description; + + OutputMessage(String description) { + this.description = description; + } + + @Override + public String toString() { + return description; + } + +} diff --git a/src/test/java/game/domain/CarTest.java b/src/test/java/game/domain/CarTest.java new file mode 100644 index 00000000..faec0e79 --- /dev/null +++ b/src/test/java/game/domain/CarTest.java @@ -0,0 +1,47 @@ +package game.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class CarTest { + + @ParameterizedTest(name = "{0}은 난수 {1} 일 때 전진합니다") + @MethodSource("getMovableCar") + void movableCar(Car car, int movementValue) { + assertThat(car.getPosition()).isZero(); + assertThat(car.move(movementValue)).isEqualTo(1); + } + + @ParameterizedTest(name = "{0}은 난수 {1} 일 때 전진하지 않습니다") + @MethodSource("getUnmovableCar") + void unmovableCar(Car car, int movementValue) { + assertThat(car.getPosition()).isZero(); + assertThat(car.move(movementValue)).isZero(); + } + + static Stream getMovableCar() { + return Stream.of( + Arguments.arguments(new Car("enzo"), 4), + Arguments.arguments(new Car("enzo"), 5), + Arguments.arguments(new Car("enzo"), 6), + Arguments.arguments(new Car("enzo"), 7), + Arguments.arguments(new Car("enzo"), 8), + Arguments.arguments(new Car("enzo"), 9) + ); + } + + static Stream getUnmovableCar() { + return Stream.of( + Arguments.arguments(new Car("enzo"), 0), + Arguments.arguments(new Car("enzo"), 1), + Arguments.arguments(new Car("enzo"), 2), + Arguments.arguments(new Car("enzo"), 3) + ); + } + + +} \ No newline at end of file diff --git a/src/test/java/game/domain/CarsTest.java b/src/test/java/game/domain/CarsTest.java new file mode 100644 index 00000000..5f3b6570 --- /dev/null +++ b/src/test/java/game/domain/CarsTest.java @@ -0,0 +1,54 @@ +package game.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class CarsTest { + + @ParameterizedTest(name = "{0}의 최대 위치는 {1} 입니다") + @MethodSource("getCarAndMaxPosition") + void getMaxPosition(Cars cars, int maxPosition) { + assertThat(cars.getMaxPosition()).isEqualTo(maxPosition); + } + + private static Stream getCarAndMaxPosition() { + int maxPosition = 5; + + List carList = new ArrayList<>(); + carList.add(new Car("enzo", maxPosition)); + carList.add(new Car("gusto", 3)); + carList.add(new Car("james", 1)); + + return Stream.of( + Arguments.arguments(Cars.fromCarList(carList), maxPosition) + ); + } + + @ParameterizedTest(name = "{0}의 경주 결과 승자는 {1}입니다") + @MethodSource("getCarListAndWinner") + void findWinner(Cars cars, Cars winners) { + assertThat(cars.findWinners()).isEqualTo(winners); + } + + private static Stream getCarListAndWinner() { + List carList = new ArrayList<>(); + carList.add(new Car("enzo", 5)); + carList.add(new Car("gusto", 5)); + carList.add(new Car("james", 1)); + + List winners = new ArrayList<>(); + winners.add(new Car("enzo", 5)); + winners.add(new Car("gusto", 5)); + + return Stream.of( + Arguments.arguments(Cars.fromCarList(carList), Cars.fromCarList(winners)) + ); + } + +} \ No newline at end of file diff --git a/src/test/java/game/validator/AttemptCountValidatorTest.java b/src/test/java/game/validator/AttemptCountValidatorTest.java new file mode 100644 index 00000000..19ebc991 --- /dev/null +++ b/src/test/java/game/validator/AttemptCountValidatorTest.java @@ -0,0 +1,34 @@ +package game.validator; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import game.exception.constant.ErrorMessage; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class AttemptCountValidatorTest { + + @ParameterizedTest(name = "{0}은 적절한 시도 횟수 입력입니다") + @ValueSource(strings = {"5", "10", "100"}) + void 적절한_시도_횟수_입력에_대해_예외를_던지지_않습니다(String input) { + assertDoesNotThrow(() -> AttemptCountValidator.validate(input)); + } + + @ParameterizedTest(name = "{0}은 숫자가 아닌 입력") + @ValueSource(strings = {"thiago,sil", "enzo", "a", "", " "}) + void 숫자가_아닌_입력값에_대하여_예외를_발생시킵니다(String input) { + assertThatThrownBy(() -> AttemptCountValidator.validate(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.INVALID_NUMBER_INPUT.getMessage()); + } + + @ParameterizedTest(name = "{0}은 1보다 작은 입력") + @ValueSource(strings = {"-1", "-100", "-99999", "0"}) + void 입력이_1보다_작은_입력값에_대하여_예외를_발생시킵니다(String input) { + assertThatThrownBy(() -> AttemptCountValidator.validate(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.INVALID_ATTEMPT_COUNT_INPUT.getMessage()); + } + +} \ No newline at end of file diff --git a/src/test/java/game/validator/CarNameValidatorTest.java b/src/test/java/game/validator/CarNameValidatorTest.java new file mode 100644 index 00000000..8c6bc258 --- /dev/null +++ b/src/test/java/game/validator/CarNameValidatorTest.java @@ -0,0 +1,33 @@ +package game.validator; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import game.exception.constant.ErrorMessage; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +class CarNameValidatorTest { + + @ParameterizedTest(name = "{0}은 적절한 이름 입력입니다") + @ValueSource(strings = {"en.zo,silva,james", "silva", "_enzo,en zo,enzo "}) + void 적절한_이름_입력에_대해_예외를_던지지_않습니다(String input) { + assertDoesNotThrow(() -> CarNameValidator.validate(input)); + } + + @ParameterizedTest(name = "{0}은 부적절한 길이의 이름이 존재합니다") + @ValueSource(strings = {"thiago,sil ", "en ,zo", ",,,,", " "}) + void 부적절한_이름_길이는_예외를_발생시킵니다(String input) { + assertThatThrownBy(() -> CarNameValidator.validate(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.INVALID_NAME_LENGTH.getMessage()); + } + + @ParameterizedTest(name = "{0}은 중복이 존재하는 이름 입력입니다") + @ValueSource(strings = {"enzo,bruno,enzo", "james,james,james"}) + void 중복이_존재하는_이름은_예외를_발생시킵니다(String input) { + assertThatThrownBy(() -> CarNameValidator.validate(input)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorMessage.DUPLICATE_NAME_FOUND.getMessage()); + } +} \ No newline at end of file