From 834d6c89c0b1643fc7aebec67c2add3b898af6fa Mon Sep 17 00:00:00 2001 From: choyeongju Date: Thu, 10 Oct 2024 01:36:20 +0900 Subject: [PATCH 1/3] =?UTF-8?q?:sparkles:=20[feat]=20=EC=9D=BC=EA=B8=B0=20?= =?UTF-8?q?=EB=B3=B5=EA=B5=AC=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/sopt/week1/DiaryController.java | 4 ++++ .../java/org/sopt/week1/DiaryRepository.java | 17 ++++++++++++++++- src/main/java/org/sopt/week1/DiaryService.java | 9 +++++++++ src/main/java/org/sopt/week1/Main.java | 7 +++++++ 4 files changed, 36 insertions(+), 1 deletion(-) 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..fdc99d1 100644 --- a/src/main/java/org/sopt/week1/DiaryRepository.java +++ b/src/main/java/org/sopt/week1/DiaryRepository.java @@ -8,6 +8,7 @@ public class DiaryRepository { private final Map storage = new ConcurrentHashMap<>(); + private final Map deletedStorage = new ConcurrentHashMap<>(); private final AtomicLong numbering = new AtomicLong(); void save(final Diary diary){ @@ -38,7 +39,10 @@ List findAll() { } void delete(final Long id) { - storage.remove(id); + String removedDiary = storage.remove(id); + if(removedDiary != null){ + deletedStorage.put(id, removedDiary); + } } void patch(final Long id, final String body) { @@ -49,7 +53,18 @@ void patch(final Long id, final String body) { storage.replace(id, body); } + void restore(final Long id) { + String beRestore = deletedStorage.remove(id); + if (beRestore != null) { + storage.put(id, beRestore); + } + } + 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/Main.java b/src/main/java/org/sopt/week1/Main.java index 6b21276..74823be 100644 --- a/src/main/java/org/sopt/week1/Main.java +++ b/src/main/java/org/sopt/week1/Main.java @@ -104,6 +104,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 +141,7 @@ private String getMenu() { - POST : 일기 작성하기 - DELETE : 일기 제거하기 - PATCH : 일기 수정하기 + - RESTORE : 일기 복구하기 """; } From b4498b4a59b69bbaa2d22fb261a8acb2d331da63 Mon Sep 17 00:00:00 2001 From: choyeongju Date: Thu, 10 Oct 2024 03:32:07 +0900 Subject: [PATCH 2/3] =?UTF-8?q?:sparkles:=20[feat]=20=EC=9D=BC=EA=B8=B0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=ED=9A=9F=EC=88=98=20=EC=A0=9C=ED=95=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/sopt/week1/DiaryRepository.java | 29 ++++++++++++++++--- src/main/java/org/sopt/week1/Main.java | 5 ++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/sopt/week1/DiaryRepository.java b/src/main/java/org/sopt/week1/DiaryRepository.java index fdc99d1..098c943 100644 --- a/src/main/java/org/sopt/week1/DiaryRepository.java +++ b/src/main/java/org/sopt/week1/DiaryRepository.java @@ -1,14 +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){ @@ -18,6 +22,8 @@ void save(final Diary diary){ // 저장 과정 storage.put(id, diary.getBody()); + patchCount.put(id, 0); + patchDate.put(id, LocalDate.now()); } List findAll() { @@ -42,21 +48,36 @@ void delete(final Long 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()); } } diff --git a/src/main/java/org/sopt/week1/Main.java b/src/main/java/org/sopt/week1/Main.java index 74823be..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()) { From 18b978b90ef61bcb2c1cc47ded7f392796d73346 Mon Sep 17 00:00:00 2001 From: choyeongju Date: Thu, 10 Oct 2024 21:31:46 +0900 Subject: [PATCH 3/3] =?UTF-8?q?:sparkles:=20[feat]=20=EC=9D=B4=EB=AA=A8?= =?UTF-8?q?=EC=A7=80=20=EC=B2=98=EB=A6=AC=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/sopt/week1/DiaryValidator.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/sopt/week1/DiaryValidator.java b/src/main/java/org/sopt/week1/DiaryValidator.java index d8222a4..636f7ec 100644 --- a/src/main/java/org/sopt/week1/DiaryValidator.java +++ b/src/main/java/org/sopt/week1/DiaryValidator.java @@ -3,13 +3,29 @@ 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()){ throw new InvalidInputException(); } - if(body.length() >= 30){ + int graphemeCount = countGraphemeClusters(body); + if(graphemeCount > 30){ 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