diff --git a/src/main/java/org/sopt/week1/DiaryController.java b/src/main/java/org/sopt/week1/DiaryController.java index ea52a8d..72df9b2 100644 --- a/src/main/java/org/sopt/week1/DiaryController.java +++ b/src/main/java/org/sopt/week1/DiaryController.java @@ -35,6 +35,10 @@ final void patch(final String id, final String body) { diaryService.patchDiary(id, body); } + final void restore(final String id){ + diaryService.restoreDiary(id); + } + enum Status { READY, RUNNING, diff --git a/src/main/java/org/sopt/week1/DiaryRepository.java b/src/main/java/org/sopt/week1/DiaryRepository.java index 9511b5b..098c943 100644 --- a/src/main/java/org/sopt/week1/DiaryRepository.java +++ b/src/main/java/org/sopt/week1/DiaryRepository.java @@ -1,13 +1,18 @@ package org.sopt.week1; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; +import org.sopt.week1.Main.UI.LimitEditException; public class DiaryRepository { private final Map storage = new ConcurrentHashMap<>(); + private final Map deletedStorage = new ConcurrentHashMap<>(); + private final Map patchCount = new ConcurrentHashMap<>(); //수정 횟수 + private final Map patchDate = new ConcurrentHashMap<>(); // 마지막으로 수정한 날짜 private final AtomicLong numbering = new AtomicLong(); void save(final Diary diary){ @@ -17,6 +22,8 @@ void save(final Diary diary){ // 저장 과정 storage.put(id, diary.getBody()); + patchCount.put(id, 0); + patchDate.put(id, LocalDate.now()); } List findAll() { @@ -38,18 +45,47 @@ List findAll() { } void delete(final Long id) { - storage.remove(id); + String removedDiary = storage.remove(id); + if(removedDiary != null){ + deletedStorage.put(id, removedDiary); + patchCount.remove(id); // 삭제 시 수정 횟수 제거 + patchDate.remove(id); // 삭제 시 날짜 제거 + } } void patch(final Long id, final String body) { - /* - replace() : key 가 존재할 때에만 값을 변경 - put() : key 가 존재하지 않으면 새로운 key-value 쌍을 추가 - */ + LocalDate today = LocalDate.now(); + LocalDate last = patchDate.getOrDefault(id, today); + + if(!today.equals(last)){ + patchCount.put(id, 0); + patchDate.put(id, today); + } + + int count = patchCount.getOrDefault(id, 0); + + if(count >= 2){ + throw new LimitEditException(); + } storage.replace(id, body); + patchCount.put(id, count + 1); + patchDate.put(id, today); + } + + void restore(final Long id) { + String beRestore = deletedStorage.remove(id); + if (beRestore != null) { + storage.put(id, beRestore); + patchCount.put(id, 0); + patchDate.put(id, LocalDate.now()); + } } boolean existById(final Long id){ return storage.containsKey(id); } + + boolean existByDeletedId(final Long id){ + return deletedStorage.containsKey(id); + } } diff --git a/src/main/java/org/sopt/week1/DiaryService.java b/src/main/java/org/sopt/week1/DiaryService.java index 8026a9a..de0ac4d 100644 --- a/src/main/java/org/sopt/week1/DiaryService.java +++ b/src/main/java/org/sopt/week1/DiaryService.java @@ -37,4 +37,13 @@ void patchDiary(final String id, final String body) { throw new IdNotExistException(); } } + + void restoreDiary(final String id) { + final Long diaryId = Long.parseLong(id); + if (diaryRepository.existByDeletedId(diaryId)) { + diaryRepository.restore(diaryId); + } else { + throw new IdNotExistException(); + } + } } diff --git a/src/main/java/org/sopt/week1/DiaryValidator.java b/src/main/java/org/sopt/week1/DiaryValidator.java index 8027ee3..e45f161 100644 --- a/src/main/java/org/sopt/week1/DiaryValidator.java +++ b/src/main/java/org/sopt/week1/DiaryValidator.java @@ -3,6 +3,9 @@ import org.sopt.week1.Main.UI.InvalidInputException; import org.sopt.week1.Main.UI.DiaryBodyLengthException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class DiaryValidator { public static void validate(final String body){ if(body.trim().isEmpty()){ @@ -12,4 +15,16 @@ public static void validate(final String body){ throw new DiaryBodyLengthException(); } } + + public static int countGraphemeClusters(String body) { + String regex = "\\X"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(body); + + int count = 0; + while (matcher.find()) { + count++; + } + return count; + } } \ No newline at end of file diff --git a/src/main/java/org/sopt/week1/Main.java b/src/main/java/org/sopt/week1/Main.java index 6b21276..fd59825 100644 --- a/src/main/java/org/sopt/week1/Main.java +++ b/src/main/java/org/sopt/week1/Main.java @@ -29,6 +29,9 @@ class DiaryBodyLengthException extends UIException{ class IdNotExistException extends UIException{ } + + class LimitEditException extends RuntimeException{ + } } static class DiaryUI implements UI { @@ -58,6 +61,8 @@ public void runRepeatedly() throws IOException { ConsoleIO.printLine("일기의 본문은 30자 이내여야 합니다."); } catch (IdNotExistException e) { ConsoleIO.printLine("해당 Id 값이 존재하지 않습니다."); + } catch (LimitEditException e) { + ConsoleIO.printLine("일기는 하루에 2번만 수정 가능합니다."); } if (isFinished()) { @@ -104,6 +109,12 @@ private void run() throws IOException { server.patch(inputId, inputBody); } + case "RESTORE" -> { + ConsoleIO.printLine("복구할 일기의 id 를 입력하세요!"); + final String inputId = ConsoleIO.readLine(); + + server.restore(inputId); + } case "FINISH" -> { server.finish(); } @@ -135,6 +146,7 @@ private String getMenu() { - POST : 일기 작성하기 - DELETE : 일기 제거하기 - PATCH : 일기 수정하기 + - RESTORE : 일기 복구하기 """; }