diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/code-review.iml b/.idea/code-review.iml new file mode 100644 index 0000000..dce5887 --- /dev/null +++ b/.idea/code-review.iml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..820225d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..07225ff --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TDD/Proverb.java b/TDD/Proverb.java new file mode 100644 index 0000000..46a7d3f --- /dev/null +++ b/TDD/Proverb.java @@ -0,0 +1,42 @@ +package TDD; + +public class Proverb { + + private int id; // 명언 ID + private String proverb; // 명언 내용 + private String author; // 작가 이름 + + // 생성자 + public Proverb(int id, String proverb, String author) { + this.id = id; + this.proverb = proverb; + this.author = author; + } + + // Getter와 Setter + public int getId() { + return id; + } + + public String getProverb() { + return proverb; + } + + public void setProverb(String proverb) { + this.proverb = proverb; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + // toString 메서드 (목록 출력용) + @Override + public String toString() { + return id + " / " + author + " / " + proverb; + } +} diff --git a/TDD/main/controller/ProverbController.java b/TDD/main/controller/ProverbController.java new file mode 100644 index 0000000..375cc18 --- /dev/null +++ b/TDD/main/controller/ProverbController.java @@ -0,0 +1,42 @@ +package TDD.main.controller; + + +import TDD.main.service.ProverbService; + +public class ProverbController { + + private final ProverbService service; + + public ProverbController() { + this.service = new ProverbService(); + } + + public String registerProverb(String proverb, String author) { + if (proverb == null || proverb.isBlank() || author == null || author.isBlank()) { + return "명언과 작가는 반드시 입력해야 합니다."; + } + return service.addProverb(proverb, author); + } + + public String listProverbs(int page) { + return service.getProverbsByPage(page); + } + + public String searchProverb(String keywordType, String keyword) { + return service.searchProverb(keywordType, keyword); + } + + public String deleteProverb(int id) { + return service.deleteProverb(id); + } + + public String updateProverb(int id, String newProverb, String newAuthor) { + return service.updateProverb(id, newProverb, newAuthor); + } + + public String saveDataToFile() { + service.saveProverbsToData(); + return "data.json 파일이 생성되었습니다."; + } + +} diff --git a/TDD/main/repository/ProverbRepository.java b/TDD/main/repository/ProverbRepository.java new file mode 100644 index 0000000..f7a0c84 --- /dev/null +++ b/TDD/main/repository/ProverbRepository.java @@ -0,0 +1,108 @@ +package TDD.main.repository; + +import TDD.Proverb; + +import java.io.*; +import java.util.*; + +public class ProverbRepository { + private static final String DB_FOLDER = "src/미니과제/db/"; + private static final String LAST_ID_FILE = DB_FOLDER + "lastId.txt"; + private static final String DATA_FILE = DB_FOLDER + "data.json"; + + public int readLastId() { + File file = new File(LAST_ID_FILE); + if (!file.exists()) return 1; + + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + return Integer.parseInt(br.readLine()); + } catch (IOException e) { + e.printStackTrace(); + return 1; + } + } + + public void saveLastId(int id) { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(LAST_ID_FILE))) { + bw.write(String.valueOf(id)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void saveProverb(Proverb proverb) { + File file = new File(DB_FOLDER + proverb.getId() + ".json"); + try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) { + String json = "{ \"id\": " + proverb.getId() + ", \"proverb\": \"" + proverb.getProverb() + "\", \"author\": \"" + proverb.getAuthor() + "\" }"; + bw.write(json); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public int getNextId() { + int lastId = readLastId(); + saveLastId(lastId + 1); + return lastId; + } + + + public void deleteProverbFile(int id) { + File file = new File(DB_FOLDER + id + ".json"); + if (file.exists()) file.delete(); + } + + public List loadProverbs() { + List proverbs = new ArrayList<>(); + File folder = new File(DB_FOLDER); + + File[] files = folder.listFiles((dir, name) -> name.endsWith(".json")); + if (files != null) { + for (File file : files) { + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + String json = br.readLine(); + if (json == null || json.isBlank()) { + System.out.println("빈 파일을 무시합니다: " + file.getName()); + continue; + } + + try { + String idString = json.substring(json.indexOf(":") + 1, json.indexOf(",")).trim(); + String proverb = json.substring(json.indexOf("proverb") + 11, json.indexOf(",", json.indexOf("proverb")) - 1).trim(); + String author = json.substring(json.indexOf("author") + 11, json.lastIndexOf("\"")).trim(); + + int id = Integer.parseInt(idString); + proverbs.add(new Proverb(id, proverb, author)); + } catch (StringIndexOutOfBoundsException | NumberFormatException e) { + System.out.println("JSON 형식 오류로 파일을 무시합니다: " + file.getName()); + } + } catch (IOException e) { + System.out.println("파일 읽기 실패: " + file.getName()); + e.printStackTrace(); + } + } + } + return proverbs; + } + + public void saveProverbsToData(List proverbsList) { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(DATA_FILE))) { + bw.write("[\n"); + for (int i = 0; i < proverbsList.size(); i++) { + Proverb proverb = proverbsList.get(i); + String json = " {\n" + + " \"id\": " + proverb.getId() + ",\n" + + " \"proverb\": \"" + proverb.getProverb() + "\",\n" + + " \"author\": \"" + proverb.getAuthor() + "\"\n" + + " }"; + bw.write(json); + if (i < proverbsList.size() - 1) { + bw.write(",\n"); + } + } + bw.write("\n]"); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/TDD/main/service/ProverbService.java b/TDD/main/service/ProverbService.java new file mode 100644 index 0000000..0e54f72 --- /dev/null +++ b/TDD/main/service/ProverbService.java @@ -0,0 +1,92 @@ +package TDD.main.service; + +import TDD.Proverb; +import TDD.main.repository.ProverbRepository; + +import java.util.ArrayList; +import java.util.List; + +public class ProverbService { + private final ProverbRepository repository; + private final List proverbList; + + public ProverbService() { + this.repository = new ProverbRepository(); + this.proverbList = repository.loadProverbs(); + } + + public String addProverb(String proverb, String author) { + int id = repository.getNextId(); + Proverb newProverb = new Proverb(id, proverb, author); + proverbList.add(newProverb); + repository.saveProverb(newProverb); + return id + "번 명언이 등록되었습니다."; + } + + public String getProverbsByPage(int page) { + int itemsPerPage = 5; + int startIndex = (page - 1) * itemsPerPage; + int endIndex = Math.min(startIndex + itemsPerPage, proverbList.size()); + + if (startIndex >= proverbList.size() || startIndex < 0) { + return "존재하지 않는 페이지입니다."; + } + + StringBuilder result = new StringBuilder("번호 / 작가 / 명언\n----------------\n"); + for (int i = startIndex; i < endIndex; i++) { + Proverb proverb = proverbList.get(i); + result.append(proverb.getId()).append(" / ").append(proverb.getAuthor()) + .append(" / ").append(proverb.getProverb()).append("\n"); + } + return result.toString(); + } + + public String searchProverb(String keywordType, String keyword) { + List results = new ArrayList<>(); + for (Proverb proverb : proverbList) { + if ("content".equals(keywordType) && proverb.getProverb().contains(keyword)) { + results.add(proverb); + } else if ("author".equals(keywordType) && proverb.getAuthor().contains(keyword)) { + results.add(proverb); + } + } + + if (results.isEmpty()) { + return "검색 결과가 없습니다."; + } + + StringBuilder result = new StringBuilder("번호 / 작가 / 명언\n----------------\n"); + for (Proverb proverb : results) { + result.append(proverb.getId()).append(" / ").append(proverb.getAuthor()) + .append(" / ").append(proverb.getProverb()).append("\n"); + } + return result.toString(); + } + + public String deleteProverb(int id) { + for (int i = 0; i < proverbList.size(); i++) { + if (proverbList.get(i).getId() == id) { + proverbList.remove(i); + repository.deleteProverbFile(id); + return id + "번 명언이 삭제되었습니다."; + } + } + return id + "번 명언은 존재하지 않습니다."; + } + + public String updateProverb(int id, String newProverb, String newAuthor) { + for (Proverb proverb : proverbList) { + if (proverb.getId() == id) { + proverb.setProverb(newProverb); + proverb.setAuthor(newAuthor); + repository.saveProverb(proverb); + return id + "번 명언이 수정되었습니다."; + } + } + return id + "번 명언은 존재하지 않습니다."; + } + + public void saveProverbsToData() { + repository.saveProverbsToData(proverbList); + } +} diff --git a/TDD/test/Controller/ProverbControllerTest.java b/TDD/test/Controller/ProverbControllerTest.java new file mode 100644 index 0000000..0751bcd --- /dev/null +++ b/TDD/test/Controller/ProverbControllerTest.java @@ -0,0 +1,68 @@ +package TDD.test.Controller; + +import TDD.main.controller.ProverbController; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class ProverbControllerTest { + + private ProverbController controller; + + @BeforeEach + void setUp() { + // 테스트 전에 ProverbController 객체 초기화 + this.controller = new ProverbController(); + } + + + @Test + @DisplayName("명언 등록 테스트") + void testRegisterProverb() { + String result = controller.registerProverb("오늘도 열리지 않는 문을 두드린다.", "박종현"); + assertTrue(result.contains("1번 명언이 등록되었습니다.")); + } + + @Test + @DisplayName("명언 목록 조회 테스트") + void testListProverbs() { + controller.registerProverb("오늘도 열리지 않는 문을 두드린다.", "박종현"); + String result = controller.listProverbs(1); + assertTrue(result.contains("1 / 박종현 / 오늘도 열리지 않는 문을 두드린다.")); + } + + @Test + @DisplayName("명언 검색 테스트") + void testSearchProverb() { + controller.registerProverb("오늘도 열리지 않는 문을 두드린다.", "박종현"); + String result = controller.searchProverb("author", "박종현"); + assertTrue(result.contains("1 / 박종현 / 오늘도 열리지 않는 문을 두드린다.")); + } + + @Test + @DisplayName("명언 삭제 테스트") + void testDeleteProverb() { + controller.registerProverb("오늘도 열리지 않는 문을 두드린다.", "박종현"); + String result = controller.deleteProverb(1); + assertEquals("1번 명언이 삭제되었습니다.", result); + } + + @Test + @DisplayName("명언 수정 테스트") + void testUpdateProverb() { + controller.registerProverb("오늘도 열리지 않는 문을 두드린다.", "박종현"); + String result = controller.updateProverb(1, "문이 열렸다.", "성공한 박종현"); + assertEquals("1번 명언이 수정되었습니다.", result); + } + + @Test + @DisplayName("데이터 파일 저장 테스트") + void testSaveDataFile() { + controller.registerProverb("오늘도 열리지 않는 문을 두드린다.", "박종현"); + String result = controller.saveDataToFile(); + assertEquals("data.json 파일이 생성되었습니다.", result); + } + +} diff --git a/TDD/test/Repository/ProverbRepositoryTest.java b/TDD/test/Repository/ProverbRepositoryTest.java new file mode 100644 index 0000000..aec002e --- /dev/null +++ b/TDD/test/Repository/ProverbRepositoryTest.java @@ -0,0 +1,33 @@ +package TDD.test.Repository; + +import TDD.main.repository.ProverbRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class ProverbRepositoryTest { + + private ProverbRepository repository; + + @BeforeEach + void setUp() { + repository = new ProverbRepository(); + } + + @Test + @DisplayName("마지막 ID 읽기 테스트") + void testReadLastId() { + int lastId = repository.readLastId(); + assertEquals(1, lastId); // 초기값 1을 기대 + } + + @Test + @DisplayName("마지막 ID 저장 테스트") + void testSaveLastId() { + repository.saveLastId(5); + int lastId = repository.readLastId(); + assertEquals(5, lastId); + } +} diff --git a/TDD/test/Service/ProverbServiceTest.java b/TDD/test/Service/ProverbServiceTest.java new file mode 100644 index 0000000..1e280d2 --- /dev/null +++ b/TDD/test/Service/ProverbServiceTest.java @@ -0,0 +1,17 @@ +package TDD.test.Service; + +import TDD.main.service.ProverbService; +import org.junit.jupiter.api.Test; + + +import static org.junit.jupiter.api.Assertions.*; + +class ProverbServiceTest { + + @Test + void testAddProverb() { + ProverbService service = new ProverbService(); + String result = service.addProverb("현재를 사랑하라.", "작자미상"); + assertEquals("1번 명언이 등록되었습니다.", result); + } +} diff --git a/out/production/code-review/.idea/.gitignore b/out/production/code-review/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/out/production/code-review/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/out/production/code-review/.idea/code-review.iml b/out/production/code-review/.idea/code-review.iml new file mode 100644 index 0000000..dce5887 --- /dev/null +++ b/out/production/code-review/.idea/code-review.iml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/out/production/code-review/.idea/misc.xml b/out/production/code-review/.idea/misc.xml new file mode 100644 index 0000000..820225d --- /dev/null +++ b/out/production/code-review/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/out/production/code-review/.idea/modules.xml b/out/production/code-review/.idea/modules.xml new file mode 100644 index 0000000..07225ff --- /dev/null +++ b/out/production/code-review/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/out/production/code-review/.idea/vcs.xml b/out/production/code-review/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/out/production/code-review/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/out/production/code-review/README.md b/out/production/code-review/README.md new file mode 100644 index 0000000..4444cb9 --- /dev/null +++ b/out/production/code-review/README.md @@ -0,0 +1 @@ +# code-review \ No newline at end of file diff --git a/out/production/code-review/TDD/Controller/ProverbControllerTest.class b/out/production/code-review/TDD/Controller/ProverbControllerTest.class new file mode 100644 index 0000000..50af374 Binary files /dev/null and b/out/production/code-review/TDD/Controller/ProverbControllerTest.class differ diff --git a/out/production/code-review/TDD/Proverb.class b/out/production/code-review/TDD/Proverb.class new file mode 100644 index 0000000..41e5355 Binary files /dev/null and b/out/production/code-review/TDD/Proverb.class differ diff --git a/out/production/code-review/TDD/Repository/ProverbRepositoryTest.class b/out/production/code-review/TDD/Repository/ProverbRepositoryTest.class new file mode 100644 index 0000000..f06032d Binary files /dev/null and b/out/production/code-review/TDD/Repository/ProverbRepositoryTest.class differ diff --git a/out/production/code-review/TDD/Service/ProverbServiceTest.class b/out/production/code-review/TDD/Service/ProverbServiceTest.class new file mode 100644 index 0000000..5a2a2af Binary files /dev/null and b/out/production/code-review/TDD/Service/ProverbServiceTest.class differ diff --git a/out/production/code-review/TDD/main/ProverbController.class b/out/production/code-review/TDD/main/ProverbController.class new file mode 100644 index 0000000..1f7ae2d Binary files /dev/null and b/out/production/code-review/TDD/main/ProverbController.class differ diff --git a/out/production/code-review/TDD/main/ProverbRepository.class b/out/production/code-review/TDD/main/ProverbRepository.class new file mode 100644 index 0000000..4c64363 Binary files /dev/null and b/out/production/code-review/TDD/main/ProverbRepository.class differ diff --git a/out/production/code-review/TDD/main/ProverbService.class b/out/production/code-review/TDD/main/ProverbService.class new file mode 100644 index 0000000..0c7bef3 Binary files /dev/null and b/out/production/code-review/TDD/main/ProverbService.class differ diff --git "a/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/App/App.class" "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/App/App.class" new file mode 100644 index 0000000..4504521 Binary files /dev/null and "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/App/App.class" differ diff --git "a/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardController/BulletinBoardController.class" "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardController/BulletinBoardController.class" new file mode 100644 index 0000000..0e41cf1 Binary files /dev/null and "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardController/BulletinBoardController.class" differ diff --git "a/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardRepository/BulletinBoardRepository.class" "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardRepository/BulletinBoardRepository.class" new file mode 100644 index 0000000..5b1f42e Binary files /dev/null and "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardRepository/BulletinBoardRepository.class" differ diff --git "a/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardService/BulletinBoardService.class" "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardService/BulletinBoardService.class" new file mode 100644 index 0000000..7bec17d Binary files /dev/null and "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardService/BulletinBoardService.class" differ diff --git "a/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/Main.class" "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/Main.class" new file mode 100644 index 0000000..3376ab7 Binary files /dev/null and "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/Main.class" differ diff --git "a/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/data.json" "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/data.json" new file mode 100644 index 0000000..c44dc44 --- /dev/null +++ "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/data.json" @@ -0,0 +1,3 @@ +[ + +] \ No newline at end of file diff --git "a/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/lastId.txt" "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/lastId.txt" new file mode 100644 index 0000000..56a6051 --- /dev/null +++ "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/lastId.txt" @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git "a/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/dblastId.txt" "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/dblastId.txt" new file mode 100644 index 0000000..56a6051 --- /dev/null +++ "b/out/production/code-review/src/\353\257\270\353\213\210\352\263\274\354\240\234/dblastId.txt" @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git "a/out/production/code-review/\353\257\270\353\213\210\352\263\274\354\240\234/Proverb.class" "b/out/production/code-review/\353\257\270\353\213\210\352\263\274\354\240\234/Proverb.class" new file mode 100644 index 0000000..2da5147 Binary files /dev/null and "b/out/production/code-review/\353\257\270\353\213\210\352\263\274\354\240\234/Proverb.class" differ diff --git "a/src/\353\257\270\353\213\210\352\263\274\354\240\234/App/App.java" "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/App/App.java" new file mode 100644 index 0000000..bfbae8b --- /dev/null +++ "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/App/App.java" @@ -0,0 +1,16 @@ +package src.미니과제.App; + + +import src.미니과제.BulletinBoardController.BulletinBoardController; + +public class App { + private final BulletinBoardController controller; + + public App() { + this.controller = new BulletinBoardController(); + } + + public void run() { + controller.start(); + } +} diff --git "a/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardController/BulletinBoardController.java" "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardController/BulletinBoardController.java" new file mode 100644 index 0000000..041deca --- /dev/null +++ "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardController/BulletinBoardController.java" @@ -0,0 +1,99 @@ +package src.미니과제.BulletinBoardController; + + +import src.미니과제.BulletinBoardService.BulletinBoardService; + +import java.util.Scanner; + +public class BulletinBoardController { + private final BulletinBoardService service; + private final Scanner scanner; + + public BulletinBoardController() { + this.service = new BulletinBoardService(); + this.scanner = new Scanner(System.in); + } + + public void start() { + System.out.println("== 명언 =="); + + while (true) { + System.out.print("명령) "); + String command = scanner.nextLine(); + + if (command.equals("등록")) { + registerProverb(); + } else if (command.equals("목록")) { + listProverb(); + } else if (command.startsWith("검색")) { + searchProverb(command); + } else if (command.startsWith("삭제?id=")) { + deleteProverb(command); + } else if (command.startsWith("수정?id=")) { + updateProverb(command); + } else if (command.equals("빌드")) { + buildDataFile(); // 빌드 명령 처리 + } else if (command.equals("종료")) { + System.out.println("프로그램이 종료되었습니다."); + break; + } else { + System.out.println("잘못된 명령어입니다."); + } + } + } + + private void registerProverb() { + System.out.print("명언 : "); + String proverb = scanner.nextLine(); + + System.out.print("작가 : "); + String author = scanner.nextLine(); + + if (proverb.trim().isEmpty() || author.trim().isEmpty()) { + System.out.println("명언과 작가는 반드시 입력해야 합니다."); + return; + } + + service.addProverb(proverb, author); + } + + private void listProverb() { + System.out.print("페이지 번호 입력: "); + int page = Integer.parseInt(scanner.nextLine()); + service.listProverbs(page); + } + + private void searchProverb(String command) { + String[] parts = command.split("\\?"); + + if (parts.length < 2) { + System.out.println("잘못된 검색 명령어입니다. 형식: 검색?keywordType=<검색타입>&keyword=<검색어>"); + return; + } + + String[] keywords = parts[1].split("&"); + if (keywords.length < 2) { + System.out.println("검색타입 또는 검색어가 누락되었습니다."); + return; + } + + String keywordType = keywords[0].split("=")[1]; + String keyword = keywords[1].split("=")[1]; + service.searchProverb(keywordType, keyword); + } + + private void deleteProverb(String command) { + int id = Integer.parseInt(command.split("=")[1]); + service.deleteProverb(id); + } + + private void updateProverb(String command) { + int id = Integer.parseInt(command.split("=")[1]); + service.updateProverb(id, scanner); + } + + private void buildDataFile() { + service.saveProverbsToData(); // 데이터 파일 빌드 + System.out.println("data.json 파일이 생성되었습니다."); + } +} diff --git "a/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardRepository/BulletinBoardRepository.java" "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardRepository/BulletinBoardRepository.java" new file mode 100644 index 0000000..b016949 --- /dev/null +++ "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardRepository/BulletinBoardRepository.java" @@ -0,0 +1,96 @@ +package src.미니과제.BulletinBoardRepository; + +import 미니과제.Proverb; + +import java.io.*; +import java.util.*; + +public class BulletinBoardRepository { + private static final String DB = "src/미니과제/db/"; + private static final String LAST_ID_FILE = DB + "lastId.txt"; + private static final String DATA_PROVERB_FILE = DB + "data.json"; + + public int readLastId() { + File file = new File(LAST_ID_FILE); + if (!file.exists()) return 1; + + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + return Integer.parseInt(br.readLine()); + } catch (IOException e) { + e.printStackTrace(); + } + return 1; + } + + public void saveLastId(int id) { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(LAST_ID_FILE))) { + bw.write(String.valueOf(id)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public List loadProverbs() { + List proverbs = new ArrayList<>(); + File folder = new File(DB); + + File[] files = folder.listFiles((dir, name) -> name.endsWith(".json")); + if (files != null) { + for (File file : files) { + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + String json = br.readLine(); // 한 줄만 읽기 + // JSON 형식에서 id, content, author 추출 + try { + String idString = json.substring(json.indexOf(":") + 1, json.indexOf(",")).trim(); + String proverb = json.substring(json.indexOf("proverb") + 11, json.indexOf(",", json.indexOf("proverb")) - 1).trim(); + String author = json.substring(json.indexOf("author") + 11, json.lastIndexOf("\"")).trim(); + + int id = Integer.parseInt(idString); + proverbs.add(new Proverb(id, proverb, author)); + } catch (StringIndexOutOfBoundsException e) { + System.out.println("JSON 형식이 잘못되었습니다: " + json); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return proverbs; + } + + public void saveProverb(Proverb proverb) { + File file = new File(DB + proverb.getId() + ".json"); + try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) { + String json = "{ \"id\": " + proverb.getId() + ", \"proverb\": \"" + proverb.getProverb() + "\", \"author\": \"" + proverb.getAuthor() + "\" }"; + bw.write(json); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void deleteProverbFile(int id) { + File file = new File(DB + id + ".json"); + if (file.exists()) file.delete(); + } + + public void saveProverbsToData(List proverbsList) { + try (BufferedWriter bw = new BufferedWriter(new FileWriter(DATA_PROVERB_FILE))) { + bw.write("[\n"); + for (int i = 0; i < proverbsList.size(); i++) { + Proverb proverb = proverbsList.get(i); + String json = " {\n" + + " \"id\": " + proverb.getId() + ",\n" + + " \"proverb\": \"" + proverb.getProverb() + "\",\n" + + " \"author\": \"" + proverb.getAuthor() + "\"\n" + + " }"; + bw.write(json); + if (i < proverbsList.size() - 1) { + bw.write(",\n"); + } + } + bw.write("\n]"); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git "a/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardService/BulletinBoardService.java" "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardService/BulletinBoardService.java" new file mode 100644 index 0000000..3593228 --- /dev/null +++ "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/BulletinBoardService/BulletinBoardService.java" @@ -0,0 +1,120 @@ +package src.미니과제.BulletinBoardService; + +import src.미니과제.BulletinBoardRepository.BulletinBoardRepository; +import 미니과제.Proverb; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class BulletinBoardService { + private final BulletinBoardRepository repository; + private final List proverbList; + + public BulletinBoardService() { + this.repository = new BulletinBoardRepository(); + this.proverbList = repository.loadProverbs(); + } + + public void addProverb(String proverb, String author) { + int id = repository.readLastId(); + Proverb proverbObject = new Proverb(id, proverb, author); + proverbList.add(proverbObject); + repository.saveProverb(proverbObject); + repository.saveLastId(id + 1); + System.out.println(id + "번 명언이 등록되었습니다."); + } + + public void listProverbs(int page) { + int itemsPerPage = 5; + int totalItems = proverbList.size(); + int totalPages = (int) Math.ceil((double) totalItems / itemsPerPage); + + if (page < 1 || page > totalPages) { + System.out.println("존재하지 않는 페이지입니다."); + return; + } + + System.out.println("번호 / 작가 / 명언"); + System.out.println("----------------"); + + int startIndex = (page - 1) * itemsPerPage; + int endIndex = Math.min(startIndex + itemsPerPage, totalItems); + + for (int i = startIndex; i < endIndex; i++) { + System.out.println(proverbList.get(i).toString()); + } + + System.out.print("페이지: ["); + for (int i = 1; i <= totalPages; i++) { + System.out.print(i == page ? " " + i + " " : " " + i + " "); + } + System.out.println("]"); + } + + public void searchProverb(String keywordType, String keyword) { + List results = new ArrayList<>(); + + for (Proverb proverb : proverbList) { + if (keywordType.equals("content") && proverb.getProverb().contains(keyword)) { + results.add(proverb); + } else if (keywordType.equals("author") && proverb.getAuthor().contains(keyword)) { + results.add(proverb); + } + } + + if (results.isEmpty()) { + System.out.println("검색 결과가 없습니다."); + return; + } + + System.out.println("번호 / 작가 / 명언"); + System.out.println("----------------"); + for (Proverb proverb : results) { + System.out.println(proverb.toString()); + } + } + + public void deleteProverb(int id) { + boolean check = false; + + for (int i = 0; i < proverbList.size(); i++) { + if (proverbList.get(i).getId() == id) { + proverbList.remove(i); + repository.deleteProverbFile(id); + System.out.println(id + "번째 명언이 삭제되었습니다."); + check = true; + break; + } + } + + if (!check || id <= 0) { + System.out.println(id + "번 명언은 존재하지 않습니다."); + } + } + + public void updateProverb(int id, Scanner scanner) { // Scanner 객체를 매개변수로 받기 + for (Proverb proverb : proverbList) { + if (proverb.getId() == id) { + System.out.println("명언(기존) : " + proverb.getProverb()); + System.out.print("명언 : "); + String newProverb = scanner.nextLine(); + proverb.setProverb(newProverb); + + System.out.println("작가(기존) : " + proverb.getAuthor()); + System.out.print("작가 : "); + String newAuthor = scanner.nextLine(); + proverb.setAuthor(newAuthor); + + repository.saveProverb(proverb); + return; + } + } + System.out.println(id + "번 명언은 존재하지 않습니다."); + } + + public void saveProverbsToData() { + repository.saveProverbsToData(proverbList); + System.out.println("data.json 파일의 내용이 갱신되었습니다."); + } +} diff --git "a/src/\353\257\270\353\213\210\352\263\274\354\240\234/Main.java" "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/Main.java" new file mode 100644 index 0000000..7f6b7b4 --- /dev/null +++ "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/Main.java" @@ -0,0 +1,11 @@ +package src.미니과제; + + +import src.미니과제.App.App; + +public class Main { + public static void main(String[] args) { + App app = new App(); + app.run(); + } +} diff --git "a/src/\353\257\270\353\213\210\352\263\274\354\240\234/Proverb.java" "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/Proverb.java" new file mode 100644 index 0000000..4aa6960 --- /dev/null +++ "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/Proverb.java" @@ -0,0 +1,40 @@ +package 미니과제; + +public class Proverb { + private int id; // id 필드를 private로 유지 + private String proverb; // private으로 변경 + private String author; // private으로 변경 + + public Proverb(int id, String proverb, String author) { + this.id = id; + this.proverb = proverb; + this.author = author; + } + + // 접근자 메서드 추가 + public int getId() { + return id; + } + + public String getProverb() { + return proverb; + } + + public String getAuthor() { + return author; + } + + // 설정자 메서드 추가 + public void setProverb(String proverb) { + this.proverb = proverb; + } + + public void setAuthor(String author) { + this.author = author; + } + + @Override + public String toString() { + return id + " / " + author + " / " + proverb; + } +} diff --git "a/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/data.json" "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/data.json" new file mode 100644 index 0000000..c44dc44 --- /dev/null +++ "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/data.json" @@ -0,0 +1,3 @@ +[ + +] \ No newline at end of file diff --git "a/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/lastId.txt" "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/lastId.txt" new file mode 100644 index 0000000..56a6051 --- /dev/null +++ "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/db/lastId.txt" @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git "a/src/\353\257\270\353\213\210\352\263\274\354\240\234/dblastId.txt" "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/dblastId.txt" new file mode 100644 index 0000000..56a6051 --- /dev/null +++ "b/src/\353\257\270\353\213\210\352\263\274\354\240\234/dblastId.txt" @@ -0,0 +1 @@ +1 \ No newline at end of file