From cd02b2304b833c4fdf9144270d2bbc6370cdf2d9 Mon Sep 17 00:00:00 2001 From: n-coding Date: Mon, 13 Aug 2018 22:18:07 +0900 Subject: [PATCH 01/27] =?UTF-8?q?git=E3=81=AE=E7=84=A1=E8=A6=96=E3=83=AA?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..215c811 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target/ +savefile From 5f636fb37db24592b5236030e5541c4d6eb14a16 Mon Sep 17 00:00:00 2001 From: n-coding Date: Mon, 13 Aug 2018 22:18:57 +0900 Subject: [PATCH 02/27] =?UTF-8?q?author=E3=82=92Book=E3=82=AA=E3=83=96?= =?UTF-8?q?=E3=82=B8=E3=82=A7=E3=82=AF=E3=83=88=E3=81=AE=E7=94=9F=E6=88=90?= =?UTF-8?q?=E5=80=8B=E6=89=80=E3=82=92=E5=BE=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/InsertCommand.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index 80e02fe..1da22fa 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -46,8 +46,7 @@ public Result validate() { .author(argments.get(2)) .publisher(argments.get(3)) .publicationDate(argments.get(4)) - .author(argments.get(5)) - .price(argments.get(6)) + .price(argments.get(5)) .build(); result.getErrMesages().addAll(book.validate().getErrMesages()); From 03374268e6f3034b02f1a7e847532e7089fcdaf1 Mon Sep 17 00:00:00 2001 From: n-coding Date: Thu, 16 Aug 2018 23:05:31 +0900 Subject: [PATCH 03/27] =?UTF-8?q?=E3=83=90=E3=83=AA=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=83=88=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Book.java | 25 ++++++++---- src/main/java/jp/co/training/BookUtil.java | 40 +++++++++++++++++-- src/main/java/jp/co/training/Const.java | 1 + .../java/jp/co/training/InsertCommand.java | 12 +++--- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/main/java/jp/co/training/Book.java b/src/main/java/jp/co/training/Book.java index ad5515a..82ecfc5 100644 --- a/src/main/java/jp/co/training/Book.java +++ b/src/main/java/jp/co/training/Book.java @@ -1,5 +1,6 @@ package jp.co.training; +import static jp.co.training.Const.DATE_PATTERN; import static jp.co.training.Const.MAX_AUTHOR; import static jp.co.training.Const.MAX_BOOK_NAME; import static jp.co.training.Const.MAX_ISBN; @@ -15,18 +16,27 @@ public class Book { private final String publicationDate; private final String price; - public Result validate() { Result result = new Result(); - //最大最小チェック - BookUtil.checkRange(isbn, 1, MAX_ISBN, "ISBM").ifPresent(msg -> result.addErrMessage(msg)); - BookUtil.checkRange(bookName, 1, MAX_BOOK_NAME, "BOOK_NAME").ifPresent(msg -> result.addErrMessage(msg)); - BookUtil.checkRange(author, 1, MAX_AUTHOR, "AUTHOR").ifPresent(msg -> result.addErrMessage(msg)); - BookUtil.checkRange(publisher, 1, MAX_PUBLISHER, "PUBLISHER").ifPresent(msg -> result.addErrMessage(msg)); - BookUtil.checkRange(price, 1, MAX_PRICE, "PRICE").ifPresent(msg -> result.addErrMessage(msg)); + //isbn + BookUtil.checkLength(isbn, 1, MAX_ISBN).ifPresent(msg -> result.addErrMessage("ISBM:" + msg)); + + //bookName + BookUtil.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(msg -> result.addErrMessage("BOOK_NAME:" + msg)); + + //author + BookUtil.checkLength(author, 1, MAX_AUTHOR).ifPresent(msg -> result.addErrMessage("AUTHOR" + msg)); + //publisher + BookUtil.checkLength(publisher, 1, MAX_PUBLISHER).ifPresent(msg -> result.addErrMessage("PUBLISHER:" + msg)); + //price + BookUtil.checkLength(price, 1, MAX_PRICE).ifPresent(msg -> result.addErrMessage("PRICE:" + msg)); + BookUtil.checkNumber(price).ifPresent(msg -> result.addErrMessage("PRICE:" + msg)); + + //publicationDate + BookUtil.checkDatePattern(publicationDate, DATE_PATTERN).ifPresent(msg -> result.addErrMessage("PUBLICATION_DATE:" + msg)); return result; } @@ -65,6 +75,7 @@ private Book(Builder builder) { } public static class Builder { + private String isbn; private String bookName; private String author; diff --git a/src/main/java/jp/co/training/BookUtil.java b/src/main/java/jp/co/training/BookUtil.java index 19e52b7..b44156e 100644 --- a/src/main/java/jp/co/training/BookUtil.java +++ b/src/main/java/jp/co/training/BookUtil.java @@ -1,6 +1,10 @@ package jp.co.training; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.Optional; +import java.util.regex.Pattern; public class BookUtil { @@ -15,15 +19,43 @@ private BookUtil() { * @param target : * @param min * @param max - * @param targetName * @return */ - public static Optional checkRange(String target, int min, int max, String targetName) { + public static Optional checkLength(String target, int min, int max) { if (target.length() < min) { - return Optional.of(targetName + "of size: min is " + min + ". but your input is " + target.length() + "."); + return Optional.of("the length must be " + min + " or more. but actual is " + target.length() + "."); } else if (target.length() > max) { - return Optional.of(targetName + "of size: max is " + max + ". but your input is " + target.length() + "."); + return Optional.of("the length must be " + max + " or less. but actual is " + target.length() + "."); } return Optional.empty(); } + + public static Optional checkDatePattern(String target, String pattern) { + DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern); + try { + LocalDate.parse(target, df); + } catch (DateTimeParseException e) { + return Optional.of("Invalid Pattern. valid pattern is " + pattern + "."); + } + return Optional.empty(); + } + + public static Optional checkNumber(String target) { + if (!isNumber(target)) { + return Optional.of("It is not a numerical format."); + } + return Optional.empty(); + } + + /** + * valueが数値文字列の場合、または空文字の場合はtrueを返す + * + * @param value + * @return + */ + private static boolean isNumber(String value) { + return Pattern.compile("^[0-9]*$").matcher(value).matches(); +// return false; + } + } diff --git a/src/main/java/jp/co/training/Const.java b/src/main/java/jp/co/training/Const.java index a4a3ab8..594d55e 100644 --- a/src/main/java/jp/co/training/Const.java +++ b/src/main/java/jp/co/training/Const.java @@ -13,6 +13,7 @@ public final class Const { public static final int MAX_AUTHOR = 30; public static final int MAX_PUBLISHER = 30; public static final int MAX_PRICE = 9; + public static final String DATE_PATTERN = "yyyyMMdd"; //外部ファイルによる設定が可能な定数 public static final String PROMPT; diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index 1da22fa..3aa6f1c 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -41,12 +41,12 @@ public Result validate() { if (argments.size() != 6) { result.addErrMessage("SyntaxError. The number of arguments does not match."); } - book = new Book.Builder().isbn(argments.get(0)) - .bookName(argments.get(1)) - .author(argments.get(2)) - .publisher(argments.get(3)) - .publicationDate(argments.get(4)) - .price(argments.get(5)) + book = new Book.Builder().isbn(argments.get(0).trim()) + .bookName(argments.get(1).trim()) + .author(argments.get(2).trim()) + .publisher(argments.get(3).trim()) + .publicationDate(argments.get(4).trim()) + .price(argments.get(5).trim()) .build(); result.getErrMesages().addAll(book.validate().getErrMesages()); From d8b725d0892025ef2ad955c7239de9fa9760587e Mon Sep 17 00:00:00 2001 From: n-coding Date: Sun, 19 Aug 2018 20:20:31 +0900 Subject: [PATCH 04/27] =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=AF=E3=83=88?= =?UTF-8?q?=E3=83=AA=E3=83=BC=E3=81=AB=E6=B8=A1=E3=81=99=E6=96=87=E5=AD=97?= =?UTF-8?q?=E5=88=97=E3=82=92=E5=B0=8F=E6=96=87=E5=AD=97=E3=81=AB=E3=81=99?= =?UTF-8?q?=E3=82=8B=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 8bca169..e09116a 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -14,7 +14,7 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio try (Scanner scan = new Scanner(System.in)) { while (true) { System.out.print(PROMPT); - Command command = CommandFactory.createCommand(scan.next()); + Command command = CommandFactory.createCommand(scan.next().toLowerCase()); List argments = Arrays.asList(scan.nextLine().split(DELIMITER)); command.setArgments(argments); From c974380ad99bab7526542eddddeb99ce527fefc7 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sun, 19 Aug 2018 11:03:11 +0900 Subject: [PATCH 05/27] =?UTF-8?q?=E3=83=90=E3=83=AA=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=82=B7=E3=83=A7=E3=83=B3=E3=80=81=E5=AE=9F=E8=A1=8C=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=81=AE=E7=B5=90=E6=9E=9C=E3=81=AB=E5=BF=9C=E3=81=98?= =?UTF-8?q?=E3=81=A6=E3=83=97=E3=83=AD=E3=82=B0=E3=83=A9=E3=83=A0=E3=81=AE?= =?UTF-8?q?=E7=B5=82=E4=BA=86=E7=B6=99=E7=B6=9A=E3=82=92=E5=88=B6=E5=BE=A1?= =?UTF-8?q?=E3=81=99=E3=82=8B=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Command.java | 2 +- src/main/java/jp/co/training/Const.java | 3 +++ src/main/java/jp/co/training/ExitCommand.java | 9 ++++--- .../java/jp/co/training/InsertCommand.java | 15 ++++++++--- .../java/jp/co/training/InvalidCommand.java | 6 +++-- src/main/java/jp/co/training/Main.java | 26 ++++++++++++++----- src/main/java/jp/co/training/Result.java | 18 ++++++++++--- src/main/java/jp/co/training/StatusCode.java | 9 +++++++ 8 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 src/main/java/jp/co/training/StatusCode.java diff --git a/src/main/java/jp/co/training/Command.java b/src/main/java/jp/co/training/Command.java index 538072e..4b28041 100644 --- a/src/main/java/jp/co/training/Command.java +++ b/src/main/java/jp/co/training/Command.java @@ -6,7 +6,7 @@ public interface Command { void setArgments(List argments); - void execute(); + Result execute(); Result validate(); } diff --git a/src/main/java/jp/co/training/Const.java b/src/main/java/jp/co/training/Const.java index 594d55e..5b3b4a8 100644 --- a/src/main/java/jp/co/training/Const.java +++ b/src/main/java/jp/co/training/Const.java @@ -17,11 +17,13 @@ public final class Const { //外部ファイルによる設定が可能な定数 public static final String PROMPT; + public static final String END_MESSAGE; public static final String DELIMITER; public static final String SAVE_FILE; //外部ファイルの設定ファイルのキー private static final String PROMPT_KEY = "prompt"; + private static final String END_MESSAGE_KEY = "end.message"; private static final String DELIMITER_KEY = "delimiter"; private static final String SAVE_FILE_KEY = "save.file"; @@ -30,6 +32,7 @@ public final class Const { PROMPT = (rb == null || !rb.containsKey(PROMPT_KEY)) ? "books>" : rb.getString(PROMPT_KEY); DELIMITER = (rb == null || !rb.containsKey(DELIMITER_KEY)) ? "," : rb.getString(DELIMITER_KEY); SAVE_FILE = (rb == null || !rb.containsKey(SAVE_FILE_KEY)) ? "savefile" : rb.getString(SAVE_FILE_KEY); + END_MESSAGE = (rb == null || !rb.containsKey(END_MESSAGE_KEY)) ? "bye." : rb.getString(END_MESSAGE_KEY); } private static ResourceBundle loadResource() { diff --git a/src/main/java/jp/co/training/ExitCommand.java b/src/main/java/jp/co/training/ExitCommand.java index 8487f8f..0723af0 100644 --- a/src/main/java/jp/co/training/ExitCommand.java +++ b/src/main/java/jp/co/training/ExitCommand.java @@ -4,10 +4,14 @@ public final class ExitCommand implements Command { + private final Result result = new Result(); + private List argments; + @Override - public void execute() { - System.exit(0); + public Result execute() { + result.setCode(StatusCode.BREAK); + return result; } @Override @@ -17,7 +21,6 @@ public void setArgments(List argments) { @Override public Result validate() { - Result result = new Result(); //パラメータ数 if (argments != null && !argments.isEmpty()) { if (argments.size() == 1 && argments.get(0).trim().equals("")) { diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index 3aa6f1c..e6da98c 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -11,6 +11,7 @@ import static jp.co.training.Const.SAVE_FILE; public final class InsertCommand implements Command { + private final Result result = new Result(); private List argments; @@ -22,7 +23,7 @@ public void setArgments(List argments) { } @Override - public void execute() { + public Result execute() { try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { for (int i = 0, size = argments.size(); i < size; i++) { bw.write((i == 0 ? "" : ",") + argments.get(i).trim()); @@ -32,15 +33,18 @@ public void execute() { Logger.getLogger(InsertCommand.class.getName()).log(Level.SEVERE, null, ex); } System.out.println("inserted."); + return result; } @Override public Result validate() { - Result result = new Result(); - //パラメータ数 + //パラメータ数チェック if (argments.size() != 6) { result.addErrMessage("SyntaxError. The number of arguments does not match."); + result.setCode(StatusCode.CONTINUE); + return result; } + //書籍情報のチェック book = new Book.Builder().isbn(argments.get(0).trim()) .bookName(argments.get(1).trim()) .author(argments.get(2).trim()) @@ -48,7 +52,10 @@ public Result validate() { .publicationDate(argments.get(4).trim()) .price(argments.get(5).trim()) .build(); - result.getErrMesages().addAll(book.validate().getErrMesages()); + result.getMesages().addAll(book.validate().getMesages()); + if (!result.getMesages().isEmpty()) { + result.setCode(StatusCode.CONTINUE); + } return result; } diff --git a/src/main/java/jp/co/training/InvalidCommand.java b/src/main/java/jp/co/training/InvalidCommand.java index f5063ba..1d13d54 100644 --- a/src/main/java/jp/co/training/InvalidCommand.java +++ b/src/main/java/jp/co/training/InvalidCommand.java @@ -3,18 +3,20 @@ import java.util.List; public final class InvalidCommand implements Command { + private final Result result = new Result(); @Override public void setArgments(List argments) { } @Override - public void execute() { + public Result execute() { + return result; } @Override public Result validate() { - Result result = new Result(); + result.setCode(StatusCode.CONTINUE); result.addErrMessage("Invalid Command."); return result; } diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 8bca169..66adc4c 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Scanner; import static jp.co.training.Const.DELIMITER; +import static jp.co.training.Const.END_MESSAGE; import static jp.co.training.Const.PROMPT; public final class Main { @@ -18,14 +19,27 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio List argments = Arrays.asList(scan.nextLine().split(DELIMITER)); command.setArgments(argments); - Result result = command.validate(); - if (result != null && result.getErrMesages().size() > 0) { - result.getErrMesages().stream().forEach(message -> { - System.err.println(message); - }); + if (validate(command)) { + continue; + } + if (command.execute().getCode() == StatusCode.BREAK) { + System.out.println(END_MESSAGE); + break; } - command.execute(); } } } + + private static boolean validate(Command command) { + Result result = command.validate(); + if (result != null && result.getMesages().size() > 0) { + result.getMesages().stream().forEach(message -> { + System.out.println(message); + }); + } + if (result != null && result.getCode() == StatusCode.CONTINUE) { + return true; + } + return false; + } } diff --git a/src/main/java/jp/co/training/Result.java b/src/main/java/jp/co/training/Result.java index 6e0a6e2..83c390a 100644 --- a/src/main/java/jp/co/training/Result.java +++ b/src/main/java/jp/co/training/Result.java @@ -5,13 +5,23 @@ public class Result { - private final List errMesages = new ArrayList<>(); + private StatusCode code = StatusCode.KEEP; + private final List mesages = new ArrayList<>(); - public List getErrMesages() { - return errMesages; + public List getMesages() { + return mesages; } public void addErrMessage(String msg) { - errMesages.add(msg); + mesages.add(msg); } + + public StatusCode getCode() { + return code; + } + + public void setCode(StatusCode code) { + this.code = code; + } + } diff --git a/src/main/java/jp/co/training/StatusCode.java b/src/main/java/jp/co/training/StatusCode.java new file mode 100644 index 0000000..4d9d850 --- /dev/null +++ b/src/main/java/jp/co/training/StatusCode.java @@ -0,0 +1,9 @@ +package jp.co.training; + +public enum StatusCode { + + KEEP,//そのまま継続 + CONTINUE,//ループの最初に戻る + BREAK//ループを抜ける + +} From 35800c499a30fefe94d584225ca2b69c101a5b4b Mon Sep 17 00:00:00 2001 From: n-coding Date: Sun, 19 Aug 2018 11:23:02 +0900 Subject: [PATCH 06/27] =?UTF-8?q?book=E3=81=AE=E7=99=BB=E9=8C=B2=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/InsertCommand.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index e6da98c..2f6b896 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -25,9 +25,13 @@ public void setArgments(List argments) { @Override public Result execute() { try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { - for (int i = 0, size = argments.size(); i < size; i++) { - bw.write((i == 0 ? "" : ",") + argments.get(i).trim()); - } + bw.write(book.getIsbn()); + bw.write(book.getBookName()); + bw.write(book.getAuthor()); + bw.write(book.getPublisher()); + bw.write(book.getPublicationDate()); + bw.write(book.getPrice()); + bw.newLine(); } catch (IOException ex) { Logger.getLogger(InsertCommand.class.getName()).log(Level.SEVERE, null, ex); From fbe0fe6efda6df3c5a67391c2589eac3a18eca64 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sun, 19 Aug 2018 21:30:40 +0900 Subject: [PATCH 07/27] =?UTF-8?q?=E3=83=90=E3=83=AA=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=81=A8=E3=82=A8=E3=82=B0=E3=82=BC=E3=82=AD=E3=83=A5?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=81=AE=E5=87=A6=E7=90=86=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/ExitCommand.java | 2 +- .../java/jp/co/training/InsertCommand.java | 10 ++++------ .../java/jp/co/training/InvalidCommand.java | 5 +++-- src/main/java/jp/co/training/Main.java | 20 +++++++++++-------- src/main/java/jp/co/training/Result.java | 6 +++--- .../training/{StatusCode.java => Status.java} | 2 +- 6 files changed, 24 insertions(+), 21 deletions(-) rename src/main/java/jp/co/training/{StatusCode.java => Status.java} (84%) diff --git a/src/main/java/jp/co/training/ExitCommand.java b/src/main/java/jp/co/training/ExitCommand.java index 0723af0..7adc2be 100644 --- a/src/main/java/jp/co/training/ExitCommand.java +++ b/src/main/java/jp/co/training/ExitCommand.java @@ -10,7 +10,7 @@ public final class ExitCommand implements Command { @Override public Result execute() { - result.setCode(StatusCode.BREAK); + result.setCode(Status.BREAK); return result; } diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index 2f6b896..144a7c5 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -6,11 +6,10 @@ import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; import static jp.co.training.Const.SAVE_FILE; public final class InsertCommand implements Command { + private final Result result = new Result(); private List argments; @@ -31,10 +30,9 @@ public Result execute() { bw.write(book.getPublisher()); bw.write(book.getPublicationDate()); bw.write(book.getPrice()); - bw.newLine(); } catch (IOException ex) { - Logger.getLogger(InsertCommand.class.getName()).log(Level.SEVERE, null, ex); + System.out.println(SAVE_FILE + ": cannot open."); } System.out.println("inserted."); return result; @@ -45,7 +43,7 @@ public Result validate() { //パラメータ数チェック if (argments.size() != 6) { result.addErrMessage("SyntaxError. The number of arguments does not match."); - result.setCode(StatusCode.CONTINUE); + result.setCode(Status.CONTINUE); return result; } //書籍情報のチェック @@ -58,7 +56,7 @@ public Result validate() { .build(); result.getMesages().addAll(book.validate().getMesages()); if (!result.getMesages().isEmpty()) { - result.setCode(StatusCode.CONTINUE); + result.setCode(Status.CONTINUE); } return result; diff --git a/src/main/java/jp/co/training/InvalidCommand.java b/src/main/java/jp/co/training/InvalidCommand.java index 1d13d54..a4a7d5b 100644 --- a/src/main/java/jp/co/training/InvalidCommand.java +++ b/src/main/java/jp/co/training/InvalidCommand.java @@ -3,6 +3,7 @@ import java.util.List; public final class InvalidCommand implements Command { + private final Result result = new Result(); @Override @@ -11,12 +12,12 @@ public void setArgments(List argments) { @Override public Result execute() { - return result; + throw new UnsupportedOperationException("Execute invalid Command."); } @Override public Result validate() { - result.setCode(StatusCode.CONTINUE); + result.setCode(Status.CONTINUE); result.addErrMessage("Invalid Command."); return result; } diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 5e6b71c..8504cc4 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Scanner; import static jp.co.training.Const.DELIMITER; -import static jp.co.training.Const.END_MESSAGE; import static jp.co.training.Const.PROMPT; public final class Main { @@ -17,29 +16,34 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio System.out.print(PROMPT); Command command = CommandFactory.createCommand(scan.next().toLowerCase()); List argments = Arrays.asList(scan.nextLine().split(DELIMITER)); - command.setArgments(argments); if (validate(command)) { continue; } - if (command.execute().getCode() == StatusCode.BREAK) { - System.out.println(END_MESSAGE); + if (execute(command)) { break; } } } } + private static boolean execute(Command command) { + Result result = command.execute(); + outputMessages(result); + return result != null && result.getCode() == Status.BREAK; + } + private static boolean validate(Command command) { Result result = command.validate(); + outputMessages(result); + return result != null && result.getCode() == Status.CONTINUE; + } + + private static void outputMessages(Result result) { if (result != null && result.getMesages().size() > 0) { result.getMesages().stream().forEach(message -> { System.out.println(message); }); } - if (result != null && result.getCode() == StatusCode.CONTINUE) { - return true; - } - return false; } } diff --git a/src/main/java/jp/co/training/Result.java b/src/main/java/jp/co/training/Result.java index 83c390a..c23b453 100644 --- a/src/main/java/jp/co/training/Result.java +++ b/src/main/java/jp/co/training/Result.java @@ -5,7 +5,7 @@ public class Result { - private StatusCode code = StatusCode.KEEP; + private Status code = Status.KEEP; private final List mesages = new ArrayList<>(); public List getMesages() { @@ -16,11 +16,11 @@ public void addErrMessage(String msg) { mesages.add(msg); } - public StatusCode getCode() { + public Status getCode() { return code; } - public void setCode(StatusCode code) { + public void setCode(Status code) { this.code = code; } diff --git a/src/main/java/jp/co/training/StatusCode.java b/src/main/java/jp/co/training/Status.java similarity index 84% rename from src/main/java/jp/co/training/StatusCode.java rename to src/main/java/jp/co/training/Status.java index 4d9d850..89bbd0d 100644 --- a/src/main/java/jp/co/training/StatusCode.java +++ b/src/main/java/jp/co/training/Status.java @@ -1,6 +1,6 @@ package jp.co.training; -public enum StatusCode { +public enum Status { KEEP,//そのまま継続 CONTINUE,//ループの最初に戻る From a9317b0f61f91ab5822863e3dbd0199552da5269 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sun, 19 Aug 2018 22:03:21 +0900 Subject: [PATCH 08/27] =?UTF-8?q?Command=E3=82=A4=E3=83=B3=E3=82=BF?= =?UTF-8?q?=E3=83=BC=E3=83=95=E3=82=A7=E3=83=BC=E3=82=B9=E3=81=8B=E3=82=89?= =?UTF-8?q?validate=E3=82=92=E9=99=A4=E5=8E=BB=E3=80=82=E3=83=90=E3=83=AA?= =?UTF-8?q?=E3=83=87=E3=83=BC=E3=83=88=E3=81=AFexecute=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=81=AE=E4=B8=AD=E3=81=A7=E5=AE=9F=E6=96=BD?= =?UTF-8?q?=E3=81=99=E3=82=8B=E5=BD=A2=E3=81=AB=E5=A4=89=E6=9B=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Book.java | 14 ++--- src/main/java/jp/co/training/Command.java | 5 +- src/main/java/jp/co/training/ExitCommand.java | 21 +------- .../java/jp/co/training/InsertCommand.java | 51 ++++++++++--------- .../java/jp/co/training/InvalidCommand.java | 12 +---- src/main/java/jp/co/training/Main.java | 25 ++------- src/main/java/jp/co/training/Result.java | 12 ++--- src/main/java/jp/co/training/Status.java | 1 - 8 files changed, 50 insertions(+), 91 deletions(-) diff --git a/src/main/java/jp/co/training/Book.java b/src/main/java/jp/co/training/Book.java index 82ecfc5..9ebb507 100644 --- a/src/main/java/jp/co/training/Book.java +++ b/src/main/java/jp/co/training/Book.java @@ -20,23 +20,23 @@ public Result validate() { Result result = new Result(); //isbn - BookUtil.checkLength(isbn, 1, MAX_ISBN).ifPresent(msg -> result.addErrMessage("ISBM:" + msg)); + BookUtil.checkLength(isbn, 1, MAX_ISBN).ifPresent(msg -> result.addMessage("ISBM:" + msg)); //bookName - BookUtil.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(msg -> result.addErrMessage("BOOK_NAME:" + msg)); + BookUtil.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(msg -> result.addMessage("BOOK_NAME:" + msg)); //author - BookUtil.checkLength(author, 1, MAX_AUTHOR).ifPresent(msg -> result.addErrMessage("AUTHOR" + msg)); + BookUtil.checkLength(author, 1, MAX_AUTHOR).ifPresent(msg -> result.addMessage("AUTHOR" + msg)); //publisher - BookUtil.checkLength(publisher, 1, MAX_PUBLISHER).ifPresent(msg -> result.addErrMessage("PUBLISHER:" + msg)); + BookUtil.checkLength(publisher, 1, MAX_PUBLISHER).ifPresent(msg -> result.addMessage("PUBLISHER:" + msg)); //price - BookUtil.checkLength(price, 1, MAX_PRICE).ifPresent(msg -> result.addErrMessage("PRICE:" + msg)); - BookUtil.checkNumber(price).ifPresent(msg -> result.addErrMessage("PRICE:" + msg)); + BookUtil.checkLength(price, 1, MAX_PRICE).ifPresent(msg -> result.addMessage("PRICE:" + msg)); + BookUtil.checkNumber(price).ifPresent(msg -> result.addMessage("PRICE:" + msg)); //publicationDate - BookUtil.checkDatePattern(publicationDate, DATE_PATTERN).ifPresent(msg -> result.addErrMessage("PUBLICATION_DATE:" + msg)); + BookUtil.checkDatePattern(publicationDate, DATE_PATTERN).ifPresent(msg -> result.addMessage("PUBLICATION_DATE:" + msg)); return result; } diff --git a/src/main/java/jp/co/training/Command.java b/src/main/java/jp/co/training/Command.java index 4b28041..6c351f0 100644 --- a/src/main/java/jp/co/training/Command.java +++ b/src/main/java/jp/co/training/Command.java @@ -1,12 +1,9 @@ package jp.co.training; -import java.util.List; - public interface Command { - void setArgments(List argments); + void setArgments(String[] argments); Result execute(); - Result validate(); } diff --git a/src/main/java/jp/co/training/ExitCommand.java b/src/main/java/jp/co/training/ExitCommand.java index 7adc2be..6008b4d 100644 --- a/src/main/java/jp/co/training/ExitCommand.java +++ b/src/main/java/jp/co/training/ExitCommand.java @@ -1,34 +1,17 @@ package jp.co.training; -import java.util.List; - public final class ExitCommand implements Command { private final Result result = new Result(); - private List argments; - @Override public Result execute() { - result.setCode(Status.BREAK); + result.setExit(true); return result; } @Override - public void setArgments(List argments) { - this.argments = argments; - } - - @Override - public Result validate() { - //パラメータ数 - if (argments != null && !argments.isEmpty()) { - if (argments.size() == 1 && argments.get(0).trim().equals("")) { - return result; - } - result.addErrMessage("SyntaxError. The number of arguments does not match."); - } - return result; + public void setArgments(String[] argments) { } } diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index 144a7c5..d534670 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -5,24 +5,28 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; -import java.util.List; import static jp.co.training.Const.SAVE_FILE; public final class InsertCommand implements Command { private final Result result = new Result(); - - private List argments; - + private String[] argments; private Book book; @Override - public void setArgments(List argments) { + public void setArgments(String[] argments) { this.argments = argments; } @Override public Result execute() { + if (!validate()) { + return result; + } + return createBook(); + } + + private Result createBook() { try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { bw.write(book.getIsbn()); bw.write(book.getBookName()); @@ -32,34 +36,33 @@ public Result execute() { bw.write(book.getPrice()); bw.newLine(); } catch (IOException ex) { - System.out.println(SAVE_FILE + ": cannot open."); + result.addMessage(SAVE_FILE + ": cannot open."); + result.setExit(true); + return result; } - System.out.println("inserted."); + result.addMessage("inserted."); return result; } - @Override - public Result validate() { + /* + 検証の結果OKならtrueを返す。それ以外はfalseを返す + */ + private boolean validate() { //パラメータ数チェック - if (argments.size() != 6) { - result.addErrMessage("SyntaxError. The number of arguments does not match."); - result.setCode(Status.CONTINUE); - return result; + if (argments.length != 6) { + result.addMessage("SyntaxError. The number of arguments does not match."); + return false; } //書籍情報のチェック - book = new Book.Builder().isbn(argments.get(0).trim()) - .bookName(argments.get(1).trim()) - .author(argments.get(2).trim()) - .publisher(argments.get(3).trim()) - .publicationDate(argments.get(4).trim()) - .price(argments.get(5).trim()) + book = new Book.Builder().isbn(argments[0].trim()) + .bookName(argments[1].trim()) + .author(argments[2].trim()) + .publisher(argments[3].trim()) + .publicationDate(argments[4].trim()) + .price(argments[5].trim()) .build(); result.getMesages().addAll(book.validate().getMesages()); - if (!result.getMesages().isEmpty()) { - result.setCode(Status.CONTINUE); - } - - return result; + return result.getMesages().isEmpty(); } } diff --git a/src/main/java/jp/co/training/InvalidCommand.java b/src/main/java/jp/co/training/InvalidCommand.java index a4a7d5b..585fd0e 100644 --- a/src/main/java/jp/co/training/InvalidCommand.java +++ b/src/main/java/jp/co/training/InvalidCommand.java @@ -1,24 +1,16 @@ package jp.co.training; -import java.util.List; - public final class InvalidCommand implements Command { private final Result result = new Result(); @Override - public void setArgments(List argments) { + public void setArgments(String[] argments) { } @Override public Result execute() { - throw new UnsupportedOperationException("Execute invalid Command."); - } - - @Override - public Result validate() { - result.setCode(Status.CONTINUE); - result.addErrMessage("Invalid Command."); + result.addMessage("Invalid Command."); return result; } diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 8504cc4..41f97ac 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -2,8 +2,6 @@ import java.io.FileNotFoundException; import java.io.IOException; -import java.util.Arrays; -import java.util.List; import java.util.Scanner; import static jp.co.training.Const.DELIMITER; import static jp.co.training.Const.PROMPT; @@ -15,30 +13,17 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio while (true) { System.out.print(PROMPT); Command command = CommandFactory.createCommand(scan.next().toLowerCase()); - List argments = Arrays.asList(scan.nextLine().split(DELIMITER)); - command.setArgments(argments); - if (validate(command)) { - continue; - } - if (execute(command)) { + command.setArgments(scan.nextLine().split(DELIMITER)); + + Result result = command.execute(); + outputMessages(result); + if (result != null && result.isExit()) { break; } } } } - private static boolean execute(Command command) { - Result result = command.execute(); - outputMessages(result); - return result != null && result.getCode() == Status.BREAK; - } - - private static boolean validate(Command command) { - Result result = command.validate(); - outputMessages(result); - return result != null && result.getCode() == Status.CONTINUE; - } - private static void outputMessages(Result result) { if (result != null && result.getMesages().size() > 0) { result.getMesages().stream().forEach(message -> { diff --git a/src/main/java/jp/co/training/Result.java b/src/main/java/jp/co/training/Result.java index c23b453..be2ecff 100644 --- a/src/main/java/jp/co/training/Result.java +++ b/src/main/java/jp/co/training/Result.java @@ -5,23 +5,23 @@ public class Result { - private Status code = Status.KEEP; + private boolean exit = false; private final List mesages = new ArrayList<>(); public List getMesages() { return mesages; } - public void addErrMessage(String msg) { + public void addMessage(String msg) { mesages.add(msg); } - public Status getCode() { - return code; + public boolean isExit() { + return exit; } - public void setCode(Status code) { - this.code = code; + public void setExit(boolean exit) { + this.exit = exit; } } diff --git a/src/main/java/jp/co/training/Status.java b/src/main/java/jp/co/training/Status.java index 89bbd0d..2379628 100644 --- a/src/main/java/jp/co/training/Status.java +++ b/src/main/java/jp/co/training/Status.java @@ -3,7 +3,6 @@ public enum Status { KEEP,//そのまま継続 - CONTINUE,//ループの最初に戻る BREAK//ループを抜ける } From 5aca116d4f21c96e64e7efaabb6edff525180848 Mon Sep 17 00:00:00 2001 From: n-coding Date: Wed, 22 Aug 2018 00:27:55 +0900 Subject: [PATCH 09/27] =?UTF-8?q?Chain=20of=20Responsibility=20=E3=82=92?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B=E5=BD=A2=E3=81=AB=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Command.java | 13 +++++++--- .../java/jp/co/training/CommandFactory.java | 19 --------------- src/main/java/jp/co/training/ExitCommand.java | 18 +++++++------- .../java/jp/co/training/InsertCommand.java | 24 +++++++++---------- .../java/jp/co/training/InvalidCommand.java | 15 ++++++------ src/main/java/jp/co/training/Main.java | 7 +++--- 6 files changed, 40 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/jp/co/training/CommandFactory.java diff --git a/src/main/java/jp/co/training/Command.java b/src/main/java/jp/co/training/Command.java index 6c351f0..9c0142f 100644 --- a/src/main/java/jp/co/training/Command.java +++ b/src/main/java/jp/co/training/Command.java @@ -1,9 +1,16 @@ package jp.co.training; -public interface Command { +public abstract class Command { - void setArgments(String[] argments); + protected Result result; - Result execute(); + protected Command next; + + public Command setNext(Command next) { + this.next = next; + return next; + } + + public abstract Result execute(String command, String[] argments); } diff --git a/src/main/java/jp/co/training/CommandFactory.java b/src/main/java/jp/co/training/CommandFactory.java deleted file mode 100644 index 3010dc0..0000000 --- a/src/main/java/jp/co/training/CommandFactory.java +++ /dev/null @@ -1,19 +0,0 @@ -package jp.co.training; - -import static jp.co.training.Const.EXIT; -import static jp.co.training.Const.INSERT; - -public final class CommandFactory { - - public static Command createCommand(String command) { - - switch (command) { - case INSERT: - return new InsertCommand(); - case EXIT: - return new ExitCommand(); - default: - return new InvalidCommand(); - } - } -} diff --git a/src/main/java/jp/co/training/ExitCommand.java b/src/main/java/jp/co/training/ExitCommand.java index 6008b4d..dcfa563 100644 --- a/src/main/java/jp/co/training/ExitCommand.java +++ b/src/main/java/jp/co/training/ExitCommand.java @@ -1,17 +1,17 @@ package jp.co.training; -public final class ExitCommand implements Command { +import static jp.co.training.Const.EXIT; - private final Result result = new Result(); +public final class ExitCommand extends Command { @Override - public Result execute() { - result.setExit(true); - return result; - } - - @Override - public void setArgments(String[] argments) { + public Result execute(String command, String[] argments) { + result = new Result(); + if (command.equals(EXIT)) { + result.setExit(true); + return result; + } + return next.execute(command, argments); } } diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index d534670..dc22af9 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -5,25 +5,23 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; +import static jp.co.training.Const.INSERT; import static jp.co.training.Const.SAVE_FILE; -public final class InsertCommand implements Command { +public final class InsertCommand extends Command { - private final Result result = new Result(); - private String[] argments; private Book book; @Override - public void setArgments(String[] argments) { - this.argments = argments; - } - - @Override - public Result execute() { - if (!validate()) { - return result; + public Result execute(String command, String[] argments) { + result = new Result(); + if (command.equals(INSERT)) { + if (!validate(argments)) { + return result; + } + return createBook(); } - return createBook(); + return next.execute(command, argments); } private Result createBook() { @@ -47,7 +45,7 @@ private Result createBook() { /* 検証の結果OKならtrueを返す。それ以外はfalseを返す */ - private boolean validate() { + private boolean validate(String[] argments) { //パラメータ数チェック if (argments.length != 6) { result.addMessage("SyntaxError. The number of arguments does not match."); diff --git a/src/main/java/jp/co/training/InvalidCommand.java b/src/main/java/jp/co/training/InvalidCommand.java index 585fd0e..def9c6d 100644 --- a/src/main/java/jp/co/training/InvalidCommand.java +++ b/src/main/java/jp/co/training/InvalidCommand.java @@ -1,17 +1,16 @@ package jp.co.training; -public final class InvalidCommand implements Command { - - private final Result result = new Result(); - - @Override - public void setArgments(String[] argments) { - } +public final class InvalidCommand extends Command { @Override - public Result execute() { + public Result execute(String command, String[] argments) { + result = new Result(); result.addMessage("Invalid Command."); return result; } + @Override + public Command setNext(Command next) { + throw new UnsupportedOperationException(); + } } diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 41f97ac..2a306b7 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -9,13 +9,12 @@ public final class Main { public static void main(String... args) throws FileNotFoundException, IOException { + Command command = new InsertCommand(); + command.setNext(new ExitCommand()).setNext(new InvalidCommand()); try (Scanner scan = new Scanner(System.in)) { while (true) { System.out.print(PROMPT); - Command command = CommandFactory.createCommand(scan.next().toLowerCase()); - command.setArgments(scan.nextLine().split(DELIMITER)); - - Result result = command.execute(); + Result result = command.execute(scan.next().toLowerCase(), scan.nextLine().split(DELIMITER)); outputMessages(result); if (result != null && result.isExit()) { break; From d1bd2ee6f16ce6e60edf709776889d162afc9ed5 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 25 Aug 2018 12:26:35 +0900 Subject: [PATCH 10/27] =?UTF-8?q?.gitignore=E3=81=AE=E8=BF=BD=E8=B7=A1?= =?UTF-8?q?=E3=82=92=E5=81=9C=E6=AD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 215c811..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target/ -savefile From 1a27ec43899ca4a9df030649a04fcf94fec1b19f Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 25 Aug 2018 12:27:12 +0900 Subject: [PATCH 11/27] =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=81=AE=E5=AE=9F=E8=A1=8C=E6=96=B9=E6=B3=95=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Command.java | 30 ++++-- src/main/java/jp/co/training/ExitCommand.java | 21 ++-- .../java/jp/co/training/InsertCommand.java | 101 +++++++++--------- .../java/jp/co/training/InvalidCommand.java | 16 --- src/main/java/jp/co/training/Main.java | 49 +++++---- 5 files changed, 109 insertions(+), 108 deletions(-) delete mode 100644 src/main/java/jp/co/training/InvalidCommand.java diff --git a/src/main/java/jp/co/training/Command.java b/src/main/java/jp/co/training/Command.java index 9c0142f..60f2a56 100644 --- a/src/main/java/jp/co/training/Command.java +++ b/src/main/java/jp/co/training/Command.java @@ -2,15 +2,31 @@ public abstract class Command { - protected Result result; + protected String name; - protected Command next; + protected Command next; - public Command setNext(Command next) { - this.next = next; - return next; - } + public Command(String name) { + this.name = name; + } - public abstract Result execute(String command, String[] argments); + public Result execute(String command, String[] argments) { + if (command.equals(name)) { + executeCommand(command, argments); + } else if (next != null) { + return next.execute(command, argments); + } + // どのコマンドにも合致しなかった場合 + Result result = new Result(); + result.addMessage("Invalid Command."); + return result; + }; + + public Command setNext(Command next) { + this.next = next; + return next; + } + + public abstract Result executeCommand(String command, String[] argments); } diff --git a/src/main/java/jp/co/training/ExitCommand.java b/src/main/java/jp/co/training/ExitCommand.java index dcfa563..79c4866 100644 --- a/src/main/java/jp/co/training/ExitCommand.java +++ b/src/main/java/jp/co/training/ExitCommand.java @@ -1,17 +1,16 @@ package jp.co.training; -import static jp.co.training.Const.EXIT; - public final class ExitCommand extends Command { - @Override - public Result execute(String command, String[] argments) { - result = new Result(); - if (command.equals(EXIT)) { - result.setExit(true); - return result; - } - return next.execute(command, argments); - } + public ExitCommand(String name) { + super(name); + } + + @Override + public Result executeCommand(String command, String[] argments) { + Result result = new Result(); + result.setExit(true); + return result; + } } diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index dc22af9..cfc8943 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -1,66 +1,65 @@ package jp.co.training; +import static jp.co.training.Const.SAVE_FILE; + import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; -import static jp.co.training.Const.INSERT; -import static jp.co.training.Const.SAVE_FILE; public final class InsertCommand extends Command { - private Book book; + private Result result; + + private Book book; + + public InsertCommand(String name) { + super(name); + } - @Override - public Result execute(String command, String[] argments) { - result = new Result(); - if (command.equals(INSERT)) { - if (!validate(argments)) { - return result; - } - return createBook(); - } - return next.execute(command, argments); - } + @Override + public Result executeCommand(String command, String[] argments) { + result = new Result(); + if (!validate(argments)) { + return result; + } + return createBook(); + } - private Result createBook() { - try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { - bw.write(book.getIsbn()); - bw.write(book.getBookName()); - bw.write(book.getAuthor()); - bw.write(book.getPublisher()); - bw.write(book.getPublicationDate()); - bw.write(book.getPrice()); - bw.newLine(); - } catch (IOException ex) { - result.addMessage(SAVE_FILE + ": cannot open."); - result.setExit(true); - return result; - } - result.addMessage("inserted."); - return result; - } + private Result createBook() { + try (BufferedWriter bw = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { + bw.write(book.getIsbn()); + bw.write(book.getBookName()); + bw.write(book.getAuthor()); + bw.write(book.getPublisher()); + bw.write(book.getPublicationDate()); + bw.write(book.getPrice()); + bw.newLine(); + } catch (IOException ex) { + result.addMessage(SAVE_FILE + ": cannot open."); + result.setExit(true); + return result; + } + result.addMessage("inserted."); + return result; + } - /* - 検証の結果OKならtrueを返す。それ以外はfalseを返す - */ - private boolean validate(String[] argments) { - //パラメータ数チェック - if (argments.length != 6) { - result.addMessage("SyntaxError. The number of arguments does not match."); - return false; - } - //書籍情報のチェック - book = new Book.Builder().isbn(argments[0].trim()) - .bookName(argments[1].trim()) - .author(argments[2].trim()) - .publisher(argments[3].trim()) - .publicationDate(argments[4].trim()) - .price(argments[5].trim()) - .build(); - result.getMesages().addAll(book.validate().getMesages()); - return result.getMesages().isEmpty(); - } + /* + * 検証の結果OKならtrueを返す。それ以外はfalseを返す + */ + private boolean validate(String[] argments) { + // パラメータ数チェック + if (argments.length != 6) { + result.addMessage("SyntaxError. The number of arguments does not match."); + return false; + } + // 書籍情報のチェック + book = new Book.Builder().isbn(argments[0].trim()).bookName(argments[1].trim()).author(argments[2].trim()) + .publisher(argments[3].trim()).publicationDate(argments[4].trim()).price(argments[5].trim()).build(); + result.getMesages().addAll(book.validate().getMesages()); + return result.getMesages().isEmpty(); + } } diff --git a/src/main/java/jp/co/training/InvalidCommand.java b/src/main/java/jp/co/training/InvalidCommand.java deleted file mode 100644 index def9c6d..0000000 --- a/src/main/java/jp/co/training/InvalidCommand.java +++ /dev/null @@ -1,16 +0,0 @@ -package jp.co.training; - -public final class InvalidCommand extends Command { - - @Override - public Result execute(String command, String[] argments) { - result = new Result(); - result.addMessage("Invalid Command."); - return result; - } - - @Override - public Command setNext(Command next) { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 2a306b7..530423f 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -1,33 +1,36 @@ package jp.co.training; +import static jp.co.training.Const.DELIMITER; +import static jp.co.training.Const.EXIT; +import static jp.co.training.Const.INSERT; +import static jp.co.training.Const.PROMPT; + import java.io.FileNotFoundException; import java.io.IOException; import java.util.Scanner; -import static jp.co.training.Const.DELIMITER; -import static jp.co.training.Const.PROMPT; public final class Main { - public static void main(String... args) throws FileNotFoundException, IOException { - Command command = new InsertCommand(); - command.setNext(new ExitCommand()).setNext(new InvalidCommand()); - try (Scanner scan = new Scanner(System.in)) { - while (true) { - System.out.print(PROMPT); - Result result = command.execute(scan.next().toLowerCase(), scan.nextLine().split(DELIMITER)); - outputMessages(result); - if (result != null && result.isExit()) { - break; - } - } - } - } + public static void main(String... args) throws FileNotFoundException, IOException { + Command command = new InsertCommand(INSERT); + command.setNext(new ExitCommand(EXIT)); + try (Scanner scan = new Scanner(System.in)) { + while (true) { + System.out.print(PROMPT); + Result result = command.execute(scan.next().toLowerCase(), scan.nextLine().split(DELIMITER)); + outputMessages(result); + if (result != null && result.isExit()) { + break; + } + } + } + } - private static void outputMessages(Result result) { - if (result != null && result.getMesages().size() > 0) { - result.getMesages().stream().forEach(message -> { - System.out.println(message); - }); - } - } + private static void outputMessages(Result result) { + if (result != null && result.getMesages().size() > 0) { + result.getMesages().stream().forEach(message -> { + System.out.println(message); + }); + } + } } From 615bdaa75b3507018fbbd9f6cf60289ae760d40e Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 25 Aug 2018 12:50:32 +0900 Subject: [PATCH 12/27] =?UTF-8?q?=E4=BB=A5=E4=B8=8B=E3=81=AE=E4=B8=8D?= =?UTF-8?q?=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3=20=E3=83=BB?= =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89=E5=AE=9F=E8=A1=8C=E6=99=82?= =?UTF-8?q?=E3=81=AB=E5=BF=85=E3=81=9A=E7=84=A1=E5=8A=B9=E3=81=AA=E3=82=B3?= =?UTF-8?q?=E3=83=9E=E3=83=B3=E3=83=89=E3=81=AE=E3=83=A1=E3=83=83=E3=82=BB?= =?UTF-8?q?=E3=83=BC=E3=82=B8=E3=82=92=E5=87=BA=E5=8A=9B=E3=81=97=E3=81=A6?= =?UTF-8?q?=E3=81=97=E3=81=BE=E3=81=86=20=E3=83=BB=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=81=B8=E3=81=AE=E7=99=BB=E9=8C=B2=E6=99=82?= =?UTF-8?q?=E3=81=AB=E3=83=87=E3=83=AA=E3=83=9F=E3=82=BF=E3=83=BC=E3=82=92?= =?UTF-8?q?=E5=87=BA=E5=8A=9B=E3=81=97=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Command.java | 2 +- src/main/java/jp/co/training/InsertCommand.java | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/jp/co/training/Command.java b/src/main/java/jp/co/training/Command.java index 60f2a56..7549704 100644 --- a/src/main/java/jp/co/training/Command.java +++ b/src/main/java/jp/co/training/Command.java @@ -12,7 +12,7 @@ public Command(String name) { public Result execute(String command, String[] argments) { if (command.equals(name)) { - executeCommand(command, argments); + return executeCommand(command, argments); } else if (next != null) { return next.execute(command, argments); } diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index cfc8943..b262e23 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -1,5 +1,6 @@ package jp.co.training; +import static jp.co.training.Const.DELIMITER; import static jp.co.training.Const.SAVE_FILE; import java.io.BufferedWriter; @@ -28,14 +29,13 @@ public Result executeCommand(String command, String[] argments) { } private Result createBook() { - try (BufferedWriter bw = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { - bw.write(book.getIsbn()); - bw.write(book.getBookName()); - bw.write(book.getAuthor()); - bw.write(book.getPublisher()); - bw.write(book.getPublicationDate()); - bw.write(book.getPrice()); + try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { + bw.write(book.getIsbn().trim() + DELIMITER); + bw.write(book.getBookName().trim() + DELIMITER); + bw.write(book.getAuthor().trim() + DELIMITER); + bw.write(book.getPublisher().trim() + DELIMITER); + bw.write(book.getPublicationDate().trim() + DELIMITER); + bw.write(book.getPrice().trim() + DELIMITER); bw.newLine(); } catch (IOException ex) { result.addMessage(SAVE_FILE + ": cannot open."); From 70ee61433f39d3ff178317b61f34ea47429520a9 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 25 Aug 2018 15:33:41 +0900 Subject: [PATCH 13/27] =?UTF-8?q?=E5=BC=95=E6=95=B0=E3=81=AE=E3=82=BB?= =?UTF-8?q?=E3=83=83=E3=83=88=E3=81=AE=E6=96=B9=E6=B3=95=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E3=80=81=E5=85=A5=E5=8A=9B=E6=83=85=E5=A0=B1=E4=BB=A5?= =?UTF-8?q?=E5=A4=96=E3=81=AE=E6=83=85=E5=A0=B1=E3=81=AE=E7=99=BB=E9=8C=B2?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Book.java | 228 +++++++++--------- src/main/java/jp/co/training/BookUtil.java | 110 +++++---- src/main/java/jp/co/training/Const.java | 83 ++++--- .../java/jp/co/training/InsertCommand.java | 34 ++- src/main/java/jp/co/training/Main.java | 8 +- src/main/java/jp/co/training/Status.java | 8 - 6 files changed, 259 insertions(+), 212 deletions(-) delete mode 100644 src/main/java/jp/co/training/Status.java diff --git a/src/main/java/jp/co/training/Book.java b/src/main/java/jp/co/training/Book.java index 9ebb507..ad6e2d6 100644 --- a/src/main/java/jp/co/training/Book.java +++ b/src/main/java/jp/co/training/Book.java @@ -1,6 +1,7 @@ package jp.co.training; import static jp.co.training.Const.DATE_PATTERN; +import static jp.co.training.Const.DELIMITER; import static jp.co.training.Const.MAX_AUTHOR; import static jp.co.training.Const.MAX_BOOK_NAME; import static jp.co.training.Const.MAX_ISBN; @@ -9,114 +10,121 @@ public class Book { - private final String isbn; - private final String bookName; - private final String author; - private final String publisher; - private final String publicationDate; - private final String price; - - public Result validate() { - Result result = new Result(); - - //isbn - BookUtil.checkLength(isbn, 1, MAX_ISBN).ifPresent(msg -> result.addMessage("ISBM:" + msg)); - - //bookName - BookUtil.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(msg -> result.addMessage("BOOK_NAME:" + msg)); - - //author - BookUtil.checkLength(author, 1, MAX_AUTHOR).ifPresent(msg -> result.addMessage("AUTHOR" + msg)); - - //publisher - BookUtil.checkLength(publisher, 1, MAX_PUBLISHER).ifPresent(msg -> result.addMessage("PUBLISHER:" + msg)); - - //price - BookUtil.checkLength(price, 1, MAX_PRICE).ifPresent(msg -> result.addMessage("PRICE:" + msg)); - BookUtil.checkNumber(price).ifPresent(msg -> result.addMessage("PRICE:" + msg)); - - //publicationDate - BookUtil.checkDatePattern(publicationDate, DATE_PATTERN).ifPresent(msg -> result.addMessage("PUBLICATION_DATE:" + msg)); - - return result; - } - - public String getIsbn() { - return isbn; - } - - public String getBookName() { - return bookName; - } - - public String getAuthor() { - return author; - } - - public String getPublisher() { - return publisher; - } - - public String getPublicationDate() { - return publicationDate; - } - - public String getPrice() { - return price; - } - - private Book(Builder builder) { - this.isbn = builder.isbn; - this.bookName = builder.bookName; - this.author = builder.author; - this.publisher = builder.publisher; - this.publicationDate = builder.publicationDate; - this.price = builder.price; - } - - public static class Builder { - - private String isbn; - private String bookName; - private String author; - private String publisher; - private String publicationDate; - private String price; - - public Builder isbn(String isbn) { - this.isbn = isbn; - return this; - } - - public Builder bookName(String bookName) { - this.bookName = bookName; - return this; - } - - public Builder author(String author) { - this.author = author; - return this; - } - - public Builder publisher(String publisher) { - this.publisher = publisher; - return this; - } - - public Builder publicationDate(String publicationDate) { - this.publicationDate = publicationDate; - return this; - } - - public Builder price(String price) { - this.price = price; - return this; - } - - public Book build() { - return new Book(this); - } - - } - + private final String isbn; + private final String bookName; + private final String author; + private final String publisher; + private final String publicationDate; + private final String price; + + public Result validate() { + Result result = new Result(); + + // isbn + BookUtil.checkLength(isbn, 1, MAX_ISBN).ifPresent(msg -> result.addMessage("ISBM:" + msg)); + + // bookName + BookUtil.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(msg -> result.addMessage("BOOK_NAME:" + msg)); + + // author + BookUtil.checkLength(author, 1, MAX_AUTHOR).ifPresent(msg -> result.addMessage("AUTHOR" + msg)); + + // publisher + BookUtil.checkLength(publisher, 1, MAX_PUBLISHER).ifPresent(msg -> result.addMessage("PUBLISHER:" + msg)); + + // price + BookUtil.checkLength(price, 1, MAX_PRICE).ifPresent(msg -> result.addMessage("PRICE:" + msg)); + BookUtil.checkNumber(price).ifPresent(msg -> result.addMessage("PRICE:" + msg)); + + // publicationDate + BookUtil.checkDatePattern(publicationDate, DATE_PATTERN) + .ifPresent(msg -> result.addMessage("PUBLICATION_DATE:" + msg)); + + return result; + } + + public String getIsbn() { + return isbn; + } + + public String getBookName() { + return bookName; + } + + public String getAuthor() { + return author; + } + + public String getPublisher() { + return publisher; + } + + public String getPublicationDate() { + return publicationDate; + } + + public String getPrice() { + return price; + } + + private Book(Builder builder) { + this.isbn = builder.isbn; + this.bookName = builder.bookName; + this.author = builder.author; + this.publisher = builder.publisher; + this.publicationDate = builder.publicationDate; + this.price = builder.price; + } + + public static class Builder { + + private String isbn; + private String bookName; + private String author; + private String publisher; + private String publicationDate; + private String price; + + public Builder isbn(String isbn) { + this.isbn = isbn; + return this; + } + + public Builder bookName(String bookName) { + this.bookName = bookName; + return this; + } + + public Builder author(String author) { + this.author = author; + return this; + } + + public Builder publisher(String publisher) { + this.publisher = publisher; + return this; + } + + public Builder publicationDate(String publicationDate) { + this.publicationDate = publicationDate; + return this; + } + + public Builder price(String price) { + this.price = price; + return this; + } + + public Book build() { + return new Book(this); + } + + } + + @Override + public String toString() { + return String.join(this.isbn, this.bookName, this.author, this.publisher, this.publicationDate, this.price, + DELIMITER); + + } } diff --git a/src/main/java/jp/co/training/BookUtil.java b/src/main/java/jp/co/training/BookUtil.java index b44156e..79a9f3b 100644 --- a/src/main/java/jp/co/training/BookUtil.java +++ b/src/main/java/jp/co/training/BookUtil.java @@ -1,5 +1,6 @@ package jp.co.training; +import java.security.SecureRandom; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; @@ -8,54 +9,65 @@ public class BookUtil { - private BookUtil() { - } - - /** - * 対象文字列が指定された最小文字数と最大文字数の範囲内であるかをチェックします
- * 範囲内である場合はOptionalの中身はnullとなる
- * 範囲外である場合はOptionalの中身は範囲外であることを示すメッセージとなる
- * - * @param target : - * @param min - * @param max - * @return - */ - public static Optional checkLength(String target, int min, int max) { - if (target.length() < min) { - return Optional.of("the length must be " + min + " or more. but actual is " + target.length() + "."); - } else if (target.length() > max) { - return Optional.of("the length must be " + max + " or less. but actual is " + target.length() + "."); - } - return Optional.empty(); - } - - public static Optional checkDatePattern(String target, String pattern) { - DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern); - try { - LocalDate.parse(target, df); - } catch (DateTimeParseException e) { - return Optional.of("Invalid Pattern. valid pattern is " + pattern + "."); - } - return Optional.empty(); - } - - public static Optional checkNumber(String target) { - if (!isNumber(target)) { - return Optional.of("It is not a numerical format."); - } - return Optional.empty(); - } - - /** - * valueが数値文字列の場合、または空文字の場合はtrueを返す - * - * @param value - * @return - */ - private static boolean isNumber(String value) { - return Pattern.compile("^[0-9]*$").matcher(value).matches(); -// return false; - } + private BookUtil() { + } + + /** + * 対象文字列が指定された最小文字数と最大文字数の範囲内であるかをチェックします
+ * 範囲内である場合はOptionalの中身はnullとなる
+ * 範囲外である場合はOptionalの中身は範囲外であることを示すメッセージとなる
+ * + * @param target + * : + * @param min + * @param max + * @return + */ + public static Optional checkLength(String target, int min, int max) { + if (target.length() < min) { + return Optional.of("the length must be " + min + " or more. but actual is " + target.length() + "."); + } else if (target.length() > max) { + return Optional.of("the length must be " + max + " or less. but actual is " + target.length() + "."); + } + return Optional.empty(); + } + + public static Optional checkDatePattern(String target, String pattern) { + DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern); + try { + LocalDate.parse(target, df); + } catch (DateTimeParseException e) { + return Optional.of("Invalid Pattern. valid pattern is " + pattern + "."); + } + return Optional.empty(); + } + + public static Optional checkNumber(String target) { + if (!isNumber(target)) { + return Optional.of("It is not a numerical format."); + } + return Optional.empty(); + } + + /** + * valueが数値文字列の場合、または空文字の場合はtrueを返す + * + * @param value + * @return + */ + private static boolean isNumber(String value) { + return Pattern.compile("^[0-9]*$").matcher(value).matches(); + } + + public static String generateID(int digit) { + SecureRandom random = new SecureRandom(); + byte bytes[] = new byte[digit / 2]; + random.nextBytes(bytes); + StringBuilder sb = new StringBuilder(); + for (byte d : bytes) { + sb.append(String.format("%02X", d)); + } + return sb.toString(); + } } diff --git a/src/main/java/jp/co/training/Const.java b/src/main/java/jp/co/training/Const.java index 5b3b4a8..ef7b623 100644 --- a/src/main/java/jp/co/training/Const.java +++ b/src/main/java/jp/co/training/Const.java @@ -5,43 +5,56 @@ public final class Const { - //外部ファイルによる設定不可能な定数 - public static final String INSERT = "insert"; - public static final String EXIT = "exit"; - public static final int MAX_ISBN = 13; - public static final int MAX_BOOK_NAME = 50; - public static final int MAX_AUTHOR = 30; - public static final int MAX_PUBLISHER = 30; - public static final int MAX_PRICE = 9; - public static final String DATE_PATTERN = "yyyyMMdd"; + // 外部ファイルによる設定不可能な定数 + public static final String INSERT = "insert"; + public static final String EXIT = "exit"; + public static final int MAX_ISBN = 13; + public static final int MAX_BOOK_NAME = 50; + public static final int MAX_AUTHOR = 30; + public static final int MAX_PUBLISHER = 30; + public static final int MAX_PRICE = 9; + public static final String DATE_PATTERN = "yyyyMMdd"; + public static final String DATE_TIME_PATTERN = "yyyyMMdd hhmmss.SSS"; + public static final int ID_LENGTH = 16; - //外部ファイルによる設定が可能な定数 - public static final String PROMPT; - public static final String END_MESSAGE; - public static final String DELIMITER; - public static final String SAVE_FILE; + // 外部ファイルによる設定が可能な定数 + public static final String PROMPT; + public static final String END_MESSAGE; + public static final String DELIMITER; + public static final String SAVE_FILE; + public static final String USER_NAME; - //外部ファイルの設定ファイルのキー - private static final String PROMPT_KEY = "prompt"; - private static final String END_MESSAGE_KEY = "end.message"; - private static final String DELIMITER_KEY = "delimiter"; - private static final String SAVE_FILE_KEY = "save.file"; + // 外部ファイルの設定ファイルのキー + private static final String PROMPT_KEY = "prompt"; + private static final String END_MESSAGE_KEY = "end.message"; + private static final String DELIMITER_KEY = "delimiter"; + private static final String SAVE_FILE_KEY = "save.file"; + private static final String USER_NAME_KEY = "user.name"; - static { - ResourceBundle rb = loadResource(); - PROMPT = (rb == null || !rb.containsKey(PROMPT_KEY)) ? "books>" : rb.getString(PROMPT_KEY); - DELIMITER = (rb == null || !rb.containsKey(DELIMITER_KEY)) ? "," : rb.getString(DELIMITER_KEY); - SAVE_FILE = (rb == null || !rb.containsKey(SAVE_FILE_KEY)) ? "savefile" : rb.getString(SAVE_FILE_KEY); - END_MESSAGE = (rb == null || !rb.containsKey(END_MESSAGE_KEY)) ? "bye." : rb.getString(END_MESSAGE_KEY); - } + static { + ResourceBundle rb = loadResource(); + if (rb == null) { + System.out.println("cannnot find configfile."); + System.exit(1); + } + if (!rb.containsKey(USER_NAME_KEY)) { + System.out.println("you must define registrant in configfile."); + System.exit(1); + } + USER_NAME = rb.getString(USER_NAME_KEY); + PROMPT = (rb.containsKey(PROMPT_KEY)) ? rb.getString(PROMPT_KEY) : "books>"; + DELIMITER = (rb.containsKey(DELIMITER_KEY)) ? rb.getString(DELIMITER_KEY) : ","; + SAVE_FILE = (rb.containsKey(SAVE_FILE_KEY)) ? rb.getString(DELIMITER_KEY) : "savefile"; + END_MESSAGE = (rb.containsKey(END_MESSAGE_KEY)) ? rb.getString(END_MESSAGE_KEY) : "bye."; + } - private static ResourceBundle loadResource() { - ResourceBundle rb = null; - try { - rb = ResourceBundle.getBundle("resource"); - } catch (MissingResourceException e) { - System.out.println("WARNNING: cannot find resource.properties"); - } - return rb; - } + private static ResourceBundle loadResource() { + ResourceBundle rb = null; + try { + rb = ResourceBundle.getBundle("resource"); + } catch (MissingResourceException e) { + System.out.println("WARNNING: cannot find resource.properties"); + } + return rb; + } } diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index b262e23..abbccc6 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -1,13 +1,18 @@ package jp.co.training; +import static jp.co.training.Const.DATE_TIME_PATTERN; import static jp.co.training.Const.DELIMITER; +import static jp.co.training.Const.ID_LENGTH; import static jp.co.training.Const.SAVE_FILE; +import static jp.co.training.Const.USER_NAME; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; public final class InsertCommand extends Command { @@ -29,13 +34,18 @@ public Result executeCommand(String command, String[] argments) { } private Result createBook() { - try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { - bw.write(book.getIsbn().trim() + DELIMITER); - bw.write(book.getBookName().trim() + DELIMITER); - bw.write(book.getAuthor().trim() + DELIMITER); - bw.write(book.getPublisher().trim() + DELIMITER); - bw.write(book.getPublicationDate().trim() + DELIMITER); - bw.write(book.getPrice().trim() + DELIMITER); + + String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); + + String output = String.join(BookUtil.generateID(ID_LENGTH), + book.toString(), + USER_NAME, today, + USER_NAME, today, + DELIMITER); + + try (BufferedWriter bw = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { + bw.write(output); bw.newLine(); } catch (IOException ex) { result.addMessage(SAVE_FILE + ": cannot open."); @@ -55,9 +65,15 @@ private boolean validate(String[] argments) { result.addMessage("SyntaxError. The number of arguments does not match."); return false; } + // 書籍情報のチェック - book = new Book.Builder().isbn(argments[0].trim()).bookName(argments[1].trim()).author(argments[2].trim()) - .publisher(argments[3].trim()).publicationDate(argments[4].trim()).price(argments[5].trim()).build(); + book = new Book.Builder() + .isbn(argments[0]) + .bookName(argments[1]) + .author(argments[2]) + .publisher(argments[3]) + .publicationDate(argments[4]) + .price(argments[5]).build(); result.getMesages().addAll(book.validate().getMesages()); return result.getMesages().isEmpty(); } diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 530423f..5a9315a 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -7,6 +7,7 @@ import java.io.FileNotFoundException; import java.io.IOException; +import java.util.Arrays; import java.util.Scanner; public final class Main { @@ -17,7 +18,12 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio try (Scanner scan = new Scanner(System.in)) { while (true) { System.out.print(PROMPT); - Result result = command.execute(scan.next().toLowerCase(), scan.nextLine().split(DELIMITER)); + String inputCommand = scan.next().toLowerCase(); + String[] argments = scan.nextLine().split(DELIMITER); + argments = (String[]) Arrays.stream(argments).map(e -> e.trim()).toArray(); + + // コマンド実行 + Result result = command.execute(inputCommand, argments); outputMessages(result); if (result != null && result.isExit()) { break; diff --git a/src/main/java/jp/co/training/Status.java b/src/main/java/jp/co/training/Status.java deleted file mode 100644 index 2379628..0000000 --- a/src/main/java/jp/co/training/Status.java +++ /dev/null @@ -1,8 +0,0 @@ -package jp.co.training; - -public enum Status { - - KEEP,//そのまま継続 - BREAK//ループを抜ける - -} From c25b213cb131f2e05c07d91368372980eba4cf77 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 25 Aug 2018 16:30:26 +0900 Subject: [PATCH 14/27] =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=81=AE=E3=83=91=E3=82=B9=E3=82=92=E5=BC=95?= =?UTF-8?q?=E6=95=B0=E3=81=A7=E6=8C=87=E5=AE=9A=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Book.java | 6 +-- src/main/java/jp/co/training/Config.java | 42 +++++++++++++++++ src/main/java/jp/co/training/Const.java | 45 +------------------ src/main/java/jp/co/training/ExitCommand.java | 3 ++ .../java/jp/co/training/InsertCommand.java | 16 +++---- src/main/java/jp/co/training/Main.java | 13 +++--- src/main/resources/resource.properties | 2 +- 7 files changed, 65 insertions(+), 62 deletions(-) create mode 100644 src/main/java/jp/co/training/Config.java diff --git a/src/main/java/jp/co/training/Book.java b/src/main/java/jp/co/training/Book.java index ad6e2d6..4b055db 100644 --- a/src/main/java/jp/co/training/Book.java +++ b/src/main/java/jp/co/training/Book.java @@ -1,12 +1,12 @@ package jp.co.training; import static jp.co.training.Const.DATE_PATTERN; -import static jp.co.training.Const.DELIMITER; import static jp.co.training.Const.MAX_AUTHOR; import static jp.co.training.Const.MAX_BOOK_NAME; import static jp.co.training.Const.MAX_ISBN; import static jp.co.training.Const.MAX_PRICE; import static jp.co.training.Const.MAX_PUBLISHER; +import static jp.co.training.Main.config; public class Book { @@ -123,8 +123,8 @@ public Book build() { @Override public String toString() { - return String.join(this.isbn, this.bookName, this.author, this.publisher, this.publicationDate, this.price, - DELIMITER); + return String.join(config.delimiter, this.isbn, this.bookName, this.author, this.publisher, + this.publicationDate, this.price); } } diff --git a/src/main/java/jp/co/training/Config.java b/src/main/java/jp/co/training/Config.java new file mode 100644 index 0000000..1be1384 --- /dev/null +++ b/src/main/java/jp/co/training/Config.java @@ -0,0 +1,42 @@ +package jp.co.training; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Config { + + // 外部ファイルによる設定が可能な定数 + public String prompt; + public String endMessage; + public String delimiter; + public String saveFile; + public String userName; + + // 外部ファイルの設定ファイルのキー + private static final String PROMPT_KEY = "prompt"; + private static final String END_MESSAGE_KEY = "end.message"; + private static final String DELIMITER_KEY = "delimiter"; + private static final String SAVE_FILE_KEY = "save.file"; + private static final String USER_NAME_KEY = "user.name"; + + public Config load(String path) { + ResourceBundle rb = null; + try { + rb = ResourceBundle.getBundle(path); + } catch (MissingResourceException e) { + System.out.println("ERROR: cannnot find configfile."); + System.exit(1); + } + if (!rb.containsKey(USER_NAME_KEY)) { + System.out.println("ERROR: you must define registrant in configfile."); + System.exit(1); + } + + userName = rb.getString(USER_NAME_KEY); + prompt = (rb.containsKey(PROMPT_KEY)) ? rb.getString(PROMPT_KEY) : "books>"; + delimiter = (rb.containsKey(DELIMITER_KEY)) ? rb.getString(DELIMITER_KEY) : ","; + saveFile = (rb.containsKey(SAVE_FILE_KEY)) ? rb.getString(DELIMITER_KEY) : "savefile"; + endMessage = (rb.containsKey(END_MESSAGE_KEY)) ? rb.getString(END_MESSAGE_KEY) : "bye."; + return this; + } +} diff --git a/src/main/java/jp/co/training/Const.java b/src/main/java/jp/co/training/Const.java index ef7b623..d753374 100644 --- a/src/main/java/jp/co/training/Const.java +++ b/src/main/java/jp/co/training/Const.java @@ -1,11 +1,8 @@ package jp.co.training; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - public final class Const { - // 外部ファイルによる設定不可能な定数 + public static final String CONFIG_FILE = "resource"; public static final String INSERT = "insert"; public static final String EXIT = "exit"; public static final int MAX_ISBN = 13; @@ -17,44 +14,4 @@ public final class Const { public static final String DATE_TIME_PATTERN = "yyyyMMdd hhmmss.SSS"; public static final int ID_LENGTH = 16; - // 外部ファイルによる設定が可能な定数 - public static final String PROMPT; - public static final String END_MESSAGE; - public static final String DELIMITER; - public static final String SAVE_FILE; - public static final String USER_NAME; - - // 外部ファイルの設定ファイルのキー - private static final String PROMPT_KEY = "prompt"; - private static final String END_MESSAGE_KEY = "end.message"; - private static final String DELIMITER_KEY = "delimiter"; - private static final String SAVE_FILE_KEY = "save.file"; - private static final String USER_NAME_KEY = "user.name"; - - static { - ResourceBundle rb = loadResource(); - if (rb == null) { - System.out.println("cannnot find configfile."); - System.exit(1); - } - if (!rb.containsKey(USER_NAME_KEY)) { - System.out.println("you must define registrant in configfile."); - System.exit(1); - } - USER_NAME = rb.getString(USER_NAME_KEY); - PROMPT = (rb.containsKey(PROMPT_KEY)) ? rb.getString(PROMPT_KEY) : "books>"; - DELIMITER = (rb.containsKey(DELIMITER_KEY)) ? rb.getString(DELIMITER_KEY) : ","; - SAVE_FILE = (rb.containsKey(SAVE_FILE_KEY)) ? rb.getString(DELIMITER_KEY) : "savefile"; - END_MESSAGE = (rb.containsKey(END_MESSAGE_KEY)) ? rb.getString(END_MESSAGE_KEY) : "bye."; - } - - private static ResourceBundle loadResource() { - ResourceBundle rb = null; - try { - rb = ResourceBundle.getBundle("resource"); - } catch (MissingResourceException e) { - System.out.println("WARNNING: cannot find resource.properties"); - } - return rb; - } } diff --git a/src/main/java/jp/co/training/ExitCommand.java b/src/main/java/jp/co/training/ExitCommand.java index 79c4866..dc961f3 100644 --- a/src/main/java/jp/co/training/ExitCommand.java +++ b/src/main/java/jp/co/training/ExitCommand.java @@ -1,5 +1,7 @@ package jp.co.training; +import static jp.co.training.Main.config; + public final class ExitCommand extends Command { public ExitCommand(String name) { @@ -9,6 +11,7 @@ public ExitCommand(String name) { @Override public Result executeCommand(String command, String[] argments) { Result result = new Result(); + result.addMessage(config.endMessage); result.setExit(true); return result; } diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index abbccc6..c1fa849 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -1,10 +1,8 @@ package jp.co.training; import static jp.co.training.Const.DATE_TIME_PATTERN; -import static jp.co.training.Const.DELIMITER; import static jp.co.training.Const.ID_LENGTH; -import static jp.co.training.Const.SAVE_FILE; -import static jp.co.training.Const.USER_NAME; +import static jp.co.training.Main.config; import java.io.BufferedWriter; import java.io.FileOutputStream; @@ -37,18 +35,18 @@ private Result createBook() { String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); - String output = String.join(BookUtil.generateID(ID_LENGTH), + String output = String.join(config.delimiter, + BookUtil.generateID(ID_LENGTH), book.toString(), - USER_NAME, today, - USER_NAME, today, - DELIMITER); + config.userName, today, + config.userName, today); try (BufferedWriter bw = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(SAVE_FILE, true), StandardCharsets.UTF_8))) { + new OutputStreamWriter(new FileOutputStream(config.saveFile, true), StandardCharsets.UTF_8))) { bw.write(output); bw.newLine(); } catch (IOException ex) { - result.addMessage(SAVE_FILE + ": cannot open."); + result.addMessage(config.saveFile + ": cannot open."); result.setExit(true); return result; } diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 5a9315a..4b6cdb7 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -1,9 +1,8 @@ package jp.co.training; -import static jp.co.training.Const.DELIMITER; +import static jp.co.training.Const.CONFIG_FILE; import static jp.co.training.Const.EXIT; import static jp.co.training.Const.INSERT; -import static jp.co.training.Const.PROMPT; import java.io.FileNotFoundException; import java.io.IOException; @@ -12,15 +11,19 @@ public final class Main { + public static Config config; + public static void main(String... args) throws FileNotFoundException, IOException { + + config = new Config().load(args.length > 0 && args[0] != null ? args[0] : CONFIG_FILE); Command command = new InsertCommand(INSERT); command.setNext(new ExitCommand(EXIT)); try (Scanner scan = new Scanner(System.in)) { while (true) { - System.out.print(PROMPT); + System.out.print(config.prompt); String inputCommand = scan.next().toLowerCase(); - String[] argments = scan.nextLine().split(DELIMITER); - argments = (String[]) Arrays.stream(argments).map(e -> e.trim()).toArray(); + String[] argments = scan.nextLine().split(config.delimiter); + argments = (String[]) Arrays.stream(argments).map(e -> e.trim()).toArray(String[]::new); // コマンド実行 Result result = command.execute(inputCommand, argments); diff --git a/src/main/resources/resource.properties b/src/main/resources/resource.properties index e8bfc1f..593f94c 100644 --- a/src/main/resources/resource.properties +++ b/src/main/resources/resource.properties @@ -1 +1 @@ -aa=aaa \ No newline at end of file +user.name=yamada taro \ No newline at end of file From 2e1201872371bf97ee989d32be21dcba4a379f83 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 25 Aug 2018 17:08:06 +0900 Subject: [PATCH 15/27] =?UTF-8?q?junit5=E3=81=AE=E3=83=A9=E3=82=A4?= =?UTF-8?q?=E3=83=96=E3=83=A9=E3=83=AA=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 62 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index 4e600a4..e2a3b8c 100644 --- a/pom.xml +++ b/pom.xml @@ -9,6 +9,7 @@ UTF-8 1.8 1.8 + 5.0.2 @@ -23,31 +24,46 @@ - + + maven-compiler-plugin + 3.7.0 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + + org.junit.platform + junit-platform-surefire-provider + 1.0.2 + + + - - org.apache.commons - commons-csv - 1.5 - + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + org.junit.platform + junit-platform-launcher + 1.0.2 + test + \ No newline at end of file From 4c53fe625ca1b1dc650b8c11f5a61729ff3431ee Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 25 Aug 2018 17:48:48 +0900 Subject: [PATCH 16/27] =?UTF-8?q?jdk=E3=82=B3=E3=83=B3=E3=83=91=E3=82=A4?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=81=8C=E3=83=87=E3=83=95=E3=82=A9=E3=83=AB=E3=83=88=E3=81=A7?= =?UTF-8?q?1.5=E3=81=AB=E3=81=AA=E3=81=A3=E3=81=A6=E3=81=97=E3=81=BE?= =?UTF-8?q?=E3=81=86=E5=95=8F=E9=A1=8C=E3=82=92=E8=A7=A3=E6=B6=88=E3=80=82?= =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92?= =?UTF-8?q?=E4=BD=9C=E6=88=90=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 +++--- src/test/java/jp/co/training/BookTest.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/test/java/jp/co/training/BookTest.java diff --git a/pom.xml b/pom.xml index e2a3b8c..a4f12af 100644 --- a/pom.xml +++ b/pom.xml @@ -28,8 +28,8 @@ maven-compiler-plugin 3.7.0 - ${java.version} - ${java.version} + ${maven.compiler.source} + ${maven.compiler.target} @@ -43,7 +43,7 @@ 1.0.2 - + diff --git a/src/test/java/jp/co/training/BookTest.java b/src/test/java/jp/co/training/BookTest.java new file mode 100644 index 0000000..bbb6a37 --- /dev/null +++ b/src/test/java/jp/co/training/BookTest.java @@ -0,0 +1,14 @@ +package jp.co.training; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class BookTest { + + @Test + void test() { + fail("まだ実装されていません"); + } + +} From a260d0b36a5136454dd9c5d61b3f1a877ec75c68 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sun, 26 Aug 2018 13:53:54 +0900 Subject: [PATCH 17/27] =?UTF-8?q?JUnit5=E3=81=AE=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=82=B1=E3=83=BC=E3=82=B9=E3=82=92=E4=BD=9C=E6=88=90?= =?UTF-8?q?=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Book.java | 243 +++++++++--------- src/main/java/jp/co/training/BookUtil.java | 7 +- .../java/jp/co/training/InsertCommand.java | 109 ++++---- src/main/java/jp/co/training/Main.java | 68 ++--- src/test/java/jp/co/training/BookTest.java | 46 +++- .../java/jp/co/training/BookUtilTest.java | 68 +++++ 6 files changed, 321 insertions(+), 220 deletions(-) create mode 100644 src/test/java/jp/co/training/BookUtilTest.java diff --git a/src/main/java/jp/co/training/Book.java b/src/main/java/jp/co/training/Book.java index 4b055db..5d020c6 100644 --- a/src/main/java/jp/co/training/Book.java +++ b/src/main/java/jp/co/training/Book.java @@ -1,130 +1,125 @@ package jp.co.training; -import static jp.co.training.Const.DATE_PATTERN; -import static jp.co.training.Const.MAX_AUTHOR; -import static jp.co.training.Const.MAX_BOOK_NAME; -import static jp.co.training.Const.MAX_ISBN; -import static jp.co.training.Const.MAX_PRICE; -import static jp.co.training.Const.MAX_PUBLISHER; -import static jp.co.training.Main.config; +import static jp.co.training.Const.*; +import static jp.co.training.Main.*; public class Book { - private final String isbn; - private final String bookName; - private final String author; - private final String publisher; - private final String publicationDate; - private final String price; - - public Result validate() { - Result result = new Result(); - - // isbn - BookUtil.checkLength(isbn, 1, MAX_ISBN).ifPresent(msg -> result.addMessage("ISBM:" + msg)); - - // bookName - BookUtil.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(msg -> result.addMessage("BOOK_NAME:" + msg)); - - // author - BookUtil.checkLength(author, 1, MAX_AUTHOR).ifPresent(msg -> result.addMessage("AUTHOR" + msg)); - - // publisher - BookUtil.checkLength(publisher, 1, MAX_PUBLISHER).ifPresent(msg -> result.addMessage("PUBLISHER:" + msg)); - - // price - BookUtil.checkLength(price, 1, MAX_PRICE).ifPresent(msg -> result.addMessage("PRICE:" + msg)); - BookUtil.checkNumber(price).ifPresent(msg -> result.addMessage("PRICE:" + msg)); - - // publicationDate - BookUtil.checkDatePattern(publicationDate, DATE_PATTERN) - .ifPresent(msg -> result.addMessage("PUBLICATION_DATE:" + msg)); - - return result; - } - - public String getIsbn() { - return isbn; - } - - public String getBookName() { - return bookName; - } - - public String getAuthor() { - return author; - } - - public String getPublisher() { - return publisher; - } - - public String getPublicationDate() { - return publicationDate; - } - - public String getPrice() { - return price; - } - - private Book(Builder builder) { - this.isbn = builder.isbn; - this.bookName = builder.bookName; - this.author = builder.author; - this.publisher = builder.publisher; - this.publicationDate = builder.publicationDate; - this.price = builder.price; - } - - public static class Builder { - - private String isbn; - private String bookName; - private String author; - private String publisher; - private String publicationDate; - private String price; - - public Builder isbn(String isbn) { - this.isbn = isbn; - return this; - } - - public Builder bookName(String bookName) { - this.bookName = bookName; - return this; - } - - public Builder author(String author) { - this.author = author; - return this; - } - - public Builder publisher(String publisher) { - this.publisher = publisher; - return this; - } - - public Builder publicationDate(String publicationDate) { - this.publicationDate = publicationDate; - return this; - } - - public Builder price(String price) { - this.price = price; - return this; - } - - public Book build() { - return new Book(this); - } - - } - - @Override - public String toString() { - return String.join(config.delimiter, this.isbn, this.bookName, this.author, this.publisher, - this.publicationDate, this.price); - - } + private final String isbn; + private final String bookName; + private final String author; + private final String publisher; + private final String publicationDate; + private final String price; + + public Result validate() { + Result result = new Result(); + + // isbn + BookUtil.checkLength(isbn, 1, MAX_ISBN).ifPresent(msg -> result.addMessage("ISBM:" + msg)); + + // bookName + BookUtil.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(msg -> result.addMessage("BOOK_NAME:" + msg)); + + // author + BookUtil.checkLength(author, 1, MAX_AUTHOR).ifPresent(msg -> result.addMessage("AUTHOR" + msg)); + + // publisher + BookUtil.checkLength(publisher, 1, MAX_PUBLISHER).ifPresent(msg -> result.addMessage("PUBLISHER:" + msg)); + + // price + BookUtil.checkLength(price, 1, MAX_PRICE).ifPresent(msg -> result.addMessage("PRICE:" + msg)); + BookUtil.checkNumber(price).ifPresent(msg -> result.addMessage("PRICE:" + msg)); + + // publicationDate + BookUtil.checkDatePattern(publicationDate, DATE_PATTERN) + .ifPresent(msg -> result.addMessage("PUBLICATION_DATE:" + msg)); + + return result; + } + + public String getIsbn() { + return isbn; + } + + public String getBookName() { + return bookName; + } + + public String getAuthor() { + return author; + } + + public String getPublisher() { + return publisher; + } + + public String getPublicationDate() { + return publicationDate; + } + + public String getPrice() { + return price; + } + + private Book(Builder builder) { + this.isbn = builder.isbn; + this.bookName = builder.bookName; + this.author = builder.author; + this.publisher = builder.publisher; + this.publicationDate = builder.publicationDate; + this.price = builder.price; + } + + public static class Builder { + + private String isbn; + private String bookName; + private String author; + private String publisher; + private String publicationDate; + private String price; + + public Builder isbn(String isbn) { + this.isbn = isbn; + return this; + } + + public Builder bookName(String bookName) { + this.bookName = bookName; + return this; + } + + public Builder author(String author) { + this.author = author; + return this; + } + + public Builder publisher(String publisher) { + this.publisher = publisher; + return this; + } + + public Builder publicationDate(String publicationDate) { + this.publicationDate = publicationDate; + return this; + } + + public Builder price(String price) { + this.price = price; + return this; + } + + public Book build() { + return new Book(this); + } + + } + + @Override + public String toString() { + return String.join(config.delimiter, this.isbn, this.bookName, this.author, this.publisher, + this.publicationDate, this.price); + + } } diff --git a/src/main/java/jp/co/training/BookUtil.java b/src/main/java/jp/co/training/BookUtil.java index 79a9f3b..371b963 100644 --- a/src/main/java/jp/co/training/BookUtil.java +++ b/src/main/java/jp/co/training/BookUtil.java @@ -15,16 +15,17 @@ private BookUtil() { /** * 対象文字列が指定された最小文字数と最大文字数の範囲内であるかをチェックします
* 範囲内である場合はOptionalの中身はnullとなる
- * 範囲外である場合はOptionalの中身は範囲外であることを示すメッセージとなる
+ * 範囲外である場合はOptionalの中身はエラーメッセージとなる
* * @param target - * : * @param min * @param max * @return */ public static Optional checkLength(String target, int min, int max) { - if (target.length() < min) { + if (target == null) { + return Optional.of("the length must be " + min + " or more. but actual is null."); + } else if (target.length() < min) { return Optional.of("the length must be " + min + " or more. but actual is " + target.length() + "."); } else if (target.length() > max) { return Optional.of("the length must be " + max + " or less. but actual is " + target.length() + "."); diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index c1fa849..a9e947d 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -1,8 +1,7 @@ package jp.co.training; -import static jp.co.training.Const.DATE_TIME_PATTERN; -import static jp.co.training.Const.ID_LENGTH; -import static jp.co.training.Main.config; +import static jp.co.training.Const.*; +import static jp.co.training.Main.*; import java.io.BufferedWriter; import java.io.FileOutputStream; @@ -14,66 +13,66 @@ public final class InsertCommand extends Command { - private Result result; + private Result result; - private Book book; + private Book book; - public InsertCommand(String name) { - super(name); - } + public InsertCommand(String name) { + super(name); + } - @Override - public Result executeCommand(String command, String[] argments) { - result = new Result(); - if (!validate(argments)) { - return result; - } - return createBook(); - } + @Override + public Result executeCommand(String command, String[] argments) { + result = new Result(); + if (!validate(argments)) { + return result; + } + return createBook(); + } - private Result createBook() { + private Result createBook() { - String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); + String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); - String output = String.join(config.delimiter, - BookUtil.generateID(ID_LENGTH), - book.toString(), - config.userName, today, - config.userName, today); + String output = String.join(config.delimiter, + BookUtil.generateID(ID_LENGTH), + book.toString(), + config.userName, today, + config.userName, today); - try (BufferedWriter bw = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(config.saveFile, true), StandardCharsets.UTF_8))) { - bw.write(output); - bw.newLine(); - } catch (IOException ex) { - result.addMessage(config.saveFile + ": cannot open."); - result.setExit(true); - return result; - } - result.addMessage("inserted."); - return result; - } + try (BufferedWriter bw = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(config.saveFile, true), StandardCharsets.UTF_8))) { + bw.write(output); + bw.newLine(); + } catch (IOException ex) { + result.addMessage(config.saveFile + ": cannot open."); + result.setExit(true); + return result; + } + result.addMessage("inserted."); + return result; + } - /* - * 検証の結果OKならtrueを返す。それ以外はfalseを返す - */ - private boolean validate(String[] argments) { - // パラメータ数チェック - if (argments.length != 6) { - result.addMessage("SyntaxError. The number of arguments does not match."); - return false; - } + /* + * 検証の結果OKならtrueを返す。それ以外はfalseを返す + */ + private boolean validate(String[] argments) { + // パラメータ数チェック + if (argments.length != 6) { + result.addMessage("SyntaxError. The number of arguments does not match."); + return false; + } - // 書籍情報のチェック - book = new Book.Builder() - .isbn(argments[0]) - .bookName(argments[1]) - .author(argments[2]) - .publisher(argments[3]) - .publicationDate(argments[4]) - .price(argments[5]).build(); - result.getMesages().addAll(book.validate().getMesages()); - return result.getMesages().isEmpty(); - } + // 書籍情報のチェック + book = new Book.Builder() + .isbn(argments[0]) + .bookName(argments[1]) + .author(argments[2]) + .publisher(argments[3]) + .publicationDate(argments[4]) + .price(argments[5]).build(); + result.getMesages().addAll(book.validate().getMesages()); + return result.getMesages().isEmpty(); + } } diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 4b6cdb7..6d18991 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -1,8 +1,6 @@ package jp.co.training; -import static jp.co.training.Const.CONFIG_FILE; -import static jp.co.training.Const.EXIT; -import static jp.co.training.Const.INSERT; +import static jp.co.training.Const.*; import java.io.FileNotFoundException; import java.io.IOException; @@ -11,35 +9,37 @@ public final class Main { - public static Config config; - - public static void main(String... args) throws FileNotFoundException, IOException { - - config = new Config().load(args.length > 0 && args[0] != null ? args[0] : CONFIG_FILE); - Command command = new InsertCommand(INSERT); - command.setNext(new ExitCommand(EXIT)); - try (Scanner scan = new Scanner(System.in)) { - while (true) { - System.out.print(config.prompt); - String inputCommand = scan.next().toLowerCase(); - String[] argments = scan.nextLine().split(config.delimiter); - argments = (String[]) Arrays.stream(argments).map(e -> e.trim()).toArray(String[]::new); - - // コマンド実行 - Result result = command.execute(inputCommand, argments); - outputMessages(result); - if (result != null && result.isExit()) { - break; - } - } - } - } - - private static void outputMessages(Result result) { - if (result != null && result.getMesages().size() > 0) { - result.getMesages().stream().forEach(message -> { - System.out.println(message); - }); - } - } + public static Config config; + + public static void main(String... args) throws FileNotFoundException, IOException { + + config = new Config().load(args.length > 0 && args[0] != null ? args[0] : CONFIG_FILE); + + Command command = new InsertCommand(INSERT); + command.setNext(new ExitCommand(EXIT)); + + try (Scanner scan = new Scanner(System.in)) { + while (true) { + System.out.print(config.prompt); + String inputCommand = scan.next().toLowerCase(); + String[] argments = scan.nextLine().split(config.delimiter); + argments = (String[]) Arrays.stream(argments).map(e -> e.trim()).toArray(String[]::new); + + // コマンド実行 + Result result = command.execute(inputCommand, argments); + outputMessages(result); + if (result != null && result.isExit()) { + break; + } + } + } + } + + private static void outputMessages(Result result) { + if (result != null && result.getMesages().size() > 0) { + result.getMesages().stream().forEach(message -> { + System.out.println(message); + }); + } + } } diff --git a/src/test/java/jp/co/training/BookTest.java b/src/test/java/jp/co/training/BookTest.java index bbb6a37..52a5dda 100644 --- a/src/test/java/jp/co/training/BookTest.java +++ b/src/test/java/jp/co/training/BookTest.java @@ -1,14 +1,52 @@ package jp.co.training; +import static jp.co.training.Const.*; import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; class BookTest { - @Test - void test() { - fail("まだ実装されていません"); - } + @Nested + @DisplayName("validateメソッドのテスト") + class validateTest { + + @Test + @DisplayName("ISBNの文字数チェックエラー") + void validateIsbnNG() { + Book book = new Book.Builder().isbn("12345678901234") + .bookName("社長も投票で決める会社をやってみた") + .author("武井 浩三") + .publisher("WAVE出版") + .publicationDate("20180423") + .price("1620").build(); + Result result = book.validate(); + assertFalse(result.isExit()); + assertEquals(1, result.getMesages().size()); + assertEquals("ISBM:the length must be " + MAX_ISBN + " or less. but actual is 14.", + result.getMesages().get(0)); + } + + } + + @Nested + @DisplayName("toStringメソッドのテスト") + class toStringTest { + + } + + @Nested + @DisplayName("Builderクラスのテスト") + class BuilderTest { + + @Nested + @DisplayName("Buildメソッドのテスト") + class buildTest { + + } + + } } diff --git a/src/test/java/jp/co/training/BookUtilTest.java b/src/test/java/jp/co/training/BookUtilTest.java new file mode 100644 index 0000000..9dd7e47 --- /dev/null +++ b/src/test/java/jp/co/training/BookUtilTest.java @@ -0,0 +1,68 @@ +package jp.co.training; + +import static jp.co.training.Const.*; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Optional; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class BookUtilTest { + + @Nested + class CheckLengthTest { + @Test + @DisplayName("最大文字超過チェックOK") + void maxOverOK() { + Optional result = BookUtil.checkLength("あいう", 1, 3); + assertFalse(result.isPresent()); + } + + @Test + @DisplayName("最小文字超過チェックOK") + void minUnderOK() { + Optional result = BookUtil.checkLength("あ", 1, 3); + assertFalse(result.isPresent()); + } + + @Test + @DisplayName("最大文字超過チェックNG") + void maxOverNG() { + Optional result = BookUtil.checkLength("あいうえ", 1, 3); + assertEquals("the length must be " + 3 + " or less. but actual is " + 4 + ".", result.get()); + } + + @Test + @DisplayName("最小文字超過チェックNG") + void minUnderNG() { + Optional result = BookUtil.checkLength("", 1, 3); + assertEquals("the length must be " + 1 + " or more. but actual is " + 0 + ".", result.get()); + } + + @Test + @DisplayName("nullチェックNG") + void nullCheckNG() { + Optional result = BookUtil.checkLength(null, 1, 3); + assertEquals("the length must be " + 1 + " or more. but actual is null.", result.get()); + } + } + + @Nested + class checkDatePatternTest { + @Test + @DisplayName("有効な日付形式OK") + void datePatternOK() { + Optional result = BookUtil.checkDatePattern("20180815", DATE_PATTERN); + assertFalse(result.isPresent()); + } + + @Test + @DisplayName("無効な日付形式NG") + void datePatternNG() { + Optional result = BookUtil.checkDatePattern("20181815", DATE_PATTERN); + assertEquals("Invalid Pattern. valid pattern is " + DATE_PATTERN + ".", result.get()); + } + } +} From 5ffc9cc7adf15b2a448677b025ed33da183e5d12 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 1 Sep 2018 17:08:11 +0900 Subject: [PATCH 18/27] =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=83=87=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=81=AE=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/BookUtil.java | 112 +++++++++--------- src/main/java/jp/co/training/Command.java | 52 ++++---- src/main/java/jp/co/training/Config.java | 62 +++++----- src/main/java/jp/co/training/Const.java | 22 ++-- src/main/java/jp/co/training/ExitCommand.java | 22 ++-- 5 files changed, 135 insertions(+), 135 deletions(-) diff --git a/src/main/java/jp/co/training/BookUtil.java b/src/main/java/jp/co/training/BookUtil.java index 371b963..e02d8a9 100644 --- a/src/main/java/jp/co/training/BookUtil.java +++ b/src/main/java/jp/co/training/BookUtil.java @@ -9,66 +9,66 @@ public class BookUtil { - private BookUtil() { - } + private BookUtil() { + } - /** - * 対象文字列が指定された最小文字数と最大文字数の範囲内であるかをチェックします
- * 範囲内である場合はOptionalの中身はnullとなる
- * 範囲外である場合はOptionalの中身はエラーメッセージとなる
- * - * @param target - * @param min - * @param max - * @return - */ - public static Optional checkLength(String target, int min, int max) { - if (target == null) { - return Optional.of("the length must be " + min + " or more. but actual is null."); - } else if (target.length() < min) { - return Optional.of("the length must be " + min + " or more. but actual is " + target.length() + "."); - } else if (target.length() > max) { - return Optional.of("the length must be " + max + " or less. but actual is " + target.length() + "."); - } - return Optional.empty(); - } + /** + * 対象文字列が指定された最小文字数と最大文字数の範囲内であるかをチェックします
+ * 範囲内である場合はOptionalの中身はnullとなる
+ * 範囲外である場合はOptionalの中身はエラーメッセージとなる
+ * + * @param target + * @param min + * @param max + * @return + */ + public static Optional checkLength(String target, int min, int max) { + if (target == null) { + return Optional.of("the length must be " + min + " or more. but actual is null."); + } else if (target.length() < min) { + return Optional.of("the length must be " + min + " or more. but actual is " + target.length() + "."); + } else if (target.length() > max) { + return Optional.of("the length must be " + max + " or less. but actual is " + target.length() + "."); + } + return Optional.empty(); + } - public static Optional checkDatePattern(String target, String pattern) { - DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern); - try { - LocalDate.parse(target, df); - } catch (DateTimeParseException e) { - return Optional.of("Invalid Pattern. valid pattern is " + pattern + "."); - } - return Optional.empty(); - } + public static Optional checkDatePattern(String target, String pattern) { + DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern); + try { + LocalDate.parse(target, df); + } catch (DateTimeParseException e) { + return Optional.of("Invalid Pattern. valid pattern is " + pattern + "."); + } + return Optional.empty(); + } - public static Optional checkNumber(String target) { - if (!isNumber(target)) { - return Optional.of("It is not a numerical format."); - } - return Optional.empty(); - } + public static Optional checkNumber(String target) { + if (!isNumber(target)) { + return Optional.of("It is not a numerical format."); + } + return Optional.empty(); + } - /** - * valueが数値文字列の場合、または空文字の場合はtrueを返す - * - * @param value - * @return - */ - private static boolean isNumber(String value) { - return Pattern.compile("^[0-9]*$").matcher(value).matches(); - } + /** + * valueが数値文字列の場合、または空文字の場合はtrueを返す + * + * @param value + * @return + */ + private static boolean isNumber(String value) { + return Pattern.compile("^[0-9]*$").matcher(value).matches(); + } - public static String generateID(int digit) { - SecureRandom random = new SecureRandom(); - byte bytes[] = new byte[digit / 2]; - random.nextBytes(bytes); - StringBuilder sb = new StringBuilder(); - for (byte d : bytes) { - sb.append(String.format("%02X", d)); - } - return sb.toString(); - } + public static String generateID(int digit) { + SecureRandom random = new SecureRandom(); + byte bytes[] = new byte[digit / 2]; + random.nextBytes(bytes); + StringBuilder sb = new StringBuilder(); + for (byte d : bytes) { + sb.append(String.format("%02X", d)); + } + return sb.toString(); + } } diff --git a/src/main/java/jp/co/training/Command.java b/src/main/java/jp/co/training/Command.java index 7549704..9f92419 100644 --- a/src/main/java/jp/co/training/Command.java +++ b/src/main/java/jp/co/training/Command.java @@ -2,31 +2,31 @@ public abstract class Command { - protected String name; - - protected Command next; - - public Command(String name) { - this.name = name; - } - - public Result execute(String command, String[] argments) { - if (command.equals(name)) { - return executeCommand(command, argments); - } else if (next != null) { - return next.execute(command, argments); - } - // どのコマンドにも合致しなかった場合 - Result result = new Result(); - result.addMessage("Invalid Command."); - return result; - }; - - public Command setNext(Command next) { - this.next = next; - return next; - } - - public abstract Result executeCommand(String command, String[] argments); + protected String name; + + protected Command next; + + public Command(String name) { + this.name = name; + } + + public Result execute(String command, String[] argments) { + if (command.equals(name)) { + return executeCommand(command, argments); + } else if (next != null) { + return next.execute(command, argments); + } + // どのコマンドにも合致しなかった場合 + Result result = new Result(); + result.addMessage("Invalid Command."); + return result; + }; + + public Command setNext(Command next) { + this.next = next; + return next; + } + + public abstract Result executeCommand(String command, String[] argments); } diff --git a/src/main/java/jp/co/training/Config.java b/src/main/java/jp/co/training/Config.java index 1be1384..29d5b2e 100644 --- a/src/main/java/jp/co/training/Config.java +++ b/src/main/java/jp/co/training/Config.java @@ -5,38 +5,38 @@ public class Config { - // 外部ファイルによる設定が可能な定数 - public String prompt; - public String endMessage; - public String delimiter; - public String saveFile; - public String userName; + // 外部ファイルによる設定が可能な定数 + public String prompt; + public String endMessage; + public String delimiter; + public String saveFile; + public String userName; - // 外部ファイルの設定ファイルのキー - private static final String PROMPT_KEY = "prompt"; - private static final String END_MESSAGE_KEY = "end.message"; - private static final String DELIMITER_KEY = "delimiter"; - private static final String SAVE_FILE_KEY = "save.file"; - private static final String USER_NAME_KEY = "user.name"; + // 外部ファイルの設定ファイルのキー + private static final String PROMPT_KEY = "prompt"; + private static final String END_MESSAGE_KEY = "end.message"; + private static final String DELIMITER_KEY = "delimiter"; + private static final String SAVE_FILE_KEY = "save.file"; + private static final String USER_NAME_KEY = "user.name"; - public Config load(String path) { - ResourceBundle rb = null; - try { - rb = ResourceBundle.getBundle(path); - } catch (MissingResourceException e) { - System.out.println("ERROR: cannnot find configfile."); - System.exit(1); - } - if (!rb.containsKey(USER_NAME_KEY)) { - System.out.println("ERROR: you must define registrant in configfile."); - System.exit(1); - } + public Config load(String path) { + ResourceBundle rb = null; + try { + rb = ResourceBundle.getBundle(path); + } catch (MissingResourceException e) { + System.out.println("ERROR: cannnot find configfile."); + System.exit(1); + } + if (!rb.containsKey(USER_NAME_KEY)) { + System.out.println("ERROR: you must define registrant in configfile."); + System.exit(1); + } - userName = rb.getString(USER_NAME_KEY); - prompt = (rb.containsKey(PROMPT_KEY)) ? rb.getString(PROMPT_KEY) : "books>"; - delimiter = (rb.containsKey(DELIMITER_KEY)) ? rb.getString(DELIMITER_KEY) : ","; - saveFile = (rb.containsKey(SAVE_FILE_KEY)) ? rb.getString(DELIMITER_KEY) : "savefile"; - endMessage = (rb.containsKey(END_MESSAGE_KEY)) ? rb.getString(END_MESSAGE_KEY) : "bye."; - return this; - } + userName = rb.getString(USER_NAME_KEY); + prompt = (rb.containsKey(PROMPT_KEY)) ? rb.getString(PROMPT_KEY) : "books>"; + delimiter = (rb.containsKey(DELIMITER_KEY)) ? rb.getString(DELIMITER_KEY) : ","; + saveFile = (rb.containsKey(SAVE_FILE_KEY)) ? rb.getString(DELIMITER_KEY) : "savefile"; + endMessage = (rb.containsKey(END_MESSAGE_KEY)) ? rb.getString(END_MESSAGE_KEY) : "bye."; + return this; + } } diff --git a/src/main/java/jp/co/training/Const.java b/src/main/java/jp/co/training/Const.java index d753374..d684d1d 100644 --- a/src/main/java/jp/co/training/Const.java +++ b/src/main/java/jp/co/training/Const.java @@ -2,16 +2,16 @@ public final class Const { - public static final String CONFIG_FILE = "resource"; - public static final String INSERT = "insert"; - public static final String EXIT = "exit"; - public static final int MAX_ISBN = 13; - public static final int MAX_BOOK_NAME = 50; - public static final int MAX_AUTHOR = 30; - public static final int MAX_PUBLISHER = 30; - public static final int MAX_PRICE = 9; - public static final String DATE_PATTERN = "yyyyMMdd"; - public static final String DATE_TIME_PATTERN = "yyyyMMdd hhmmss.SSS"; - public static final int ID_LENGTH = 16; + public static final String CONFIG_FILE = "resource"; + public static final String INSERT = "insert"; + public static final String EXIT = "exit"; + public static final int MAX_ISBN = 13; + public static final int MAX_BOOK_NAME = 50; + public static final int MAX_AUTHOR = 30; + public static final int MAX_PUBLISHER = 30; + public static final int MAX_PRICE = 9; + public static final String DATE_PATTERN = "yyyyMMdd"; + public static final String DATE_TIME_PATTERN = "yyyyMMdd hhmmss.SSS"; + public static final int ID_LENGTH = 16; } diff --git a/src/main/java/jp/co/training/ExitCommand.java b/src/main/java/jp/co/training/ExitCommand.java index dc961f3..e4dab91 100644 --- a/src/main/java/jp/co/training/ExitCommand.java +++ b/src/main/java/jp/co/training/ExitCommand.java @@ -1,19 +1,19 @@ package jp.co.training; -import static jp.co.training.Main.config; +import static jp.co.training.Main.*; public final class ExitCommand extends Command { - public ExitCommand(String name) { - super(name); - } + public ExitCommand(String name) { + super(name); + } - @Override - public Result executeCommand(String command, String[] argments) { - Result result = new Result(); - result.addMessage(config.endMessage); - result.setExit(true); - return result; - } + @Override + public Result executeCommand(String command, String[] argments) { + Result result = new Result(); + result.addMessage(config.endMessage); + result.setExit(true); + return result; + } } From 27adca067dabf34d039fd61e140b27b3bf598272 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sun, 2 Sep 2018 14:29:59 +0900 Subject: [PATCH 19/27] =?UTF-8?q?BookRecore=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=82=92=E4=BD=9C=E6=88=90=E3=80=82Book=E3=81=AE=E3=83=90?= =?UTF-8?q?=E3=83=AA=E3=82=A8=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92=E4=BF=AE=E6=AD=A3=E3=80=82=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=81=AE=E9=AA=A8=E6=A0=BC=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Book.java | 27 ++++- .../java/jp/co/training/BookException.java | 16 +++ src/main/java/jp/co/training/BookRecord.java | 106 ++++++++++++++++++ .../java/jp/co/training/InsertCommand.java | 76 ++++++------- .../java/jp/co/training/UpdateCommand.java | 51 +++++++++ 5 files changed, 230 insertions(+), 46 deletions(-) create mode 100644 src/main/java/jp/co/training/BookException.java create mode 100644 src/main/java/jp/co/training/BookRecord.java create mode 100644 src/main/java/jp/co/training/UpdateCommand.java diff --git a/src/main/java/jp/co/training/Book.java b/src/main/java/jp/co/training/Book.java index 5d020c6..5f5c30f 100644 --- a/src/main/java/jp/co/training/Book.java +++ b/src/main/java/jp/co/training/Book.java @@ -5,6 +5,8 @@ public class Book { + private static final int NUMBER_OF_ITEMS = 6; + private final String isbn; private final String bookName; private final String author; @@ -71,6 +73,21 @@ private Book(Builder builder) { this.price = builder.price; } + public static Book createBook(String[] argments) throws BookException { + // パラメータ数チェック + if (argments.length != NUMBER_OF_ITEMS) { + throw new BookException("SyntaxError. The number of arguments does not match.", argments.length); + } + + return new Book.Builder() + .isbn(argments[0]) + .bookName(argments[1]) + .author(argments[2]) + .publisher(argments[3]) + .publicationDate(argments[4]) + .price(argments[5]).build(); + } + public static class Builder { private String isbn; @@ -118,8 +135,12 @@ public Book build() { @Override public String toString() { - return String.join(config.delimiter, this.isbn, this.bookName, this.author, this.publisher, - this.publicationDate, this.price); - + return String.join(config.delimiter, + this.isbn, + this.bookName, + this.author, + this.publisher, + this.publicationDate, + this.price); } } diff --git a/src/main/java/jp/co/training/BookException.java b/src/main/java/jp/co/training/BookException.java new file mode 100644 index 0000000..281d906 --- /dev/null +++ b/src/main/java/jp/co/training/BookException.java @@ -0,0 +1,16 @@ +package jp.co.training; + +public class BookException extends Exception { + + private final int actualLength; + + public BookException(String message, int actualLength) { + super(message); + this.actualLength = actualLength; + } + + public int getActualLength() { + return actualLength; + } + +} diff --git a/src/main/java/jp/co/training/BookRecord.java b/src/main/java/jp/co/training/BookRecord.java new file mode 100644 index 0000000..396c15c --- /dev/null +++ b/src/main/java/jp/co/training/BookRecord.java @@ -0,0 +1,106 @@ +package jp.co.training; + +import static jp.co.training.Main.*; + +public class BookRecord { + + private static final int NUMBER_OF_ITEMS = 11; + + private String id; + private Book book; + private String createUser; + private String createdDate; + private String updateUser; + private String updatedDate; + + private BookRecord(Builder builder) { + this.id = builder.id; + this.book = builder.book; + this.createUser = builder.createUser; + this.createdDate = builder.createdDate; + this.updateUser = builder.updateUser; + this.updatedDate = builder.updatedDate; + } + + public static BookRecord decode(String[] argments) throws BookException { + + // パラメータ数チェック + if (argments.length != NUMBER_OF_ITEMS) { + throw new BookException("SyntaxError. The number of arguments does not match.", argments.length); + } + + //BookRecordオブジェクト生成 + return new BookRecord.Builder() + .id(argments[0]) + .book(new Book.Builder() + .isbn(argments[1]) + .bookName(argments[2]) + .author(argments[3]) + .publisher(argments[4]) + .publicationDate(argments[5]) + .price(argments[6]).build()) + .createUser(argments[7]) + .createdDate(argments[8]) + .updateUser(argments[9]) + .updatedDate(argments[10]).build(); + } + + public static String encode(BookRecord bookRecord) { + return bookRecord.toString(); + } + + public static class Builder { + private String id; + private Book book; + private String createUser; + private String createdDate; + private String updateUser; + private String updatedDate; + + public Builder id(String id) { + this.id = id; + return this; + } + + public Builder book(Book book) { + this.book = book; + return this; + } + + public Builder createUser(String createUser) { + this.createUser = createUser; + return this; + } + + public Builder createdDate(String createdDate) { + this.createdDate = createdDate; + return this; + } + + public Builder updateUser(String updateUser) { + this.updateUser = updateUser; + return this; + } + + public Builder updatedDate(String updatedDate) { + this.updatedDate = updatedDate; + return this; + } + + public BookRecord build() { + return new BookRecord(this); + } + + } + + @Override + public String toString() { + return String.join(config.delimiter, + this.id, + this.book.toString(), + this.createUser, + this.createdDate, + this.updateUser, + this.updatedDate); + } +} diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index a9e947d..3051bce 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -3,47 +3,59 @@ import static jp.co.training.Const.*; import static jp.co.training.Main.*; -import java.io.BufferedWriter; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStreamWriter; +import java.io.PrintWriter; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public final class InsertCommand extends Command { - private Result result; - - private Book book; - public InsertCommand(String name) { super(name); } @Override public Result executeCommand(String command, String[] argments) { - result = new Result(); - if (!validate(argments)) { + + //Bookオブジェクト生成 + Book book = null; + try { + book = Book.createBook(argments); + } catch (BookException e) { + Result result = new Result(); + result.addMessage(e.getMessage()); + return result; + } + + // 書籍情報のチェック + Result result = book.validate(); + if (!result.getMesages().isEmpty()) { return result; } - return createBook(); - } - private Result createBook() { + //書籍情報の登録 + return insert(book); + } + private Result insert(Book book) { + Result result = new Result(); String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); - String output = String.join(config.delimiter, - BookUtil.generateID(ID_LENGTH), - book.toString(), - config.userName, today, - config.userName, today); + String output = new BookRecord.Builder() + .id(BookUtil.generateID(ID_LENGTH)) + .book(book) + .createUser(config.userName) + .createdDate(today) + .updateUser(config.userName) + .updatedDate(today) + .build().toString(); - try (BufferedWriter bw = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(config.saveFile, true), StandardCharsets.UTF_8))) { - bw.write(output); - bw.newLine(); + try (PrintWriter writer = new PrintWriter( + Files.newBufferedWriter(Paths.get(config.saveFile), StandardCharsets.UTF_8))) { + writer.println(output); } catch (IOException ex) { result.addMessage(config.saveFile + ": cannot open."); result.setExit(true); @@ -53,26 +65,4 @@ private Result createBook() { return result; } - /* - * 検証の結果OKならtrueを返す。それ以外はfalseを返す - */ - private boolean validate(String[] argments) { - // パラメータ数チェック - if (argments.length != 6) { - result.addMessage("SyntaxError. The number of arguments does not match."); - return false; - } - - // 書籍情報のチェック - book = new Book.Builder() - .isbn(argments[0]) - .bookName(argments[1]) - .author(argments[2]) - .publisher(argments[3]) - .publicationDate(argments[4]) - .price(argments[5]).build(); - result.getMesages().addAll(book.validate().getMesages()); - return result.getMesages().isEmpty(); - } - } diff --git a/src/main/java/jp/co/training/UpdateCommand.java b/src/main/java/jp/co/training/UpdateCommand.java new file mode 100644 index 0000000..aeb0351 --- /dev/null +++ b/src/main/java/jp/co/training/UpdateCommand.java @@ -0,0 +1,51 @@ +package jp.co.training; + +import static jp.co.training.Main.*; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class UpdateCommand extends Command { + + public UpdateCommand(String name) { + super(name); + } + + @Override + public Result executeCommand(String command, String[] argments) { + Result result = new Result(); + String suffix = ".tmp" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss")); + + Path saveFilePath = Paths.get(config.saveFile); + Path tmpFilePath = Paths.get(config.saveFile + suffix); + try (BufferedReader reader = Files.newBufferedReader(saveFilePath); + PrintWriter writer = new PrintWriter(Files.newBufferedWriter(tmpFilePath, StandardCharsets.UTF_8))) { + + String input; + while ((input = reader.readLine()) != null) { + BookRecord record = BookRecord.decode(input.split(config.delimiter)); + //TODO 判定や変換処理 + String output = input; + writer.println(output); + } + Files.delete(saveFilePath); + Files.move(tmpFilePath, saveFilePath); + } catch (IOException e) { + e.printStackTrace(); + } catch (BookException e) { + result.addMessage("File format is invalid."); + result.addMessage(e.getMessage()); + return result; + } + + return result; + } + +} From 1ba19773b45d40289f5b64a4897cdb327d5ffa07 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sun, 2 Sep 2018 14:42:50 +0900 Subject: [PATCH 20/27] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/BookRecord.java | 24 +++++++++++++++ .../java/jp/co/training/UpdateCommand.java | 29 +++++++++++++++---- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/main/java/jp/co/training/BookRecord.java b/src/main/java/jp/co/training/BookRecord.java index 396c15c..1c2d994 100644 --- a/src/main/java/jp/co/training/BookRecord.java +++ b/src/main/java/jp/co/training/BookRecord.java @@ -22,6 +22,30 @@ private BookRecord(Builder builder) { this.updatedDate = builder.updatedDate; } + public String getId() { + return id; + } + + public Book getBook() { + return book; + } + + public String getCreateUser() { + return createUser; + } + + public String getCreatedDate() { + return createdDate; + } + + public String getUpdateUser() { + return updateUser; + } + + public String getUpdatedDate() { + return updatedDate; + } + public static BookRecord decode(String[] argments) throws BookException { // パラメータ数チェック diff --git a/src/main/java/jp/co/training/UpdateCommand.java b/src/main/java/jp/co/training/UpdateCommand.java index aeb0351..d4bcb52 100644 --- a/src/main/java/jp/co/training/UpdateCommand.java +++ b/src/main/java/jp/co/training/UpdateCommand.java @@ -1,5 +1,6 @@ package jp.co.training; +import static jp.co.training.Const.*; import static jp.co.training.Main.*; import java.io.BufferedReader; @@ -23,17 +24,35 @@ public Result executeCommand(String command, String[] argments) { Result result = new Result(); String suffix = ".tmp" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss")); + Book updateBook = null; + try { + updateBook = Book.createBook(argments); + } catch (BookException e1) { + result.addMessage(e1.getMessage()); + return result; + } + Path saveFilePath = Paths.get(config.saveFile); Path tmpFilePath = Paths.get(config.saveFile + suffix); try (BufferedReader reader = Files.newBufferedReader(saveFilePath); PrintWriter writer = new PrintWriter(Files.newBufferedWriter(tmpFilePath, StandardCharsets.UTF_8))) { - String input; - while ((input = reader.readLine()) != null) { - BookRecord record = BookRecord.decode(input.split(config.delimiter)); + String recordLine; + while ((recordLine = reader.readLine()) != null) { + BookRecord record = BookRecord.decode(recordLine.split(config.delimiter)); //TODO 判定や変換処理 - String output = input; - writer.println(output); + if (updateBook.getIsbn().equals(record.getBook().getIsbn())) { + String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); + recordLine = new BookRecord.Builder() + .id(record.getId()) + .book(updateBook) + .createUser(record.getCreateUser()) + .createdDate(record.getCreatedDate()) + .updateUser(config.userName) + .updatedDate(today) + .build().toString(); + } + writer.println(recordLine); } Files.delete(saveFilePath); Files.move(tmpFilePath, saveFilePath); From 4aa7aa9d13c39e7f314221beac5745d386e6370d Mon Sep 17 00:00:00 2001 From: n-coding Date: Tue, 4 Sep 2018 23:07:58 +0900 Subject: [PATCH 21/27] =?UTF-8?q?Command=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AE=E5=BD=B9=E5=89=B2=E3=82=92=E5=88=86=E9=9B=A2=E3=80=82?= =?UTF-8?q?=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=82=92=E5=88=A5?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=8B=E3=82=89=E8=AA=AD?= =?UTF-8?q?=E3=81=BF=E8=BE=BC=E3=82=80=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Book.java | 133 +++++++++++++++--- src/main/java/jp/co/training/BookResult.java | 15 ++ src/main/java/jp/co/training/BookUtil.java | 12 +- src/main/java/jp/co/training/Code.java | 17 +++ src/main/java/jp/co/training/Command.java | 6 +- .../java/jp/co/training/CommandResult.java | 15 ++ src/main/java/jp/co/training/Config.java | 40 ++++-- src/main/java/jp/co/training/Entity.java | 26 ++++ src/main/java/jp/co/training/ExitCommand.java | 4 +- .../java/jp/co/training/InsertCommand.java | 68 +++------ src/main/java/jp/co/training/Main.java | 8 +- src/main/java/jp/co/training/Result.java | 24 ++-- src/main/java/jp/co/training/Status.java | 7 + src/main/java/jp/co/training/dao/BookDao.java | 34 +++++ src/main/resources/messages | 0 src/test/java/jp/co/training/BookTest.java | 2 +- 16 files changed, 307 insertions(+), 104 deletions(-) create mode 100644 src/main/java/jp/co/training/BookResult.java create mode 100644 src/main/java/jp/co/training/Code.java create mode 100644 src/main/java/jp/co/training/CommandResult.java create mode 100644 src/main/java/jp/co/training/Entity.java create mode 100644 src/main/java/jp/co/training/Status.java create mode 100644 src/main/java/jp/co/training/dao/BookDao.java create mode 100644 src/main/resources/messages diff --git a/src/main/java/jp/co/training/Book.java b/src/main/java/jp/co/training/Book.java index 5f5c30f..0a31106 100644 --- a/src/main/java/jp/co/training/Book.java +++ b/src/main/java/jp/co/training/Book.java @@ -3,19 +3,23 @@ import static jp.co.training.Const.*; import static jp.co.training.Main.*; -public class Book { +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; - private static final int NUMBER_OF_ITEMS = 6; +public class Book extends Entity { - private final String isbn; - private final String bookName; - private final String author; - private final String publisher; - private final String publicationDate; - private final String price; + public static final int NUMBER_OF_ITEMS = 6; - public Result validate() { - Result result = new Result(); + private String id; + private String isbn; + private String bookName; + private String author; + private String publisher; + private String publicationDate; + private String price; + + public CommandResult validate() { + CommandResult result = new CommandResult(); // isbn BookUtil.checkLength(isbn, 1, MAX_ISBN).ifPresent(msg -> result.addMessage("ISBM:" + msg)); @@ -65,37 +69,97 @@ public String getPrice() { } private Book(Builder builder) { + this.id = builder.id; this.isbn = builder.isbn; this.bookName = builder.bookName; this.author = builder.author; this.publisher = builder.publisher; this.publicationDate = builder.publicationDate; this.price = builder.price; + this.createUser = builder.createUser; + this.createdDate = builder.createdDate; + this.updateUser = builder.updateUser; + this.updatedDate = builder.updatedDate; } - public static Book createBook(String[] argments) throws BookException { - // パラメータ数チェック - if (argments.length != NUMBER_OF_ITEMS) { - throw new BookException("SyntaxError. The number of arguments does not match.", argments.length); + public static final int NUM_ISBN = 0; + public static final int NUM_BOOK_NAME = 1; + public static final int NUM_AUTHOR = 2; + public static final int NUM_PUBLISHER = 3; + public static final int NUM_PRICE = 4; + public static final int NUM_PUBLICATION_DATE = 5; + + public static BookResult createBook(String[] argments) { + + BookResult result = new BookResult(); + + //各項目のバリデーション + + // isbn + BookUtil.checkLength(argments[NUM_ISBN], 1, MAX_ISBN).ifPresent(msg -> result.addMessage("ISBM:" + msg)); + + // bookName + BookUtil.checkLength(argments[NUM_BOOK_NAME], 1, MAX_BOOK_NAME) + .ifPresent(msg -> result.addMessage("BOOK_NAME:" + msg)); + + // author + BookUtil.checkLength(argments[NUM_AUTHOR], 1, MAX_AUTHOR).ifPresent(msg -> result.addMessage("AUTHOR" + msg)); + + // publisher + BookUtil.checkLength(argments[NUM_PUBLISHER], 1, MAX_PUBLISHER) + .ifPresent(msg -> result.addMessage("PUBLISHER:" + msg)); + + // price + BookUtil.checkLength(argments[NUM_PRICE], 1, MAX_PRICE).ifPresent(msg -> result.addMessage("PRICE:" + msg)); + BookUtil.checkNumber(argments[NUM_PRICE]).ifPresent(msg -> result.addMessage("PRICE:" + msg)); + + // publicationDate + BookUtil.checkDatePattern(argments[NUM_PUBLICATION_DATE], DATE_PATTERN) + .ifPresent(msg -> result.addMessage("PUBLICATION_DATE:" + msg)); + + if (!result.getMessages().isEmpty()) { + return result; } - return new Book.Builder() - .isbn(argments[0]) - .bookName(argments[1]) - .author(argments[2]) - .publisher(argments[3]) - .publicationDate(argments[4]) - .price(argments[5]).build(); + String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); + + Book book = new Book.Builder() + .id(BookUtil.generateID(ID_LENGTH)) + .isbn(argments[NUM_ISBN]) + .bookName(argments[NUM_BOOK_NAME]) + .author(argments[NUM_AUTHOR]) + .publisher(argments[NUM_PUBLISHER]) + .publicationDate(argments[NUM_PUBLICATION_DATE]) + .price(argments[NUM_PRICE]) + .createUser(config.userName) + .createdDate(today) + .updateUser(config.userName) + .updatedDate(today) + .build(); + + result.setBook(book); + result.setStatus(Status.OK); + return result; } public static class Builder { + private String id; private String isbn; private String bookName; private String author; private String publisher; private String publicationDate; private String price; + private String createUser; + private String createdDate; + private String updateUser; + private String updatedDate; + + public Builder id(String id) { + this.id = id; + return this; + } public Builder isbn(String isbn) { this.isbn = isbn; @@ -127,6 +191,26 @@ public Builder price(String price) { return this; } + public Builder createUser(String createUser) { + this.createUser = createUser; + return this; + } + + public Builder createdDate(String createdDate) { + this.createdDate = createdDate; + return this; + } + + public Builder updateUser(String updateUser) { + this.updateUser = updateUser; + return this; + } + + public Builder updatedDate(String updatedDate) { + this.updatedDate = updatedDate; + return this; + } + public Book build() { return new Book(this); } @@ -136,11 +220,16 @@ public Book build() { @Override public String toString() { return String.join(config.delimiter, + this.id, this.isbn, this.bookName, this.author, this.publisher, this.publicationDate, - this.price); + this.price, + this.createUser, + this.createdDate, + this.updateUser, + this.updatedDate); } } diff --git a/src/main/java/jp/co/training/BookResult.java b/src/main/java/jp/co/training/BookResult.java new file mode 100644 index 0000000..eb7c7a7 --- /dev/null +++ b/src/main/java/jp/co/training/BookResult.java @@ -0,0 +1,15 @@ +package jp.co.training; + +public class BookResult extends Result { + + private Book book; + + public Book getBook() { + return book; + } + + public void setBook(Book book) { + this.book = book; + } + +} diff --git a/src/main/java/jp/co/training/BookUtil.java b/src/main/java/jp/co/training/BookUtil.java index e02d8a9..7c8220e 100644 --- a/src/main/java/jp/co/training/BookUtil.java +++ b/src/main/java/jp/co/training/BookUtil.java @@ -1,5 +1,7 @@ package jp.co.training; +import static jp.co.training.Main.*; + import java.security.SecureRandom; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -23,12 +25,12 @@ private BookUtil() { * @return */ public static Optional checkLength(String target, int min, int max) { - if (target == null) { - return Optional.of("the length must be " + min + " or more. but actual is null."); - } else if (target.length() < min) { - return Optional.of("the length must be " + min + " or more. but actual is " + target.length() + "."); + if (target == null || target.length() < min) { + return Optional.of(config.getMessage(Code.MIN_LENGTH_UNDER, String.valueOf(min), + target == null ? "null" : String.valueOf(target.length()))); } else if (target.length() > max) { - return Optional.of("the length must be " + max + " or less. but actual is " + target.length() + "."); + return Optional.of(config.getMessage(Code.MAX_LENGTH_OVER, String.valueOf(max), + String.valueOf(target.length()))); } return Optional.empty(); } diff --git a/src/main/java/jp/co/training/Code.java b/src/main/java/jp/co/training/Code.java new file mode 100644 index 0000000..420ca1b --- /dev/null +++ b/src/main/java/jp/co/training/Code.java @@ -0,0 +1,17 @@ +package jp.co.training; + +public enum Code { + + MAX_LENGTH_OVER("E001"), MIN_LENGTH_UNDER("E002"), INVALID_DATE_PATTERN("E003"), NOT_NUMERICAL("E004"); + + private final String code; + + Code(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + +} diff --git a/src/main/java/jp/co/training/Command.java b/src/main/java/jp/co/training/Command.java index 9f92419..68d4ac9 100644 --- a/src/main/java/jp/co/training/Command.java +++ b/src/main/java/jp/co/training/Command.java @@ -10,14 +10,14 @@ public Command(String name) { this.name = name; } - public Result execute(String command, String[] argments) { + public CommandResult execute(String command, String[] argments) { if (command.equals(name)) { return executeCommand(command, argments); } else if (next != null) { return next.execute(command, argments); } // どのコマンドにも合致しなかった場合 - Result result = new Result(); + CommandResult result = new CommandResult(); result.addMessage("Invalid Command."); return result; }; @@ -27,6 +27,6 @@ public Command setNext(Command next) { return next; } - public abstract Result executeCommand(String command, String[] argments); + public abstract CommandResult executeCommand(String command, String[] argments); } diff --git a/src/main/java/jp/co/training/CommandResult.java b/src/main/java/jp/co/training/CommandResult.java new file mode 100644 index 0000000..0bc4138 --- /dev/null +++ b/src/main/java/jp/co/training/CommandResult.java @@ -0,0 +1,15 @@ +package jp.co.training; + +public class CommandResult extends Result { + + private boolean exit = false; + + public boolean isExit() { + return exit; + } + + public void setExit(boolean exit) { + this.exit = exit; + } + +} diff --git a/src/main/java/jp/co/training/Config.java b/src/main/java/jp/co/training/Config.java index 29d5b2e..716bf42 100644 --- a/src/main/java/jp/co/training/Config.java +++ b/src/main/java/jp/co/training/Config.java @@ -19,24 +19,48 @@ public class Config { private static final String SAVE_FILE_KEY = "save.file"; private static final String USER_NAME_KEY = "user.name"; + ResourceBundle rbMessages; + + //メッセージ定義ファイルのパス + private static final String MESSAGES_RESOURCE = "messages"; + public Config load(String path) { - ResourceBundle rb = null; + ResourceBundle rbProperties = null; try { - rb = ResourceBundle.getBundle(path); + rbProperties = ResourceBundle.getBundle(path); } catch (MissingResourceException e) { System.out.println("ERROR: cannnot find configfile."); System.exit(1); } - if (!rb.containsKey(USER_NAME_KEY)) { + if (!rbProperties.containsKey(USER_NAME_KEY)) { System.out.println("ERROR: you must define registrant in configfile."); System.exit(1); } - userName = rb.getString(USER_NAME_KEY); - prompt = (rb.containsKey(PROMPT_KEY)) ? rb.getString(PROMPT_KEY) : "books>"; - delimiter = (rb.containsKey(DELIMITER_KEY)) ? rb.getString(DELIMITER_KEY) : ","; - saveFile = (rb.containsKey(SAVE_FILE_KEY)) ? rb.getString(DELIMITER_KEY) : "savefile"; - endMessage = (rb.containsKey(END_MESSAGE_KEY)) ? rb.getString(END_MESSAGE_KEY) : "bye."; + try { + rbMessages = ResourceBundle.getBundle(MESSAGES_RESOURCE); + } catch (MissingResourceException e) { + System.out.println("ERROR: cannnot find message file."); + System.exit(1); + } + + userName = rbProperties.getString(USER_NAME_KEY); + prompt = (rbProperties.containsKey(PROMPT_KEY)) ? rbProperties.getString(PROMPT_KEY) : "books>"; + delimiter = (rbProperties.containsKey(DELIMITER_KEY)) ? rbProperties.getString(DELIMITER_KEY) : ","; + saveFile = (rbProperties.containsKey(SAVE_FILE_KEY)) ? rbProperties.getString(DELIMITER_KEY) : "savefile"; + endMessage = (rbProperties.containsKey(END_MESSAGE_KEY)) ? rbProperties.getString(END_MESSAGE_KEY) : "bye."; return this; } + + public String getMessage(Code code, String... params) { + + // メッセージ取得 + String msg = rbMessages.getString(code.getCode()); + + // 可変項目の置換え + for (int i = 0; i < params.length; i++) { + msg.replaceFirst("{" + i + "}", params[i]); + } + return msg; + } } diff --git a/src/main/java/jp/co/training/Entity.java b/src/main/java/jp/co/training/Entity.java new file mode 100644 index 0000000..feaf3c6 --- /dev/null +++ b/src/main/java/jp/co/training/Entity.java @@ -0,0 +1,26 @@ +package jp.co.training; + +public abstract class Entity { + + protected String createUser; + protected String createdDate; + protected String updateUser; + protected String updatedDate; + + public String getCreateUser() { + return createUser; + } + + public String getCreatedDate() { + return createdDate; + } + + public String getUpdateUser() { + return updateUser; + } + + public String getUpdatedDate() { + return updatedDate; + } + +} diff --git a/src/main/java/jp/co/training/ExitCommand.java b/src/main/java/jp/co/training/ExitCommand.java index e4dab91..ee6e658 100644 --- a/src/main/java/jp/co/training/ExitCommand.java +++ b/src/main/java/jp/co/training/ExitCommand.java @@ -9,8 +9,8 @@ public ExitCommand(String name) { } @Override - public Result executeCommand(String command, String[] argments) { - Result result = new Result(); + public CommandResult executeCommand(String command, String[] argments) { + CommandResult result = new CommandResult(); result.addMessage(config.endMessage); result.setExit(true); return result; diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/InsertCommand.java index 3051bce..77b08c8 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/InsertCommand.java @@ -1,15 +1,6 @@ package jp.co.training; -import static jp.co.training.Const.*; -import static jp.co.training.Main.*; - -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; +import jp.co.training.dao.BookDao; public final class InsertCommand extends Command { @@ -18,51 +9,30 @@ public InsertCommand(String name) { } @Override - public Result executeCommand(String command, String[] argments) { + public CommandResult executeCommand(String command, String[] argments) { - //Bookオブジェクト生成 - Book book = null; - try { - book = Book.createBook(argments); - } catch (BookException e) { - Result result = new Result(); - result.addMessage(e.getMessage()); - return result; - } + CommandResult commandResult = new CommandResult(); - // 書籍情報のチェック - Result result = book.validate(); - if (!result.getMesages().isEmpty()) { - return result; + // パラメータ数チェック + if (argments.length != Book.NUMBER_OF_ITEMS) { + commandResult.addMessage("SyntaxError. The number of arguments does not match. expected:" + + Book.NUMBER_OF_ITEMS + " but actual:" + argments.length); + return commandResult; } - //書籍情報の登録 - return insert(book); - } - - private Result insert(Book book) { - Result result = new Result(); - String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); - - String output = new BookRecord.Builder() - .id(BookUtil.generateID(ID_LENGTH)) - .book(book) - .createUser(config.userName) - .createdDate(today) - .updateUser(config.userName) - .updatedDate(today) - .build().toString(); + //Bookオブジェクト生成 + BookResult bookResult = Book.createBook(argments); - try (PrintWriter writer = new PrintWriter( - Files.newBufferedWriter(Paths.get(config.saveFile), StandardCharsets.UTF_8))) { - writer.println(output); - } catch (IOException ex) { - result.addMessage(config.saveFile + ": cannot open."); - result.setExit(true); - return result; + if (bookResult.getStatus() == Status.NG) { + commandResult.addMessages(bookResult.getMessages()); + return commandResult; } - result.addMessage("inserted."); - return result; + + //書籍情報の登録 + Result result = new BookDao().insert(bookResult.getBook()); + commandResult.addMessages(result.getMessages()); + commandResult.setStatus(Status.OK); + return commandResult; } } diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 6d18991..c5ee888 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -26,7 +26,7 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio argments = (String[]) Arrays.stream(argments).map(e -> e.trim()).toArray(String[]::new); // コマンド実行 - Result result = command.execute(inputCommand, argments); + CommandResult result = command.execute(inputCommand, argments); outputMessages(result); if (result != null && result.isExit()) { break; @@ -35,9 +35,9 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio } } - private static void outputMessages(Result result) { - if (result != null && result.getMesages().size() > 0) { - result.getMesages().stream().forEach(message -> { + private static void outputMessages(CommandResult result) { + if (result != null && result.getMessages().size() > 0) { + result.getMessages().stream().forEach(message -> { System.out.println(message); }); } diff --git a/src/main/java/jp/co/training/Result.java b/src/main/java/jp/co/training/Result.java index be2ecff..b317356 100644 --- a/src/main/java/jp/co/training/Result.java +++ b/src/main/java/jp/co/training/Result.java @@ -5,23 +5,27 @@ public class Result { - private boolean exit = false; - private final List mesages = new ArrayList<>(); + private Status status = Status.NG; - public List getMesages() { - return mesages; + private final List messages = new ArrayList<>(); + + public Status getStatus() { + return status; } - public void addMessage(String msg) { - mesages.add(msg); + public void setStatus(Status status) { + this.status = status; } - public boolean isExit() { - return exit; + public List getMessages() { + return messages; } - public void setExit(boolean exit) { - this.exit = exit; + public void addMessage(String message) { + this.messages.add(message); } + public void addMessages(List messages) { + this.messages.addAll(messages); + } } diff --git a/src/main/java/jp/co/training/Status.java b/src/main/java/jp/co/training/Status.java new file mode 100644 index 0000000..a74c738 --- /dev/null +++ b/src/main/java/jp/co/training/Status.java @@ -0,0 +1,7 @@ +package jp.co.training; + +public enum Status { + + OK, NG + +} diff --git a/src/main/java/jp/co/training/dao/BookDao.java b/src/main/java/jp/co/training/dao/BookDao.java new file mode 100644 index 0000000..878660e --- /dev/null +++ b/src/main/java/jp/co/training/dao/BookDao.java @@ -0,0 +1,34 @@ +package jp.co.training.dao; + +import static jp.co.training.Main.*; + +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +import jp.co.training.Book; +import jp.co.training.Result; +import jp.co.training.Status; + +public class BookDao { + + public Result insert(Book book) { + + Result result = new Result(); + + try (PrintWriter writer = new PrintWriter( + Files.newBufferedWriter(Paths.get(config.saveFile), StandardCharsets.UTF_8))) { + writer.println(book.toString()); + } catch (IOException ex) { + result.addMessage(config.saveFile + ": cannot open."); + return result; + } + + result.addMessage("inserted."); + result.setStatus(Status.OK); + return result; + } + +} diff --git a/src/main/resources/messages b/src/main/resources/messages new file mode 100644 index 0000000..e69de29 diff --git a/src/test/java/jp/co/training/BookTest.java b/src/test/java/jp/co/training/BookTest.java index 52a5dda..b39dd9b 100644 --- a/src/test/java/jp/co/training/BookTest.java +++ b/src/test/java/jp/co/training/BookTest.java @@ -22,7 +22,7 @@ void validateIsbnNG() { .publisher("WAVE出版") .publicationDate("20180423") .price("1620").build(); - Result result = book.validate(); + CommandResult result = book.validate(); assertFalse(result.isExit()); assertEquals(1, result.getMesages().size()); assertEquals("ISBM:the length must be " + MAX_ISBN + " or less. but actual is 14.", From d59091d7b885f6e39f2df3ef7887da093b906d5c Mon Sep 17 00:00:00 2001 From: n-coding Date: Tue, 11 Sep 2018 18:39:02 +0900 Subject: [PATCH 22/27] =?UTF-8?q?Result=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AB=E7=9B=B4=E6=8E=A5=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=82=92=E4=BF=9D=E6=8C=81=E3=81=9B=E3=81=9A=E3=80=81?= =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E4=BF=9D=E6=8C=81=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3=E3=80=82?= =?UTF-8?q?=E3=83=91=E3=83=83=E3=82=B1=E3=83=BC=E3=82=B8=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=81=97=E3=81=A6=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92?= =?UTF-8?q?=E6=95=B4=E7=90=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/jp/co/training/BookException.java | 16 --- src/main/java/jp/co/training/BookRecord.java | 130 ------------------ src/main/java/jp/co/training/BookResult.java | 15 -- src/main/java/jp/co/training/Code.java | 7 +- .../java/jp/co/training/CommandResult.java | 15 -- src/main/java/jp/co/training/Config.java | 2 +- src/main/java/jp/co/training/ItemCode.java | 19 +++ src/main/java/jp/co/training/Main.java | 26 ++-- src/main/java/jp/co/training/Result.java | 18 +-- .../java/jp/co/training/UpdateCommand.java | 70 ---------- .../java/jp/co/training/{ => book}/Book.java | 48 ++++--- .../java/jp/co/training/book/BookResult.java | 34 +++++ .../BookValidater.java} | 38 ++--- .../jp/co/training/{ => command}/Command.java | 8 +- .../jp/co/training/command/CommandResult.java | 39 ++++++ .../training/{ => command}/ExitCommand.java | 7 +- .../training/{ => command}/InsertCommand.java | 15 +- .../jp/co/training/command/UpdateCommand.java | 62 +++++++++ src/main/java/jp/co/training/dao/BookDao.java | 6 +- .../java/jp/co/training/util/BookUtil.java | 21 +++ src/test/java/jp/co/training/BookTest.java | 3 + .../java/jp/co/training/BookUtilTest.java | 16 ++- 22 files changed, 276 insertions(+), 339 deletions(-) delete mode 100644 src/main/java/jp/co/training/BookException.java delete mode 100644 src/main/java/jp/co/training/BookRecord.java delete mode 100644 src/main/java/jp/co/training/BookResult.java delete mode 100644 src/main/java/jp/co/training/CommandResult.java create mode 100644 src/main/java/jp/co/training/ItemCode.java delete mode 100644 src/main/java/jp/co/training/UpdateCommand.java rename src/main/java/jp/co/training/{ => book}/Book.java (72%) create mode 100644 src/main/java/jp/co/training/book/BookResult.java rename src/main/java/jp/co/training/{BookUtil.java => book/BookValidater.java} (52%) rename src/main/java/jp/co/training/{ => command}/Command.java (86%) create mode 100644 src/main/java/jp/co/training/command/CommandResult.java rename src/main/java/jp/co/training/{ => command}/ExitCommand.java (68%) rename src/main/java/jp/co/training/{ => command}/InsertCommand.java (68%) create mode 100644 src/main/java/jp/co/training/command/UpdateCommand.java create mode 100644 src/main/java/jp/co/training/util/BookUtil.java diff --git a/src/main/java/jp/co/training/BookException.java b/src/main/java/jp/co/training/BookException.java deleted file mode 100644 index 281d906..0000000 --- a/src/main/java/jp/co/training/BookException.java +++ /dev/null @@ -1,16 +0,0 @@ -package jp.co.training; - -public class BookException extends Exception { - - private final int actualLength; - - public BookException(String message, int actualLength) { - super(message); - this.actualLength = actualLength; - } - - public int getActualLength() { - return actualLength; - } - -} diff --git a/src/main/java/jp/co/training/BookRecord.java b/src/main/java/jp/co/training/BookRecord.java deleted file mode 100644 index 1c2d994..0000000 --- a/src/main/java/jp/co/training/BookRecord.java +++ /dev/null @@ -1,130 +0,0 @@ -package jp.co.training; - -import static jp.co.training.Main.*; - -public class BookRecord { - - private static final int NUMBER_OF_ITEMS = 11; - - private String id; - private Book book; - private String createUser; - private String createdDate; - private String updateUser; - private String updatedDate; - - private BookRecord(Builder builder) { - this.id = builder.id; - this.book = builder.book; - this.createUser = builder.createUser; - this.createdDate = builder.createdDate; - this.updateUser = builder.updateUser; - this.updatedDate = builder.updatedDate; - } - - public String getId() { - return id; - } - - public Book getBook() { - return book; - } - - public String getCreateUser() { - return createUser; - } - - public String getCreatedDate() { - return createdDate; - } - - public String getUpdateUser() { - return updateUser; - } - - public String getUpdatedDate() { - return updatedDate; - } - - public static BookRecord decode(String[] argments) throws BookException { - - // パラメータ数チェック - if (argments.length != NUMBER_OF_ITEMS) { - throw new BookException("SyntaxError. The number of arguments does not match.", argments.length); - } - - //BookRecordオブジェクト生成 - return new BookRecord.Builder() - .id(argments[0]) - .book(new Book.Builder() - .isbn(argments[1]) - .bookName(argments[2]) - .author(argments[3]) - .publisher(argments[4]) - .publicationDate(argments[5]) - .price(argments[6]).build()) - .createUser(argments[7]) - .createdDate(argments[8]) - .updateUser(argments[9]) - .updatedDate(argments[10]).build(); - } - - public static String encode(BookRecord bookRecord) { - return bookRecord.toString(); - } - - public static class Builder { - private String id; - private Book book; - private String createUser; - private String createdDate; - private String updateUser; - private String updatedDate; - - public Builder id(String id) { - this.id = id; - return this; - } - - public Builder book(Book book) { - this.book = book; - return this; - } - - public Builder createUser(String createUser) { - this.createUser = createUser; - return this; - } - - public Builder createdDate(String createdDate) { - this.createdDate = createdDate; - return this; - } - - public Builder updateUser(String updateUser) { - this.updateUser = updateUser; - return this; - } - - public Builder updatedDate(String updatedDate) { - this.updatedDate = updatedDate; - return this; - } - - public BookRecord build() { - return new BookRecord(this); - } - - } - - @Override - public String toString() { - return String.join(config.delimiter, - this.id, - this.book.toString(), - this.createUser, - this.createdDate, - this.updateUser, - this.updatedDate); - } -} diff --git a/src/main/java/jp/co/training/BookResult.java b/src/main/java/jp/co/training/BookResult.java deleted file mode 100644 index eb7c7a7..0000000 --- a/src/main/java/jp/co/training/BookResult.java +++ /dev/null @@ -1,15 +0,0 @@ -package jp.co.training; - -public class BookResult extends Result { - - private Book book; - - public Book getBook() { - return book; - } - - public void setBook(Book book) { - this.book = book; - } - -} diff --git a/src/main/java/jp/co/training/Code.java b/src/main/java/jp/co/training/Code.java index 420ca1b..10e73a3 100644 --- a/src/main/java/jp/co/training/Code.java +++ b/src/main/java/jp/co/training/Code.java @@ -1,8 +1,7 @@ package jp.co.training; public enum Code { - - MAX_LENGTH_OVER("E001"), MIN_LENGTH_UNDER("E002"), INVALID_DATE_PATTERN("E003"), NOT_NUMERICAL("E004"); + WRONG_NUMBER_OF_ARGUMENTS("E001"), INVALID_COMMAND("E002"), IO_ERROR("E003"); private final String code; @@ -10,8 +9,4 @@ public enum Code { this.code = code; } - public String getCode() { - return code; - } - } diff --git a/src/main/java/jp/co/training/CommandResult.java b/src/main/java/jp/co/training/CommandResult.java deleted file mode 100644 index 0bc4138..0000000 --- a/src/main/java/jp/co/training/CommandResult.java +++ /dev/null @@ -1,15 +0,0 @@ -package jp.co.training; - -public class CommandResult extends Result { - - private boolean exit = false; - - public boolean isExit() { - return exit; - } - - public void setExit(boolean exit) { - this.exit = exit; - } - -} diff --git a/src/main/java/jp/co/training/Config.java b/src/main/java/jp/co/training/Config.java index 716bf42..7332daa 100644 --- a/src/main/java/jp/co/training/Config.java +++ b/src/main/java/jp/co/training/Config.java @@ -52,7 +52,7 @@ public Config load(String path) { return this; } - public String getMessage(Code code, String... params) { + public String getMessage(ItemCode code, String... params) { // メッセージ取得 String msg = rbMessages.getString(code.getCode()); diff --git a/src/main/java/jp/co/training/ItemCode.java b/src/main/java/jp/co/training/ItemCode.java new file mode 100644 index 0000000..1a98d13 --- /dev/null +++ b/src/main/java/jp/co/training/ItemCode.java @@ -0,0 +1,19 @@ +package jp.co.training; + +public enum ItemCode { + + MAX_LENGTH_OVER("E101"), MIN_LENGTH_UNDER("E102"), + + INVALID_DATE_PATTERN("E103"), NOT_NUMERICAL("E104"); + + private final String code; + + ItemCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + +} diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index c5ee888..a91b522 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -7,6 +7,11 @@ import java.util.Arrays; import java.util.Scanner; +import jp.co.training.command.Command; +import jp.co.training.command.CommandResult; +import jp.co.training.command.ExitCommand; +import jp.co.training.command.InsertCommand; + public final class Main { public static Config config; @@ -15,8 +20,8 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio config = new Config().load(args.length > 0 && args[0] != null ? args[0] : CONFIG_FILE); - Command command = new InsertCommand(INSERT); - command.setNext(new ExitCommand(EXIT)); + Command command = new ExitCommand(INSERT); + command.setNext(new InsertCommand(EXIT)); try (Scanner scan = new Scanner(System.in)) { while (true) { @@ -27,7 +32,8 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio // コマンド実行 CommandResult result = command.execute(inputCommand, argments); - outputMessages(result); + //viewerクラスでメッセージ出力をする + // outputMessages(result); if (result != null && result.isExit()) { break; } @@ -35,11 +41,11 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio } } - private static void outputMessages(CommandResult result) { - if (result != null && result.getMessages().size() > 0) { - result.getMessages().stream().forEach(message -> { - System.out.println(message); - }); - } - } + // private static void outputMessages(CommandResult result) { + // if (result != null && result.getMessages().size() > 0) { + // result.getMessages().stream().forEach(message -> { + // System.out.println(message); + // }); + // } + // } } diff --git a/src/main/java/jp/co/training/Result.java b/src/main/java/jp/co/training/Result.java index b317356..40ba3e6 100644 --- a/src/main/java/jp/co/training/Result.java +++ b/src/main/java/jp/co/training/Result.java @@ -1,13 +1,12 @@ package jp.co.training; -import java.util.ArrayList; -import java.util.List; +import java.util.EnumSet; public class Result { private Status status = Status.NG; - private final List messages = new ArrayList<>(); + private EnumSet codes = EnumSet.noneOf(Code.class); public Status getStatus() { return status; @@ -17,15 +16,16 @@ public void setStatus(Status status) { this.status = status; } - public List getMessages() { - return messages; + public EnumSet getCodes() { + return codes; } - public void addMessage(String message) { - this.messages.add(message); + public void addCode(Code code) { + codes.add(code); } - public void addMessages(List messages) { - this.messages.addAll(messages); + public void addCodes(EnumSet codes) { + this.codes.addAll(codes); } + } diff --git a/src/main/java/jp/co/training/UpdateCommand.java b/src/main/java/jp/co/training/UpdateCommand.java deleted file mode 100644 index d4bcb52..0000000 --- a/src/main/java/jp/co/training/UpdateCommand.java +++ /dev/null @@ -1,70 +0,0 @@ -package jp.co.training; - -import static jp.co.training.Const.*; -import static jp.co.training.Main.*; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -public class UpdateCommand extends Command { - - public UpdateCommand(String name) { - super(name); - } - - @Override - public Result executeCommand(String command, String[] argments) { - Result result = new Result(); - String suffix = ".tmp" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss")); - - Book updateBook = null; - try { - updateBook = Book.createBook(argments); - } catch (BookException e1) { - result.addMessage(e1.getMessage()); - return result; - } - - Path saveFilePath = Paths.get(config.saveFile); - Path tmpFilePath = Paths.get(config.saveFile + suffix); - try (BufferedReader reader = Files.newBufferedReader(saveFilePath); - PrintWriter writer = new PrintWriter(Files.newBufferedWriter(tmpFilePath, StandardCharsets.UTF_8))) { - - String recordLine; - while ((recordLine = reader.readLine()) != null) { - BookRecord record = BookRecord.decode(recordLine.split(config.delimiter)); - //TODO 判定や変換処理 - if (updateBook.getIsbn().equals(record.getBook().getIsbn())) { - String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); - recordLine = new BookRecord.Builder() - .id(record.getId()) - .book(updateBook) - .createUser(record.getCreateUser()) - .createdDate(record.getCreatedDate()) - .updateUser(config.userName) - .updatedDate(today) - .build().toString(); - } - writer.println(recordLine); - } - Files.delete(saveFilePath); - Files.move(tmpFilePath, saveFilePath); - } catch (IOException e) { - e.printStackTrace(); - } catch (BookException e) { - result.addMessage("File format is invalid."); - result.addMessage(e.getMessage()); - return result; - } - - return result; - } - -} diff --git a/src/main/java/jp/co/training/Book.java b/src/main/java/jp/co/training/book/Book.java similarity index 72% rename from src/main/java/jp/co/training/Book.java rename to src/main/java/jp/co/training/book/Book.java index 0a31106..9b43be6 100644 --- a/src/main/java/jp/co/training/Book.java +++ b/src/main/java/jp/co/training/book/Book.java @@ -1,4 +1,4 @@ -package jp.co.training; +package jp.co.training.book; import static jp.co.training.Const.*; import static jp.co.training.Main.*; @@ -6,6 +6,11 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import jp.co.training.Entity; +import jp.co.training.Status; +import jp.co.training.command.CommandResult; +import jp.co.training.util.BookUtil; + public class Book extends Entity { public static final int NUMBER_OF_ITEMS = 6; @@ -22,24 +27,25 @@ public CommandResult validate() { CommandResult result = new CommandResult(); // isbn - BookUtil.checkLength(isbn, 1, MAX_ISBN).ifPresent(msg -> result.addMessage("ISBM:" + msg)); + BookValidater.checkLength(isbn, 1, MAX_ISBN).ifPresent(code -> result.addItemCode("ISBM", code)); // bookName - BookUtil.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(msg -> result.addMessage("BOOK_NAME:" + msg)); + BookValidater.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(code -> result.addItemCode("BOOK_NAME", code)); // author - BookUtil.checkLength(author, 1, MAX_AUTHOR).ifPresent(msg -> result.addMessage("AUTHOR" + msg)); + BookValidater.checkLength(author, 1, MAX_AUTHOR).ifPresent(code -> result.addItemCode("AUTHOR", code)); // publisher - BookUtil.checkLength(publisher, 1, MAX_PUBLISHER).ifPresent(msg -> result.addMessage("PUBLISHER:" + msg)); + BookValidater.checkLength(publisher, 1, MAX_PUBLISHER) + .ifPresent(code -> result.addItemCode("PUBLISHER", code)); // price - BookUtil.checkLength(price, 1, MAX_PRICE).ifPresent(msg -> result.addMessage("PRICE:" + msg)); - BookUtil.checkNumber(price).ifPresent(msg -> result.addMessage("PRICE:" + msg)); + BookValidater.checkLength(price, 1, MAX_PRICE).ifPresent(code -> result.addItemCode("PRICE", code)); + BookValidater.checkNumber(price).ifPresent(code -> result.addItemCode("PRICE", code)); // publicationDate - BookUtil.checkDatePattern(publicationDate, DATE_PATTERN) - .ifPresent(msg -> result.addMessage("PUBLICATION_DATE:" + msg)); + BookValidater.checkDatePattern(publicationDate, DATE_PATTERN) + .ifPresent(code -> result.addItemCode("PUBLICATION_DATE", code)); return result; } @@ -96,28 +102,30 @@ public static BookResult createBook(String[] argments) { //各項目のバリデーション // isbn - BookUtil.checkLength(argments[NUM_ISBN], 1, MAX_ISBN).ifPresent(msg -> result.addMessage("ISBM:" + msg)); + BookValidater.checkLength(argments[NUM_ISBN], 1, MAX_ISBN).ifPresent(code -> result.addCode("ISBM", code)); // bookName - BookUtil.checkLength(argments[NUM_BOOK_NAME], 1, MAX_BOOK_NAME) - .ifPresent(msg -> result.addMessage("BOOK_NAME:" + msg)); + BookValidater.checkLength(argments[NUM_BOOK_NAME], 1, MAX_BOOK_NAME) + .ifPresent(code -> result.addCode("BOOK_NAME", code)); // author - BookUtil.checkLength(argments[NUM_AUTHOR], 1, MAX_AUTHOR).ifPresent(msg -> result.addMessage("AUTHOR" + msg)); + BookValidater.checkLength(argments[NUM_AUTHOR], 1, MAX_AUTHOR) + .ifPresent(code -> result.addCode("AUTHOR", code)); // publisher - BookUtil.checkLength(argments[NUM_PUBLISHER], 1, MAX_PUBLISHER) - .ifPresent(msg -> result.addMessage("PUBLISHER:" + msg)); + BookValidater.checkLength(argments[NUM_PUBLISHER], 1, MAX_PUBLISHER) + .ifPresent(code -> result.addCode("PUBLISHER", code)); // price - BookUtil.checkLength(argments[NUM_PRICE], 1, MAX_PRICE).ifPresent(msg -> result.addMessage("PRICE:" + msg)); - BookUtil.checkNumber(argments[NUM_PRICE]).ifPresent(msg -> result.addMessage("PRICE:" + msg)); + BookValidater.checkLength(argments[NUM_PRICE], 1, MAX_PRICE) + .ifPresent(code -> result.addCode("PRICE", code)); + BookValidater.checkNumber(argments[NUM_PRICE]).ifPresent(code -> result.addCode("PRICE", code)); // publicationDate - BookUtil.checkDatePattern(argments[NUM_PUBLICATION_DATE], DATE_PATTERN) - .ifPresent(msg -> result.addMessage("PUBLICATION_DATE:" + msg)); + BookValidater.checkDatePattern(argments[NUM_PUBLICATION_DATE], DATE_PATTERN) + .ifPresent(code -> result.addCode("PUBLICATION_DATE", code)); - if (!result.getMessages().isEmpty()) { + if (!result.getItemCodes().isEmpty()) { return result; } diff --git a/src/main/java/jp/co/training/book/BookResult.java b/src/main/java/jp/co/training/book/BookResult.java new file mode 100644 index 0000000..2b1a3e1 --- /dev/null +++ b/src/main/java/jp/co/training/book/BookResult.java @@ -0,0 +1,34 @@ +package jp.co.training.book; + +import java.util.EnumSet; +import java.util.Map; + +import jp.co.training.ItemCode; +import jp.co.training.Result; + +public class BookResult extends Result { + + private Book book; + + private Map> itemCodes; + + public Book getBook() { + return book; + } + + public void setBook(Book book) { + this.book = book; + } + + public Map> getItemCodes() { + return itemCodes; + } + + public void addCode(String key, ItemCode code) { + if (itemCodes.get(key) == null) { + itemCodes.put(key, EnumSet.noneOf(ItemCode.class)); + } + itemCodes.get(key).add(code); + } + +} diff --git a/src/main/java/jp/co/training/BookUtil.java b/src/main/java/jp/co/training/book/BookValidater.java similarity index 52% rename from src/main/java/jp/co/training/BookUtil.java rename to src/main/java/jp/co/training/book/BookValidater.java index 7c8220e..8a7be6f 100644 --- a/src/main/java/jp/co/training/BookUtil.java +++ b/src/main/java/jp/co/training/book/BookValidater.java @@ -1,17 +1,18 @@ -package jp.co.training; +package jp.co.training.book; -import static jp.co.training.Main.*; +import static jp.co.training.ItemCode.*; -import java.security.SecureRandom; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.Optional; import java.util.regex.Pattern; -public class BookUtil { +import jp.co.training.ItemCode; - private BookUtil() { +public class BookValidater { + + private BookValidater() { } /** @@ -24,30 +25,28 @@ private BookUtil() { * @param max * @return */ - public static Optional checkLength(String target, int min, int max) { + public static Optional checkLength(String target, int min, int max) { if (target == null || target.length() < min) { - return Optional.of(config.getMessage(Code.MIN_LENGTH_UNDER, String.valueOf(min), - target == null ? "null" : String.valueOf(target.length()))); + return Optional.of(MIN_LENGTH_UNDER); } else if (target.length() > max) { - return Optional.of(config.getMessage(Code.MAX_LENGTH_OVER, String.valueOf(max), - String.valueOf(target.length()))); + return Optional.of(MAX_LENGTH_OVER); } return Optional.empty(); } - public static Optional checkDatePattern(String target, String pattern) { + public static Optional checkDatePattern(String target, String pattern) { DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern); try { LocalDate.parse(target, df); } catch (DateTimeParseException e) { - return Optional.of("Invalid Pattern. valid pattern is " + pattern + "."); + return Optional.of(INVALID_DATE_PATTERN); } return Optional.empty(); } - public static Optional checkNumber(String target) { + public static Optional checkNumber(String target) { if (!isNumber(target)) { - return Optional.of("It is not a numerical format."); + return Optional.of(NOT_NUMERICAL); } return Optional.empty(); } @@ -62,15 +61,4 @@ private static boolean isNumber(String value) { return Pattern.compile("^[0-9]*$").matcher(value).matches(); } - public static String generateID(int digit) { - SecureRandom random = new SecureRandom(); - byte bytes[] = new byte[digit / 2]; - random.nextBytes(bytes); - StringBuilder sb = new StringBuilder(); - for (byte d : bytes) { - sb.append(String.format("%02X", d)); - } - return sb.toString(); - } - } diff --git a/src/main/java/jp/co/training/Command.java b/src/main/java/jp/co/training/command/Command.java similarity index 86% rename from src/main/java/jp/co/training/Command.java rename to src/main/java/jp/co/training/command/Command.java index 68d4ac9..1470c21 100644 --- a/src/main/java/jp/co/training/Command.java +++ b/src/main/java/jp/co/training/command/Command.java @@ -1,4 +1,6 @@ -package jp.co.training; +package jp.co.training.command; + +import jp.co.training.Code; public abstract class Command { @@ -18,9 +20,9 @@ public CommandResult execute(String command, String[] argments) { } // どのコマンドにも合致しなかった場合 CommandResult result = new CommandResult(); - result.addMessage("Invalid Command."); + result.addCode(Code.INVALID_COMMAND); return result; - }; + } public Command setNext(Command next) { this.next = next; diff --git a/src/main/java/jp/co/training/command/CommandResult.java b/src/main/java/jp/co/training/command/CommandResult.java new file mode 100644 index 0000000..8ae4c64 --- /dev/null +++ b/src/main/java/jp/co/training/command/CommandResult.java @@ -0,0 +1,39 @@ +package jp.co.training.command; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +import jp.co.training.ItemCode; +import jp.co.training.Result; + +public class CommandResult extends Result { + + private boolean exit = false; + + private Map> itemCodes = new HashMap<>(); + + public boolean isExit() { + return exit; + } + + public void setExit(boolean exit) { + this.exit = exit; + } + + public void addItemCode(String key, ItemCode itemCode) { + if (itemCodes.get(key) == null) { + itemCodes.put(key, EnumSet.noneOf(ItemCode.class)); + } + itemCodes.get(key).add(itemCode); + } + + public void addItemCodes(Map> itemCodes) { + for (Map.Entry> e : itemCodes.entrySet()) { + for (ItemCode code : e.getValue()) { + addItemCode(e.getKey(), code); + } + } + } + +} diff --git a/src/main/java/jp/co/training/ExitCommand.java b/src/main/java/jp/co/training/command/ExitCommand.java similarity index 68% rename from src/main/java/jp/co/training/ExitCommand.java rename to src/main/java/jp/co/training/command/ExitCommand.java index ee6e658..de50377 100644 --- a/src/main/java/jp/co/training/ExitCommand.java +++ b/src/main/java/jp/co/training/command/ExitCommand.java @@ -1,6 +1,4 @@ -package jp.co.training; - -import static jp.co.training.Main.*; +package jp.co.training.command; public final class ExitCommand extends Command { @@ -11,7 +9,8 @@ public ExitCommand(String name) { @Override public CommandResult executeCommand(String command, String[] argments) { CommandResult result = new CommandResult(); - result.addMessage(config.endMessage); + //TODO 以下の処理はviewerクラスに任せる + // result.addMessage(config.endMessage); result.setExit(true); return result; } diff --git a/src/main/java/jp/co/training/InsertCommand.java b/src/main/java/jp/co/training/command/InsertCommand.java similarity index 68% rename from src/main/java/jp/co/training/InsertCommand.java rename to src/main/java/jp/co/training/command/InsertCommand.java index 77b08c8..2584b58 100644 --- a/src/main/java/jp/co/training/InsertCommand.java +++ b/src/main/java/jp/co/training/command/InsertCommand.java @@ -1,5 +1,11 @@ -package jp.co.training; +package jp.co.training.command; +import static jp.co.training.Code.*; + +import jp.co.training.Result; +import jp.co.training.Status; +import jp.co.training.book.Book; +import jp.co.training.book.BookResult; import jp.co.training.dao.BookDao; public final class InsertCommand extends Command { @@ -15,8 +21,7 @@ public CommandResult executeCommand(String command, String[] argments) { // パラメータ数チェック if (argments.length != Book.NUMBER_OF_ITEMS) { - commandResult.addMessage("SyntaxError. The number of arguments does not match. expected:" - + Book.NUMBER_OF_ITEMS + " but actual:" + argments.length); + commandResult.addCode(WRONG_NUMBER_OF_ARGUMENTS); return commandResult; } @@ -24,13 +29,13 @@ public CommandResult executeCommand(String command, String[] argments) { BookResult bookResult = Book.createBook(argments); if (bookResult.getStatus() == Status.NG) { - commandResult.addMessages(bookResult.getMessages()); + commandResult.addItemCodes(bookResult.getItemCodes()); return commandResult; } //書籍情報の登録 Result result = new BookDao().insert(bookResult.getBook()); - commandResult.addMessages(result.getMessages()); + commandResult.addCodes(result.getCodes()); commandResult.setStatus(Status.OK); return commandResult; } diff --git a/src/main/java/jp/co/training/command/UpdateCommand.java b/src/main/java/jp/co/training/command/UpdateCommand.java new file mode 100644 index 0000000..e39d739 --- /dev/null +++ b/src/main/java/jp/co/training/command/UpdateCommand.java @@ -0,0 +1,62 @@ +package jp.co.training.command; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import jp.co.training.book.Book; + +public class UpdateCommand extends Command { + + public UpdateCommand(String name) { + super(name); + } + + @Override + public CommandResult executeCommand(String command, String[] argments) { + CommandResult result = new CommandResult(); + String suffix = ".tmp" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss")); + + Book updateBook = null; + // try { + // updateBook = Book.createBook(argments); + // } catch (BookException e1) { + // result.addMessage(e1.getMessage()); + // return result; + // } + // + // Path saveFilePath = Paths.get(config.saveFile); + // Path tmpFilePath = Paths.get(config.saveFile + suffix); + // try (BufferedReader reader = Files.newBufferedReader(saveFilePath); + // PrintWriter writer = new PrintWriter(Files.newBufferedWriter(tmpFilePath, StandardCharsets.UTF_8))) { + // + // String recordLine; + // while ((recordLine = reader.readLine()) != null) { + // BookRecord record = BookRecord.decode(recordLine.split(config.delimiter)); + // //TODO 判定や変換処理 + // if (updateBook.getIsbn().equals(record.getBook().getIsbn())) { + // String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); + // recordLine = new BookRecord.Builder() + // .id(record.getId()) + // .book(updateBook) + // .createUser(record.getCreateUser()) + // .createdDate(record.getCreatedDate()) + // .updateUser(config.userName) + // .updatedDate(today) + // .build().toString(); + // } + // writer.println(recordLine); + // } + // Files.delete(saveFilePath); + // Files.move(tmpFilePath, saveFilePath); + // } catch (IOException e) { + // e.printStackTrace(); + // } catch (BookException e) { + // result.addMessage("File format is invalid."); + // result.addMessage(e.getMessage()); + // return result; + // } + + return result; + } + +} diff --git a/src/main/java/jp/co/training/dao/BookDao.java b/src/main/java/jp/co/training/dao/BookDao.java index 878660e..70c3960 100644 --- a/src/main/java/jp/co/training/dao/BookDao.java +++ b/src/main/java/jp/co/training/dao/BookDao.java @@ -8,9 +8,10 @@ import java.nio.file.Files; import java.nio.file.Paths; -import jp.co.training.Book; import jp.co.training.Result; import jp.co.training.Status; +import jp.co.training.book.Book; +import jp.co.training.Code; public class BookDao { @@ -22,11 +23,10 @@ public Result insert(Book book) { Files.newBufferedWriter(Paths.get(config.saveFile), StandardCharsets.UTF_8))) { writer.println(book.toString()); } catch (IOException ex) { - result.addMessage(config.saveFile + ": cannot open."); + result.addCode(Code.IO_ERROR); return result; } - result.addMessage("inserted."); result.setStatus(Status.OK); return result; } diff --git a/src/main/java/jp/co/training/util/BookUtil.java b/src/main/java/jp/co/training/util/BookUtil.java new file mode 100644 index 0000000..d6e64fb --- /dev/null +++ b/src/main/java/jp/co/training/util/BookUtil.java @@ -0,0 +1,21 @@ +package jp.co.training.util; + +import java.security.SecureRandom; + +public class BookUtil { + + private BookUtil() { + } + + public static String generateID(int digit) { + SecureRandom random = new SecureRandom(); + byte bytes[] = new byte[digit / 2]; + random.nextBytes(bytes); + StringBuilder sb = new StringBuilder(); + for (byte d : bytes) { + sb.append(String.format("%02X", d)); + } + return sb.toString(); + } + +} diff --git a/src/test/java/jp/co/training/BookTest.java b/src/test/java/jp/co/training/BookTest.java index b39dd9b..3cfe942 100644 --- a/src/test/java/jp/co/training/BookTest.java +++ b/src/test/java/jp/co/training/BookTest.java @@ -7,6 +7,9 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import jp.co.training.book.Book; +import jp.co.training.command.CommandResult; + class BookTest { @Nested diff --git a/src/test/java/jp/co/training/BookUtilTest.java b/src/test/java/jp/co/training/BookUtilTest.java index 9dd7e47..f0dc51b 100644 --- a/src/test/java/jp/co/training/BookUtilTest.java +++ b/src/test/java/jp/co/training/BookUtilTest.java @@ -9,6 +9,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import jp.co.training.book.BookValidater; + class BookUtilTest { @Nested @@ -16,35 +18,35 @@ class CheckLengthTest { @Test @DisplayName("最大文字超過チェックOK") void maxOverOK() { - Optional result = BookUtil.checkLength("あいう", 1, 3); + Optional result = BookValidater.checkLength("あいう", 1, 3); assertFalse(result.isPresent()); } @Test @DisplayName("最小文字超過チェックOK") void minUnderOK() { - Optional result = BookUtil.checkLength("あ", 1, 3); + Optional result = BookValidater.checkLength("あ", 1, 3); assertFalse(result.isPresent()); } @Test @DisplayName("最大文字超過チェックNG") void maxOverNG() { - Optional result = BookUtil.checkLength("あいうえ", 1, 3); + Optional result = BookValidater.checkLength("あいうえ", 1, 3); assertEquals("the length must be " + 3 + " or less. but actual is " + 4 + ".", result.get()); } @Test @DisplayName("最小文字超過チェックNG") void minUnderNG() { - Optional result = BookUtil.checkLength("", 1, 3); + Optional result = BookValidater.checkLength("", 1, 3); assertEquals("the length must be " + 1 + " or more. but actual is " + 0 + ".", result.get()); } @Test @DisplayName("nullチェックNG") void nullCheckNG() { - Optional result = BookUtil.checkLength(null, 1, 3); + Optional result = BookValidater.checkLength(null, 1, 3); assertEquals("the length must be " + 1 + " or more. but actual is null.", result.get()); } } @@ -54,14 +56,14 @@ class checkDatePatternTest { @Test @DisplayName("有効な日付形式OK") void datePatternOK() { - Optional result = BookUtil.checkDatePattern("20180815", DATE_PATTERN); + Optional result = BookValidater.checkDatePattern("20180815", DATE_PATTERN); assertFalse(result.isPresent()); } @Test @DisplayName("無効な日付形式NG") void datePatternNG() { - Optional result = BookUtil.checkDatePattern("20181815", DATE_PATTERN); + Optional result = BookValidater.checkDatePattern("20181815", DATE_PATTERN); assertEquals("Invalid Pattern. valid pattern is " + DATE_PATTERN + ".", result.get()); } } From 4c83d908a032befabe901af00c94dca67aeb4b5b Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 15 Sep 2018 14:25:20 +0900 Subject: [PATCH 23/27] =?UTF-8?q?Result=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=A8Code=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92=E6=95=B4?= =?UTF-8?q?=E7=90=86=E3=80=82Viewer=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92?= =?UTF-8?q?=E4=BD=9C=E6=88=90=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Code.java | 12 ---- src/main/java/jp/co/training/Config.java | 2 + src/main/java/jp/co/training/Const.java | 2 + src/main/java/jp/co/training/Main.java | 24 ++++--- src/main/java/jp/co/training/Result.java | 31 --------- src/main/java/jp/co/training/Viewer.java | 68 +++++++++++++++++++ src/main/java/jp/co/training/book/Book.java | 49 +++---------- .../java/jp/co/training/book/BookResult.java | 12 ++-- .../jp/co/training/{ => book}/ItemCode.java | 11 ++- .../java/jp/co/training/command/Command.java | 6 +- .../jp/co/training/command/CommandCode.java | 19 ++++++ .../jp/co/training/command/CommandResult.java | 44 ++++++++++-- .../jp/co/training/command/ExitCommand.java | 4 +- .../jp/co/training/command/InsertCommand.java | 11 +-- .../jp/co/training/command/UpdateCommand.java | 4 +- src/main/java/jp/co/training/common/Code.java | 6 ++ .../jp/co/training/{ => common}/Entity.java | 4 +- .../java/jp/co/training/common/Result.java | 15 ++++ .../jp/co/training/{ => common}/Status.java | 2 +- src/main/java/jp/co/training/dao/BookDao.java | 10 ++- src/main/java/jp/co/training/dao/DaoCode.java | 20 ++++++ .../java/jp/co/training/dao/DaoResult.java | 25 +++++++ .../ItemValidater.java} | 10 +-- .../java/jp/co/training/BookUtilTest.java | 16 ++--- 24 files changed, 270 insertions(+), 137 deletions(-) delete mode 100644 src/main/java/jp/co/training/Code.java delete mode 100644 src/main/java/jp/co/training/Result.java create mode 100644 src/main/java/jp/co/training/Viewer.java rename src/main/java/jp/co/training/{ => book}/ItemCode.java (63%) create mode 100644 src/main/java/jp/co/training/command/CommandCode.java create mode 100644 src/main/java/jp/co/training/common/Code.java rename src/main/java/jp/co/training/{ => common}/Entity.java (86%) create mode 100644 src/main/java/jp/co/training/common/Result.java rename src/main/java/jp/co/training/{ => common}/Status.java (54%) create mode 100644 src/main/java/jp/co/training/dao/DaoCode.java create mode 100644 src/main/java/jp/co/training/dao/DaoResult.java rename src/main/java/jp/co/training/{book/BookValidater.java => validate/ItemValidater.java} (90%) diff --git a/src/main/java/jp/co/training/Code.java b/src/main/java/jp/co/training/Code.java deleted file mode 100644 index 10e73a3..0000000 --- a/src/main/java/jp/co/training/Code.java +++ /dev/null @@ -1,12 +0,0 @@ -package jp.co.training; - -public enum Code { - WRONG_NUMBER_OF_ARGUMENTS("E001"), INVALID_COMMAND("E002"), IO_ERROR("E003"); - - private final String code; - - Code(String code) { - this.code = code; - } - -} diff --git a/src/main/java/jp/co/training/Config.java b/src/main/java/jp/co/training/Config.java index 7332daa..730430f 100644 --- a/src/main/java/jp/co/training/Config.java +++ b/src/main/java/jp/co/training/Config.java @@ -3,6 +3,8 @@ import java.util.MissingResourceException; import java.util.ResourceBundle; +import jp.co.training.book.ItemCode; + public class Config { // 外部ファイルによる設定が可能な定数 diff --git a/src/main/java/jp/co/training/Const.java b/src/main/java/jp/co/training/Const.java index d684d1d..3d06c53 100644 --- a/src/main/java/jp/co/training/Const.java +++ b/src/main/java/jp/co/training/Const.java @@ -4,7 +4,9 @@ public final class Const { public static final String CONFIG_FILE = "resource"; public static final String INSERT = "insert"; + public static final String UPDATE = "update"; public static final String EXIT = "exit"; + public static final String INVALID = "invalid"; public static final int MAX_ISBN = 13; public static final int MAX_BOOK_NAME = 50; public static final int MAX_AUTHOR = 30; diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index a91b522..53f6d4d 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -11,6 +11,7 @@ import jp.co.training.command.CommandResult; import jp.co.training.command.ExitCommand; import jp.co.training.command.InsertCommand; +import jp.co.training.common.Status; public final class Main { @@ -19,19 +20,28 @@ public final class Main { public static void main(String... args) throws FileNotFoundException, IOException { config = new Config().load(args.length > 0 && args[0] != null ? args[0] : CONFIG_FILE); + Viewer viewer = new Viewer(); - Command command = new ExitCommand(INSERT); - command.setNext(new InsertCommand(EXIT)); + Command command = new ExitCommand(EXIT); + command.setNext(new InsertCommand(INSERT)); try (Scanner scan = new Scanner(System.in)) { while (true) { - System.out.print(config.prompt); + viewer.promptMessages(); String inputCommand = scan.next().toLowerCase(); String[] argments = scan.nextLine().split(config.delimiter); argments = (String[]) Arrays.stream(argments).map(e -> e.trim()).toArray(String[]::new); // コマンド実行 CommandResult result = command.execute(inputCommand, argments); + + if (result.getStatus() == Status.OK) { + viewer.standardMessages(result.getCommandName()); + } else { + viewer.errorMessages(result.getCodes()); + viewer.errorMessages(result.getItemCodes()); + } + //viewerクラスでメッセージ出力をする // outputMessages(result); if (result != null && result.isExit()) { @@ -39,13 +49,7 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio } } } + viewer.endMessages(); } - // private static void outputMessages(CommandResult result) { - // if (result != null && result.getMessages().size() > 0) { - // result.getMessages().stream().forEach(message -> { - // System.out.println(message); - // }); - // } - // } } diff --git a/src/main/java/jp/co/training/Result.java b/src/main/java/jp/co/training/Result.java deleted file mode 100644 index 40ba3e6..0000000 --- a/src/main/java/jp/co/training/Result.java +++ /dev/null @@ -1,31 +0,0 @@ -package jp.co.training; - -import java.util.EnumSet; - -public class Result { - - private Status status = Status.NG; - - private EnumSet codes = EnumSet.noneOf(Code.class); - - public Status getStatus() { - return status; - } - - public void setStatus(Status status) { - this.status = status; - } - - public EnumSet getCodes() { - return codes; - } - - public void addCode(Code code) { - codes.add(code); - } - - public void addCodes(EnumSet codes) { - this.codes.addAll(codes); - } - -} diff --git a/src/main/java/jp/co/training/Viewer.java b/src/main/java/jp/co/training/Viewer.java new file mode 100644 index 0000000..6b3b5b4 --- /dev/null +++ b/src/main/java/jp/co/training/Viewer.java @@ -0,0 +1,68 @@ +package jp.co.training; + +import static jp.co.training.Const.*; +import static jp.co.training.Main.*; + +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.Set; + +import jp.co.training.book.ItemCode; +import jp.co.training.common.Code; + +public class Viewer { + + private ResourceBundle rbMessages; + + //メッセージ定義ファイルのパス + private static final String MESSAGES_RESOURCE = "messages"; + + public Viewer() { + try { + rbMessages = ResourceBundle.getBundle(MESSAGES_RESOURCE); + } catch (MissingResourceException e) { + System.out.println("ERROR: cannnot find message file."); + System.exit(1); + } + } + + public void promptMessages() { + System.out.print(config.prompt); + } + + public void endMessages() { + System.out.print(config.endMessage); + } + + public void standardMessages(String commandName) { + + switch (commandName) { + + case INSERT: + System.out.println("inserted"); + break; + + default: + } + + } + + public void errorMessages(Map> itemCodes) { + + for (Map.Entry> entry : itemCodes.entrySet()) { + System.out.println(entry.getKey()); + for (ItemCode code : entry.getValue()) { + System.out.println(code); + } + } + + } + + public void errorMessages(Set codes) { + for (Code code : codes) { + System.out.println(code); + } + } + +} diff --git a/src/main/java/jp/co/training/book/Book.java b/src/main/java/jp/co/training/book/Book.java index 9b43be6..64c7505 100644 --- a/src/main/java/jp/co/training/book/Book.java +++ b/src/main/java/jp/co/training/book/Book.java @@ -6,10 +6,10 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import jp.co.training.Entity; -import jp.co.training.Status; -import jp.co.training.command.CommandResult; +import jp.co.training.common.Entity; +import jp.co.training.common.Status; import jp.co.training.util.BookUtil; +import jp.co.training.validate.ItemValidater; public class Book extends Entity { @@ -23,33 +23,6 @@ public class Book extends Entity { private String publicationDate; private String price; - public CommandResult validate() { - CommandResult result = new CommandResult(); - - // isbn - BookValidater.checkLength(isbn, 1, MAX_ISBN).ifPresent(code -> result.addItemCode("ISBM", code)); - - // bookName - BookValidater.checkLength(bookName, 1, MAX_BOOK_NAME).ifPresent(code -> result.addItemCode("BOOK_NAME", code)); - - // author - BookValidater.checkLength(author, 1, MAX_AUTHOR).ifPresent(code -> result.addItemCode("AUTHOR", code)); - - // publisher - BookValidater.checkLength(publisher, 1, MAX_PUBLISHER) - .ifPresent(code -> result.addItemCode("PUBLISHER", code)); - - // price - BookValidater.checkLength(price, 1, MAX_PRICE).ifPresent(code -> result.addItemCode("PRICE", code)); - BookValidater.checkNumber(price).ifPresent(code -> result.addItemCode("PRICE", code)); - - // publicationDate - BookValidater.checkDatePattern(publicationDate, DATE_PATTERN) - .ifPresent(code -> result.addItemCode("PUBLICATION_DATE", code)); - - return result; - } - public String getIsbn() { return isbn; } @@ -102,27 +75,27 @@ public static BookResult createBook(String[] argments) { //各項目のバリデーション // isbn - BookValidater.checkLength(argments[NUM_ISBN], 1, MAX_ISBN).ifPresent(code -> result.addCode("ISBM", code)); + ItemValidater.checkLength(argments[NUM_ISBN], 1, MAX_ISBN).ifPresent(code -> result.addCode("ISBM", code)); // bookName - BookValidater.checkLength(argments[NUM_BOOK_NAME], 1, MAX_BOOK_NAME) + ItemValidater.checkLength(argments[NUM_BOOK_NAME], 1, MAX_BOOK_NAME) .ifPresent(code -> result.addCode("BOOK_NAME", code)); // author - BookValidater.checkLength(argments[NUM_AUTHOR], 1, MAX_AUTHOR) + ItemValidater.checkLength(argments[NUM_AUTHOR], 1, MAX_AUTHOR) .ifPresent(code -> result.addCode("AUTHOR", code)); // publisher - BookValidater.checkLength(argments[NUM_PUBLISHER], 1, MAX_PUBLISHER) + ItemValidater.checkLength(argments[NUM_PUBLISHER], 1, MAX_PUBLISHER) .ifPresent(code -> result.addCode("PUBLISHER", code)); // price - BookValidater.checkLength(argments[NUM_PRICE], 1, MAX_PRICE) + ItemValidater.checkLength(argments[NUM_PRICE], 1, MAX_PRICE) .ifPresent(code -> result.addCode("PRICE", code)); - BookValidater.checkNumber(argments[NUM_PRICE]).ifPresent(code -> result.addCode("PRICE", code)); + ItemValidater.checkNumber(argments[NUM_PRICE]).ifPresent(code -> result.addCode("PRICE", code)); // publicationDate - BookValidater.checkDatePattern(argments[NUM_PUBLICATION_DATE], DATE_PATTERN) + ItemValidater.checkDatePattern(argments[NUM_PUBLICATION_DATE], DATE_PATTERN) .ifPresent(code -> result.addCode("PUBLICATION_DATE", code)); if (!result.getItemCodes().isEmpty()) { @@ -226,7 +199,7 @@ public Book build() { } @Override - public String toString() { + public String encode() { return String.join(config.delimiter, this.id, this.isbn, diff --git a/src/main/java/jp/co/training/book/BookResult.java b/src/main/java/jp/co/training/book/BookResult.java index 2b1a3e1..11a097d 100644 --- a/src/main/java/jp/co/training/book/BookResult.java +++ b/src/main/java/jp/co/training/book/BookResult.java @@ -1,16 +1,16 @@ package jp.co.training.book; -import java.util.EnumSet; +import java.util.HashSet; import java.util.Map; +import java.util.Set; -import jp.co.training.ItemCode; -import jp.co.training.Result; +import jp.co.training.common.Result; public class BookResult extends Result { private Book book; - private Map> itemCodes; + private Map> itemCodes; public Book getBook() { return book; @@ -20,13 +20,13 @@ public void setBook(Book book) { this.book = book; } - public Map> getItemCodes() { + public Map> getItemCodes() { return itemCodes; } public void addCode(String key, ItemCode code) { if (itemCodes.get(key) == null) { - itemCodes.put(key, EnumSet.noneOf(ItemCode.class)); + itemCodes.put(key, new HashSet<>()); } itemCodes.get(key).add(code); } diff --git a/src/main/java/jp/co/training/ItemCode.java b/src/main/java/jp/co/training/book/ItemCode.java similarity index 63% rename from src/main/java/jp/co/training/ItemCode.java rename to src/main/java/jp/co/training/book/ItemCode.java index 1a98d13..46358cd 100644 --- a/src/main/java/jp/co/training/ItemCode.java +++ b/src/main/java/jp/co/training/book/ItemCode.java @@ -1,6 +1,12 @@ -package jp.co.training; +package jp.co.training.book; -public enum ItemCode { +import jp.co.training.common.Code; + +/** + * 項目ごとのコード + * + */ +public enum ItemCode implements Code { MAX_LENGTH_OVER("E101"), MIN_LENGTH_UNDER("E102"), @@ -12,6 +18,7 @@ public enum ItemCode { this.code = code; } + @Override public String getCode() { return code; } diff --git a/src/main/java/jp/co/training/command/Command.java b/src/main/java/jp/co/training/command/Command.java index 1470c21..09a7bde 100644 --- a/src/main/java/jp/co/training/command/Command.java +++ b/src/main/java/jp/co/training/command/Command.java @@ -1,6 +1,6 @@ package jp.co.training.command; -import jp.co.training.Code; +import static jp.co.training.Const.*; public abstract class Command { @@ -19,8 +19,8 @@ public CommandResult execute(String command, String[] argments) { return next.execute(command, argments); } // どのコマンドにも合致しなかった場合 - CommandResult result = new CommandResult(); - result.addCode(Code.INVALID_COMMAND); + CommandResult result = new CommandResult(INVALID); + result.addCode(CommandCode.INVALID_COMMAND); return result; } diff --git a/src/main/java/jp/co/training/command/CommandCode.java b/src/main/java/jp/co/training/command/CommandCode.java new file mode 100644 index 0000000..5ebfa77 --- /dev/null +++ b/src/main/java/jp/co/training/command/CommandCode.java @@ -0,0 +1,19 @@ +package jp.co.training.command; + +import jp.co.training.common.Code; + +public enum CommandCode implements Code { + + WRONG_NUMBER_OF_ARGUMENTS("E001"), INVALID_COMMAND("E002"); + + private final String code; + + CommandCode(String code) { + this.code = code; + } + + @Override + public String getCode() { + return this.code; + } +} diff --git a/src/main/java/jp/co/training/command/CommandResult.java b/src/main/java/jp/co/training/command/CommandResult.java index 8ae4c64..27e9853 100644 --- a/src/main/java/jp/co/training/command/CommandResult.java +++ b/src/main/java/jp/co/training/command/CommandResult.java @@ -1,17 +1,27 @@ package jp.co.training.command; -import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; -import jp.co.training.ItemCode; -import jp.co.training.Result; +import jp.co.training.book.ItemCode; +import jp.co.training.common.Code; +import jp.co.training.common.Result; public class CommandResult extends Result { private boolean exit = false; - private Map> itemCodes = new HashMap<>(); + private final String commandName; + + private Map> itemCodes = new HashMap<>(); + + private Set codes = new HashSet<>(); + + public CommandResult(String commandName) { + this.commandName = commandName; + } public boolean isExit() { return exit; @@ -21,19 +31,39 @@ public void setExit(boolean exit) { this.exit = exit; } + public String getCommandName() { + return commandName; + } + + public Map> getItemCodes() { + return itemCodes; + } + public void addItemCode(String key, ItemCode itemCode) { if (itemCodes.get(key) == null) { - itemCodes.put(key, EnumSet.noneOf(ItemCode.class)); + itemCodes.put(key, new HashSet<>()); } itemCodes.get(key).add(itemCode); } - public void addItemCodes(Map> itemCodes) { - for (Map.Entry> e : itemCodes.entrySet()) { + public void addItemCodes(Map> itemCodes) { + for (Map.Entry> e : itemCodes.entrySet()) { for (ItemCode code : e.getValue()) { addItemCode(e.getKey(), code); } } } + public Set getCodes() { + return codes; + } + + public void addCode(Code code) { + codes.add(code); + } + + public void addCodes(Set codes) { + this.codes.addAll(codes); + } + } diff --git a/src/main/java/jp/co/training/command/ExitCommand.java b/src/main/java/jp/co/training/command/ExitCommand.java index de50377..02c6b53 100644 --- a/src/main/java/jp/co/training/command/ExitCommand.java +++ b/src/main/java/jp/co/training/command/ExitCommand.java @@ -1,5 +1,7 @@ package jp.co.training.command; +import static jp.co.training.Const.*; + public final class ExitCommand extends Command { public ExitCommand(String name) { @@ -8,7 +10,7 @@ public ExitCommand(String name) { @Override public CommandResult executeCommand(String command, String[] argments) { - CommandResult result = new CommandResult(); + CommandResult result = new CommandResult(EXIT); //TODO 以下の処理はviewerクラスに任せる // result.addMessage(config.endMessage); result.setExit(true); diff --git a/src/main/java/jp/co/training/command/InsertCommand.java b/src/main/java/jp/co/training/command/InsertCommand.java index 2584b58..1f34181 100644 --- a/src/main/java/jp/co/training/command/InsertCommand.java +++ b/src/main/java/jp/co/training/command/InsertCommand.java @@ -1,12 +1,13 @@ package jp.co.training.command; -import static jp.co.training.Code.*; +import static jp.co.training.Const.*; +import static jp.co.training.command.CommandCode.*; -import jp.co.training.Result; -import jp.co.training.Status; import jp.co.training.book.Book; import jp.co.training.book.BookResult; +import jp.co.training.common.Status; import jp.co.training.dao.BookDao; +import jp.co.training.dao.DaoResult; public final class InsertCommand extends Command { @@ -17,7 +18,7 @@ public InsertCommand(String name) { @Override public CommandResult executeCommand(String command, String[] argments) { - CommandResult commandResult = new CommandResult(); + CommandResult commandResult = new CommandResult(INSERT); // パラメータ数チェック if (argments.length != Book.NUMBER_OF_ITEMS) { @@ -34,7 +35,7 @@ public CommandResult executeCommand(String command, String[] argments) { } //書籍情報の登録 - Result result = new BookDao().insert(bookResult.getBook()); + DaoResult result = new BookDao().insert(bookResult.getBook()); commandResult.addCodes(result.getCodes()); commandResult.setStatus(Status.OK); return commandResult; diff --git a/src/main/java/jp/co/training/command/UpdateCommand.java b/src/main/java/jp/co/training/command/UpdateCommand.java index e39d739..d9720fb 100644 --- a/src/main/java/jp/co/training/command/UpdateCommand.java +++ b/src/main/java/jp/co/training/command/UpdateCommand.java @@ -1,5 +1,7 @@ package jp.co.training.command; +import static jp.co.training.Const.*; + import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -13,7 +15,7 @@ public UpdateCommand(String name) { @Override public CommandResult executeCommand(String command, String[] argments) { - CommandResult result = new CommandResult(); + CommandResult result = new CommandResult(UPDATE); String suffix = ".tmp" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss")); Book updateBook = null; diff --git a/src/main/java/jp/co/training/common/Code.java b/src/main/java/jp/co/training/common/Code.java new file mode 100644 index 0000000..e1b6727 --- /dev/null +++ b/src/main/java/jp/co/training/common/Code.java @@ -0,0 +1,6 @@ +package jp.co.training.common; + +public interface Code { + + String getCode(); +} diff --git a/src/main/java/jp/co/training/Entity.java b/src/main/java/jp/co/training/common/Entity.java similarity index 86% rename from src/main/java/jp/co/training/Entity.java rename to src/main/java/jp/co/training/common/Entity.java index feaf3c6..9958eee 100644 --- a/src/main/java/jp/co/training/Entity.java +++ b/src/main/java/jp/co/training/common/Entity.java @@ -1,4 +1,4 @@ -package jp.co.training; +package jp.co.training.common; public abstract class Entity { @@ -23,4 +23,6 @@ public String getUpdatedDate() { return updatedDate; } + public abstract String encode(); + } diff --git a/src/main/java/jp/co/training/common/Result.java b/src/main/java/jp/co/training/common/Result.java new file mode 100644 index 0000000..a6944d5 --- /dev/null +++ b/src/main/java/jp/co/training/common/Result.java @@ -0,0 +1,15 @@ +package jp.co.training.common; + +public abstract class Result { + + private Status status = Status.NG; + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + +} diff --git a/src/main/java/jp/co/training/Status.java b/src/main/java/jp/co/training/common/Status.java similarity index 54% rename from src/main/java/jp/co/training/Status.java rename to src/main/java/jp/co/training/common/Status.java index a74c738..1b084ac 100644 --- a/src/main/java/jp/co/training/Status.java +++ b/src/main/java/jp/co/training/common/Status.java @@ -1,4 +1,4 @@ -package jp.co.training; +package jp.co.training.common; public enum Status { diff --git a/src/main/java/jp/co/training/dao/BookDao.java b/src/main/java/jp/co/training/dao/BookDao.java index 70c3960..37792b5 100644 --- a/src/main/java/jp/co/training/dao/BookDao.java +++ b/src/main/java/jp/co/training/dao/BookDao.java @@ -8,22 +8,20 @@ import java.nio.file.Files; import java.nio.file.Paths; -import jp.co.training.Result; -import jp.co.training.Status; import jp.co.training.book.Book; -import jp.co.training.Code; +import jp.co.training.common.Status; public class BookDao { - public Result insert(Book book) { + public DaoResult insert(Book book) { - Result result = new Result(); + DaoResult result = new DaoResult(); try (PrintWriter writer = new PrintWriter( Files.newBufferedWriter(Paths.get(config.saveFile), StandardCharsets.UTF_8))) { writer.println(book.toString()); } catch (IOException ex) { - result.addCode(Code.IO_ERROR); + result.addCode(DaoCode.IO_ERROR); return result; } diff --git a/src/main/java/jp/co/training/dao/DaoCode.java b/src/main/java/jp/co/training/dao/DaoCode.java new file mode 100644 index 0000000..2301134 --- /dev/null +++ b/src/main/java/jp/co/training/dao/DaoCode.java @@ -0,0 +1,20 @@ +package jp.co.training.dao; + +import jp.co.training.common.Code; + +public enum DaoCode implements Code { + + IO_ERROR("E003"); + + private final String code; + + DaoCode(String code) { + this.code = code; + } + + @Override + public String getCode() { + return this.code; + } + +} diff --git a/src/main/java/jp/co/training/dao/DaoResult.java b/src/main/java/jp/co/training/dao/DaoResult.java new file mode 100644 index 0000000..bbb608e --- /dev/null +++ b/src/main/java/jp/co/training/dao/DaoResult.java @@ -0,0 +1,25 @@ +package jp.co.training.dao; + +import java.util.HashSet; +import java.util.Set; + +import jp.co.training.common.Code; +import jp.co.training.common.Result; + +public class DaoResult extends Result { + + private Set codes = new HashSet<>(); + + public Set getCodes() { + return codes; + } + + public void addCode(Code code) { + codes.add(code); + } + + public void addCodes(Set codes) { + this.codes.addAll(codes); + } + +} diff --git a/src/main/java/jp/co/training/book/BookValidater.java b/src/main/java/jp/co/training/validate/ItemValidater.java similarity index 90% rename from src/main/java/jp/co/training/book/BookValidater.java rename to src/main/java/jp/co/training/validate/ItemValidater.java index 8a7be6f..a9adbfa 100644 --- a/src/main/java/jp/co/training/book/BookValidater.java +++ b/src/main/java/jp/co/training/validate/ItemValidater.java @@ -1,6 +1,6 @@ -package jp.co.training.book; +package jp.co.training.validate; -import static jp.co.training.ItemCode.*; +import static jp.co.training.book.ItemCode.*; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -8,11 +8,11 @@ import java.util.Optional; import java.util.regex.Pattern; -import jp.co.training.ItemCode; +import jp.co.training.book.ItemCode; -public class BookValidater { +public class ItemValidater { - private BookValidater() { + private ItemValidater() { } /** diff --git a/src/test/java/jp/co/training/BookUtilTest.java b/src/test/java/jp/co/training/BookUtilTest.java index f0dc51b..1230c59 100644 --- a/src/test/java/jp/co/training/BookUtilTest.java +++ b/src/test/java/jp/co/training/BookUtilTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import jp.co.training.book.BookValidater; +import jp.co.training.validate.ItemValidater; class BookUtilTest { @@ -18,35 +18,35 @@ class CheckLengthTest { @Test @DisplayName("最大文字超過チェックOK") void maxOverOK() { - Optional result = BookValidater.checkLength("あいう", 1, 3); + Optional result = ItemValidater.checkLength("あいう", 1, 3); assertFalse(result.isPresent()); } @Test @DisplayName("最小文字超過チェックOK") void minUnderOK() { - Optional result = BookValidater.checkLength("あ", 1, 3); + Optional result = ItemValidater.checkLength("あ", 1, 3); assertFalse(result.isPresent()); } @Test @DisplayName("最大文字超過チェックNG") void maxOverNG() { - Optional result = BookValidater.checkLength("あいうえ", 1, 3); + Optional result = ItemValidater.checkLength("あいうえ", 1, 3); assertEquals("the length must be " + 3 + " or less. but actual is " + 4 + ".", result.get()); } @Test @DisplayName("最小文字超過チェックNG") void minUnderNG() { - Optional result = BookValidater.checkLength("", 1, 3); + Optional result = ItemValidater.checkLength("", 1, 3); assertEquals("the length must be " + 1 + " or more. but actual is " + 0 + ".", result.get()); } @Test @DisplayName("nullチェックNG") void nullCheckNG() { - Optional result = BookValidater.checkLength(null, 1, 3); + Optional result = ItemValidater.checkLength(null, 1, 3); assertEquals("the length must be " + 1 + " or more. but actual is null.", result.get()); } } @@ -56,14 +56,14 @@ class checkDatePatternTest { @Test @DisplayName("有効な日付形式OK") void datePatternOK() { - Optional result = BookValidater.checkDatePattern("20180815", DATE_PATTERN); + Optional result = ItemValidater.checkDatePattern("20180815", DATE_PATTERN); assertFalse(result.isPresent()); } @Test @DisplayName("無効な日付形式NG") void datePatternNG() { - Optional result = BookValidater.checkDatePattern("20181815", DATE_PATTERN); + Optional result = ItemValidater.checkDatePattern("20181815", DATE_PATTERN); assertEquals("Invalid Pattern. valid pattern is " + DATE_PATTERN + ".", result.get()); } } From c59d468c713a481fb0434f482e86b0efb2c2c072 Mon Sep 17 00:00:00 2001 From: n-coding Date: Sat, 15 Sep 2018 14:29:21 +0900 Subject: [PATCH 24/27] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=82=92=E4=B8=80=E9=83=A8=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Main.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index 53f6d4d..cebaeac 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -35,6 +35,7 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio // コマンド実行 CommandResult result = command.execute(inputCommand, argments); + //viewerクラスでメッセージ出力をする if (result.getStatus() == Status.OK) { viewer.standardMessages(result.getCommandName()); } else { @@ -42,8 +43,6 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio viewer.errorMessages(result.getItemCodes()); } - //viewerクラスでメッセージ出力をする - // outputMessages(result); if (result != null && result.isExit()) { break; } From 77d13b406867ef5bff19f4e0142a89270ebe45dd Mon Sep 17 00:00:00 2001 From: n-coding Date: Mon, 17 Sep 2018 17:02:01 +0900 Subject: [PATCH 25/27] =?UTF-8?q?=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=82=92=E5=A4=96=E9=83=A8=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=8B=E3=82=89=E5=8F=96=E5=BE=97=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3(=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E9=80=94=E4=B8=AD)=E3=80=82=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD=E5=8A=A0(=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E4=B8=AD)=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Config.java | 7 -- src/main/java/jp/co/training/Const.java | 1 + src/main/java/jp/co/training/Main.java | 16 +--- src/main/java/jp/co/training/Viewer.java | 27 ++++-- .../java/jp/co/training/command/Command.java | 4 +- .../jp/co/training/command/ExitCommand.java | 2 +- .../jp/co/training/command/InsertCommand.java | 17 +++- .../jp/co/training/command/UpdateCommand.java | 93 +++++++++---------- src/main/java/jp/co/training/dao/BookDao.java | 54 +++++++++++ 9 files changed, 139 insertions(+), 82 deletions(-) diff --git a/src/main/java/jp/co/training/Config.java b/src/main/java/jp/co/training/Config.java index 730430f..1e80178 100644 --- a/src/main/java/jp/co/training/Config.java +++ b/src/main/java/jp/co/training/Config.java @@ -8,15 +8,10 @@ public class Config { // 外部ファイルによる設定が可能な定数 - public String prompt; - public String endMessage; public String delimiter; public String saveFile; public String userName; - // 外部ファイルの設定ファイルのキー - private static final String PROMPT_KEY = "prompt"; - private static final String END_MESSAGE_KEY = "end.message"; private static final String DELIMITER_KEY = "delimiter"; private static final String SAVE_FILE_KEY = "save.file"; private static final String USER_NAME_KEY = "user.name"; @@ -47,10 +42,8 @@ public Config load(String path) { } userName = rbProperties.getString(USER_NAME_KEY); - prompt = (rbProperties.containsKey(PROMPT_KEY)) ? rbProperties.getString(PROMPT_KEY) : "books>"; delimiter = (rbProperties.containsKey(DELIMITER_KEY)) ? rbProperties.getString(DELIMITER_KEY) : ","; saveFile = (rbProperties.containsKey(SAVE_FILE_KEY)) ? rbProperties.getString(DELIMITER_KEY) : "savefile"; - endMessage = (rbProperties.containsKey(END_MESSAGE_KEY)) ? rbProperties.getString(END_MESSAGE_KEY) : "bye."; return this; } diff --git a/src/main/java/jp/co/training/Const.java b/src/main/java/jp/co/training/Const.java index 3d06c53..39cf720 100644 --- a/src/main/java/jp/co/training/Const.java +++ b/src/main/java/jp/co/training/Const.java @@ -5,6 +5,7 @@ public final class Const { public static final String CONFIG_FILE = "resource"; public static final String INSERT = "insert"; public static final String UPDATE = "update"; + public static final String SET = "set"; public static final String EXIT = "exit"; public static final String INVALID = "invalid"; public static final int MAX_ISBN = 13; diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index cebaeac..ac7db1e 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -4,14 +4,12 @@ import java.io.FileNotFoundException; import java.io.IOException; -import java.util.Arrays; import java.util.Scanner; import jp.co.training.command.Command; import jp.co.training.command.CommandResult; import jp.co.training.command.ExitCommand; import jp.co.training.command.InsertCommand; -import jp.co.training.common.Status; public final class Main { @@ -29,19 +27,15 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio while (true) { viewer.promptMessages(); String inputCommand = scan.next().toLowerCase(); - String[] argments = scan.nextLine().split(config.delimiter); - argments = (String[]) Arrays.stream(argments).map(e -> e.trim()).toArray(String[]::new); + //引数部の生成方法がinsert用になっている。updateでも使用できるように修正。 + + String argments = scan.nextLine().trim(); // コマンド実行 CommandResult result = command.execute(inputCommand, argments); - //viewerクラスでメッセージ出力をする - if (result.getStatus() == Status.OK) { - viewer.standardMessages(result.getCommandName()); - } else { - viewer.errorMessages(result.getCodes()); - viewer.errorMessages(result.getItemCodes()); - } + //実行結果を出力 + viewer.commandMessages(result); if (result != null && result.isExit()) { break; diff --git a/src/main/java/jp/co/training/Viewer.java b/src/main/java/jp/co/training/Viewer.java index 6b3b5b4..9491c55 100644 --- a/src/main/java/jp/co/training/Viewer.java +++ b/src/main/java/jp/co/training/Viewer.java @@ -1,7 +1,6 @@ package jp.co.training; import static jp.co.training.Const.*; -import static jp.co.training.Main.*; import java.util.Map; import java.util.MissingResourceException; @@ -9,12 +8,18 @@ import java.util.Set; import jp.co.training.book.ItemCode; +import jp.co.training.command.CommandResult; import jp.co.training.common.Code; +import jp.co.training.common.Status; public class Viewer { private ResourceBundle rbMessages; + // メッセージ定義ファイルのキー + private static final String PROMPT_KEY = "prompt"; + private static final String END_MESSAGE_KEY = "end.message"; + //メッセージ定義ファイルのパス private static final String MESSAGES_RESOURCE = "messages"; @@ -28,35 +33,39 @@ public Viewer() { } public void promptMessages() { - System.out.print(config.prompt); + System.out.print(rbMessages.containsKey(PROMPT_KEY) ? rbMessages.getString(PROMPT_KEY) : "books>"); } public void endMessages() { - System.out.print(config.endMessage); + System.out.print(rbMessages.containsKey(END_MESSAGE_KEY) ? rbMessages.getString(PROMPT_KEY) : "bye."); } - public void standardMessages(String commandName) { + public void commandMessages(CommandResult commandResult) { + if (commandResult.getStatus() == Status.OK) { + standardMessages(commandResult.getCommandName()); + } else { + errorMessages(commandResult.getCodes()); + errorMessages(commandResult.getItemCodes()); + } - switch (commandName) { + } + public void standardMessages(String commandName) { + switch (commandName) { case INSERT: System.out.println("inserted"); break; - default: } - } public void errorMessages(Map> itemCodes) { - for (Map.Entry> entry : itemCodes.entrySet()) { System.out.println(entry.getKey()); for (ItemCode code : entry.getValue()) { System.out.println(code); } } - } public void errorMessages(Set codes) { diff --git a/src/main/java/jp/co/training/command/Command.java b/src/main/java/jp/co/training/command/Command.java index 09a7bde..8efbe5e 100644 --- a/src/main/java/jp/co/training/command/Command.java +++ b/src/main/java/jp/co/training/command/Command.java @@ -12,7 +12,7 @@ public Command(String name) { this.name = name; } - public CommandResult execute(String command, String[] argments) { + public CommandResult execute(String command, String argments) { if (command.equals(name)) { return executeCommand(command, argments); } else if (next != null) { @@ -29,6 +29,6 @@ public Command setNext(Command next) { return next; } - public abstract CommandResult executeCommand(String command, String[] argments); + public abstract CommandResult executeCommand(String command, String argments); } diff --git a/src/main/java/jp/co/training/command/ExitCommand.java b/src/main/java/jp/co/training/command/ExitCommand.java index 02c6b53..55e90f5 100644 --- a/src/main/java/jp/co/training/command/ExitCommand.java +++ b/src/main/java/jp/co/training/command/ExitCommand.java @@ -9,7 +9,7 @@ public ExitCommand(String name) { } @Override - public CommandResult executeCommand(String command, String[] argments) { + public CommandResult executeCommand(String command, String argments) { CommandResult result = new CommandResult(EXIT); //TODO 以下の処理はviewerクラスに任せる // result.addMessage(config.endMessage); diff --git a/src/main/java/jp/co/training/command/InsertCommand.java b/src/main/java/jp/co/training/command/InsertCommand.java index 1f34181..e0ecca4 100644 --- a/src/main/java/jp/co/training/command/InsertCommand.java +++ b/src/main/java/jp/co/training/command/InsertCommand.java @@ -1,8 +1,11 @@ package jp.co.training.command; import static jp.co.training.Const.*; +import static jp.co.training.Main.*; import static jp.co.training.command.CommandCode.*; +import java.util.Arrays; + import jp.co.training.book.Book; import jp.co.training.book.BookResult; import jp.co.training.common.Status; @@ -16,18 +19,22 @@ public InsertCommand(String name) { } @Override - public CommandResult executeCommand(String command, String[] argments) { + public CommandResult executeCommand(String command, String argments) { CommandResult commandResult = new CommandResult(INSERT); + //引数をinsert用にパース + String[] params = argments.split(config.delimiter); + params = (String[]) Arrays.stream(params).map(e -> e.trim()).toArray(String[]::new); + // パラメータ数チェック - if (argments.length != Book.NUMBER_OF_ITEMS) { + if (params.length != Book.NUMBER_OF_ITEMS) { commandResult.addCode(WRONG_NUMBER_OF_ARGUMENTS); return commandResult; } //Bookオブジェクト生成 - BookResult bookResult = Book.createBook(argments); + BookResult bookResult = Book.createBook(params); if (bookResult.getStatus() == Status.NG) { commandResult.addItemCodes(bookResult.getItemCodes()); @@ -35,8 +42,8 @@ public CommandResult executeCommand(String command, String[] argments) { } //書籍情報の登録 - DaoResult result = new BookDao().insert(bookResult.getBook()); - commandResult.addCodes(result.getCodes()); + DaoResult daoResult = new BookDao().insert(bookResult.getBook()); + commandResult.addCodes(daoResult.getCodes()); commandResult.setStatus(Status.OK); return commandResult; } diff --git a/src/main/java/jp/co/training/command/UpdateCommand.java b/src/main/java/jp/co/training/command/UpdateCommand.java index d9720fb..da09607 100644 --- a/src/main/java/jp/co/training/command/UpdateCommand.java +++ b/src/main/java/jp/co/training/command/UpdateCommand.java @@ -2,10 +2,14 @@ import static jp.co.training.Const.*; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; -import jp.co.training.book.Book; +import jp.co.training.Const; + +import jp.co.training.common.Status; +import jp.co.training.dao.BookDao; +import jp.co.training.dao.DaoResult; public class UpdateCommand extends Command { @@ -14,51 +18,46 @@ public UpdateCommand(String name) { } @Override - public CommandResult executeCommand(String command, String[] argments) { - CommandResult result = new CommandResult(UPDATE); - String suffix = ".tmp" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss")); - - Book updateBook = null; - // try { - // updateBook = Book.createBook(argments); - // } catch (BookException e1) { - // result.addMessage(e1.getMessage()); - // return result; - // } - // - // Path saveFilePath = Paths.get(config.saveFile); - // Path tmpFilePath = Paths.get(config.saveFile + suffix); - // try (BufferedReader reader = Files.newBufferedReader(saveFilePath); - // PrintWriter writer = new PrintWriter(Files.newBufferedWriter(tmpFilePath, StandardCharsets.UTF_8))) { - // - // String recordLine; - // while ((recordLine = reader.readLine()) != null) { - // BookRecord record = BookRecord.decode(recordLine.split(config.delimiter)); - // //TODO 判定や変換処理 - // if (updateBook.getIsbn().equals(record.getBook().getIsbn())) { - // String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); - // recordLine = new BookRecord.Builder() - // .id(record.getId()) - // .book(updateBook) - // .createUser(record.getCreateUser()) - // .createdDate(record.getCreatedDate()) - // .updateUser(config.userName) - // .updatedDate(today) - // .build().toString(); - // } - // writer.println(recordLine); - // } - // Files.delete(saveFilePath); - // Files.move(tmpFilePath, saveFilePath); - // } catch (IOException e) { - // e.printStackTrace(); - // } catch (BookException e) { - // result.addMessage("File format is invalid."); - // result.addMessage(e.getMessage()); - // return result; - // } + public CommandResult executeCommand(String command, String argments) { + CommandResult commandResult = new CommandResult(UPDATE); + + //argmentsを解析 + + //更新対象として指定しているID取得 + if (argments.indexOf(" ") == -1) { + //TODO 構文エラーを返却 + } + String targetId = argments.substring(0, argments.indexOf(" ")); + argments = argments.substring(argments.indexOf(" ")); + if (!targetId.equals("")) {//TODO正規表現比較に修正 + //TODO ID不正エラー + } + + //サブコマンド(「SET」)取得 + String subCommand = argments.substring(0, argments.indexOf(" ")).toLowerCase(); + argments = argments.substring(argments.indexOf(" ")); + if (!subCommand.equals(Const.SET)) { + //TODO エラー返却 + } + + //Bookオブジェクト生成(&バリデート) + String[] params = argments.split(","); + if (params.equals("")) {//TODO key=valueの形式チェック + //TODO 構文エラー + } + + //更新項目mapを生成 + Map updateParams = new HashMap<>(); + for (String param : params) { + updateParams.put(param.substring(0, param.indexOf("=")), param.substring(param.indexOf("=") + 1)); + } + + //更新実行 + DaoResult daoResult = new BookDao().update(targetId, updateParams); + commandResult.addCodes(daoResult.getCodes()); + commandResult.setStatus(Status.OK); + return commandResult; - return result; } } diff --git a/src/main/java/jp/co/training/dao/BookDao.java b/src/main/java/jp/co/training/dao/BookDao.java index 37792b5..b37a280 100644 --- a/src/main/java/jp/co/training/dao/BookDao.java +++ b/src/main/java/jp/co/training/dao/BookDao.java @@ -7,6 +7,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.Map; import jp.co.training.book.Book; import jp.co.training.common.Status; @@ -29,4 +30,57 @@ public DaoResult insert(Book book) { return result; } + public DaoResult select() { + return null; + } + + public DaoResult update(String id, Map updateParams) { + //TODO 1行ずつ読取、1行ずつ書込 + + // String suffix = ".tmp" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss")); + + // Book updateBook = null; + // try { + // updateBook = Book.createBook(argments); + // } catch (BookException e1) { + // result.addMessage(e1.getMessage()); + // return result; + // } + // + // Path saveFilePath = Paths.get(config.saveFile); + // Path tmpFilePath = Paths.get(config.saveFile + suffix); + // try (BufferedReader reader = Files.newBufferedReader(saveFilePath); + // PrintWriter writer = new PrintWriter(Files.newBufferedWriter(tmpFilePath, StandardCharsets.UTF_8))) { + // + // String recordLine; + // while ((recordLine = reader.readLine()) != null) { + // BookRecord record = BookRecord.decode(recordLine.split(config.delimiter)); + // //TODO 判定や変換処理 + // if (updateBook.getIsbn().equals(record.getBook().getIsbn())) { + // String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)); + // recordLine = new BookRecord.Builder() + // .id(record.getId()) + // .book(updateBook) + // .createUser(record.getCreateUser()) + // .createdDate(record.getCreatedDate()) + // .updateUser(config.userName) + // .updatedDate(today) + // .build().toString(); + // } + // writer.println(recordLine); + // } + // Files.delete(saveFilePath); + // Files.move(tmpFilePath, saveFilePath); + // } catch (IOException e) { + // e.printStackTrace(); + // } catch (BookException e) { + // result.addMessage("File format is invalid."); + // result.addMessage(e.getMessage()); + // return result; + // } + // return result; + + return null; + } + } From 75fdfa88fdff79ba118b2a6b6f9c10e3a4837f09 Mon Sep 17 00:00:00 2001 From: n-coding Date: Wed, 19 Sep 2018 01:21:46 +0900 Subject: [PATCH 26/27] =?UTF-8?q?select=E6=96=87=E3=81=AE=E5=A4=A7?= =?UTF-8?q?=E6=9E=A0=E3=81=A0=E3=81=91=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Const.java | 2 + src/main/java/jp/co/training/book/Book.java | 30 ++++++++++++ .../java/jp/co/training/command/Command.java | 4 +- .../jp/co/training/command/CommandResult.java | 11 +++++ .../jp/co/training/command/ExitCommand.java | 2 +- .../jp/co/training/command/InsertCommand.java | 2 +- .../jp/co/training/command/SelectCommand.java | 47 +++++++++++++++++++ .../jp/co/training/command/UpdateCommand.java | 2 +- src/main/java/jp/co/training/dao/BookDao.java | 22 +++++++-- .../jp/co/training/dao/SelectDaoResult.java | 18 +++++++ 10 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 src/main/java/jp/co/training/command/SelectCommand.java create mode 100644 src/main/java/jp/co/training/dao/SelectDaoResult.java diff --git a/src/main/java/jp/co/training/Const.java b/src/main/java/jp/co/training/Const.java index 39cf720..cb5b0f6 100644 --- a/src/main/java/jp/co/training/Const.java +++ b/src/main/java/jp/co/training/Const.java @@ -6,6 +6,8 @@ public final class Const { public static final String INSERT = "insert"; public static final String UPDATE = "update"; public static final String SET = "set"; + public static final String SELECT = "select"; + public static final String ORDERBY = "orderby"; public static final String EXIT = "exit"; public static final String INVALID = "invalid"; public static final int MAX_ISBN = 13; diff --git a/src/main/java/jp/co/training/book/Book.java b/src/main/java/jp/co/training/book/Book.java index 64c7505..287ad12 100644 --- a/src/main/java/jp/co/training/book/Book.java +++ b/src/main/java/jp/co/training/book/Book.java @@ -5,6 +5,8 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; import jp.co.training.common.Entity; import jp.co.training.common.Status; @@ -213,4 +215,32 @@ public String encode() { this.updateUser, this.updatedDate); } + + public static Book decode(String params) { + return null;//TODO Bookを返却するように修正 + } + + public List output(String[] cols) { + + List list = new ArrayList<>(); + //TODO 作成中 + for (int i = 0; i < cols.length; i++) { + switch (Book.BookCol.valueOf(cols[i])) { + case ID: + list.add(this.id); + break; + case ISBN: + list.add(this.isbn); + break; + default: + + } + } + + return list; + } + + public enum BookCol { + ID, ISBN, BOOK_NAME, AUTHOR, PUBLISHER, PUBLICATION_DATE, PRICE, CREATE_USER, CREATE_DATE, UPDATE_USER, UPDATE_DATE + } } diff --git a/src/main/java/jp/co/training/command/Command.java b/src/main/java/jp/co/training/command/Command.java index 8efbe5e..617cae1 100644 --- a/src/main/java/jp/co/training/command/Command.java +++ b/src/main/java/jp/co/training/command/Command.java @@ -14,7 +14,7 @@ public Command(String name) { public CommandResult execute(String command, String argments) { if (command.equals(name)) { - return executeCommand(command, argments); + return executeCommand(argments); } else if (next != null) { return next.execute(command, argments); } @@ -29,6 +29,6 @@ public Command setNext(Command next) { return next; } - public abstract CommandResult executeCommand(String command, String argments); + public abstract CommandResult executeCommand(String argments); } diff --git a/src/main/java/jp/co/training/command/CommandResult.java b/src/main/java/jp/co/training/command/CommandResult.java index 27e9853..5898fb7 100644 --- a/src/main/java/jp/co/training/command/CommandResult.java +++ b/src/main/java/jp/co/training/command/CommandResult.java @@ -2,6 +2,7 @@ import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -19,6 +20,16 @@ public class CommandResult extends Result { private Set codes = new HashSet<>(); + private List> records; + + public List> getRecords() { + return records; + } + + public void addRecord(List record) { + this.records.add(record); + } + public CommandResult(String commandName) { this.commandName = commandName; } diff --git a/src/main/java/jp/co/training/command/ExitCommand.java b/src/main/java/jp/co/training/command/ExitCommand.java index 55e90f5..4971abf 100644 --- a/src/main/java/jp/co/training/command/ExitCommand.java +++ b/src/main/java/jp/co/training/command/ExitCommand.java @@ -9,7 +9,7 @@ public ExitCommand(String name) { } @Override - public CommandResult executeCommand(String command, String argments) { + public CommandResult executeCommand(String argments) { CommandResult result = new CommandResult(EXIT); //TODO 以下の処理はviewerクラスに任せる // result.addMessage(config.endMessage); diff --git a/src/main/java/jp/co/training/command/InsertCommand.java b/src/main/java/jp/co/training/command/InsertCommand.java index e0ecca4..e66a6c2 100644 --- a/src/main/java/jp/co/training/command/InsertCommand.java +++ b/src/main/java/jp/co/training/command/InsertCommand.java @@ -19,7 +19,7 @@ public InsertCommand(String name) { } @Override - public CommandResult executeCommand(String command, String argments) { + public CommandResult executeCommand(String argments) { CommandResult commandResult = new CommandResult(INSERT); diff --git a/src/main/java/jp/co/training/command/SelectCommand.java b/src/main/java/jp/co/training/command/SelectCommand.java new file mode 100644 index 0000000..b51d0f5 --- /dev/null +++ b/src/main/java/jp/co/training/command/SelectCommand.java @@ -0,0 +1,47 @@ +package jp.co.training.command; + +import static jp.co.training.Const.*; +import static jp.co.training.Main.*; + +import java.util.List; + +import jp.co.training.book.Book; +import jp.co.training.dao.BookDao; +import jp.co.training.dao.SelectDaoResult; + +public class SelectCommand extends Command { + + public SelectCommand(String name) { + super(name); + } + + @Override + public CommandResult executeCommand(String argments) { + + CommandResult result = new CommandResult(SELECT); + + //TODO argments解析 + //orderbyまでを取り出し、それ以前を,区切りで配列にする、それ以降を空白区切りで配列にする + + String[] cols; + String[] orderCols; + if (argments.toLowerCase().indexOf("orderby") == -1) { + cols = argments.split(config.delimiter); + } else { + cols = argments.substring(0, argments.toLowerCase().indexOf(ORDERBY)).split(config.delimiter); + orderCols = argments.substring(argments.toLowerCase().indexOf(ORDERBY) + 1).split(config.delimiter); + } + + //colsのバリデーション + + // + SelectDaoResult daoResult = new BookDao().select(); + List records = daoResult.getRecords(); + + for (Book book : records) { + result.addRecord((book.output(cols))); + } + return result; + } + +} diff --git a/src/main/java/jp/co/training/command/UpdateCommand.java b/src/main/java/jp/co/training/command/UpdateCommand.java index da09607..556fd55 100644 --- a/src/main/java/jp/co/training/command/UpdateCommand.java +++ b/src/main/java/jp/co/training/command/UpdateCommand.java @@ -18,7 +18,7 @@ public UpdateCommand(String name) { } @Override - public CommandResult executeCommand(String command, String argments) { + public CommandResult executeCommand(String argments) { CommandResult commandResult = new CommandResult(UPDATE); //argmentsを解析 diff --git a/src/main/java/jp/co/training/dao/BookDao.java b/src/main/java/jp/co/training/dao/BookDao.java index b37a280..fb781ca 100644 --- a/src/main/java/jp/co/training/dao/BookDao.java +++ b/src/main/java/jp/co/training/dao/BookDao.java @@ -2,10 +2,12 @@ import static jp.co.training.Main.*; +import java.io.BufferedReader; import java.io.IOException; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map; @@ -30,10 +32,6 @@ public DaoResult insert(Book book) { return result; } - public DaoResult select() { - return null; - } - public DaoResult update(String id, Map updateParams) { //TODO 1行ずつ読取、1行ずつ書込 @@ -83,4 +81,20 @@ public DaoResult update(String id, Map updateParams) { return null; } + public SelectDaoResult select() { + SelectDaoResult result = new SelectDaoResult<>(); + Path saveFilePath = Paths.get(config.saveFile); + try (BufferedReader reader = Files.newBufferedReader(saveFilePath)) { + + String recordLine; + while ((recordLine = reader.readLine()) != null) { + result.add(Book.decode(recordLine)); + } + } catch (IOException e) { + result.addCode(DaoCode.IO_ERROR); + return result; + } + return result; + } + } diff --git a/src/main/java/jp/co/training/dao/SelectDaoResult.java b/src/main/java/jp/co/training/dao/SelectDaoResult.java new file mode 100644 index 0000000..656dae7 --- /dev/null +++ b/src/main/java/jp/co/training/dao/SelectDaoResult.java @@ -0,0 +1,18 @@ +package jp.co.training.dao; + +import java.util.ArrayList; +import java.util.List; + +public class SelectDaoResult extends DaoResult { + + private List records = new ArrayList<>(); + + public List getRecords() { + return records; + } + + public void add(T t) { + records.add(t); + } + +} From 18291736e5e5c7a7a6a176761d77211e738a06d7 Mon Sep 17 00:00:00 2001 From: n-coding Date: Thu, 20 Sep 2018 00:16:59 +0900 Subject: [PATCH 27/27] =?UTF-8?q?update=E3=81=AE=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=81=AE=E7=84=A1=E9=A7=84=E3=81=AA=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/co/training/Main.java | 2 -- .../jp/co/training/command/UpdateCommand.java | 30 +++++-------------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/main/java/jp/co/training/Main.java b/src/main/java/jp/co/training/Main.java index ac7db1e..9cd8cc4 100644 --- a/src/main/java/jp/co/training/Main.java +++ b/src/main/java/jp/co/training/Main.java @@ -27,8 +27,6 @@ public static void main(String... args) throws FileNotFoundException, IOExceptio while (true) { viewer.promptMessages(); String inputCommand = scan.next().toLowerCase(); - //引数部の生成方法がinsert用になっている。updateでも使用できるように修正。 - String argments = scan.nextLine().trim(); // コマンド実行 diff --git a/src/main/java/jp/co/training/command/UpdateCommand.java b/src/main/java/jp/co/training/command/UpdateCommand.java index 556fd55..d131a34 100644 --- a/src/main/java/jp/co/training/command/UpdateCommand.java +++ b/src/main/java/jp/co/training/command/UpdateCommand.java @@ -22,34 +22,20 @@ public CommandResult executeCommand(String argments) { CommandResult commandResult = new CommandResult(UPDATE); //argmentsを解析 - - //更新対象として指定しているID取得 - if (argments.indexOf(" ") == -1) { + String[] params = argments.split(" " + Const.SET + " "); + if (params.length == 1) { //TODO 構文エラーを返却 } - String targetId = argments.substring(0, argments.indexOf(" ")); - argments = argments.substring(argments.indexOf(" ")); - if (!targetId.equals("")) {//TODO正規表現比較に修正 - //TODO ID不正エラー - } - //サブコマンド(「SET」)取得 - String subCommand = argments.substring(0, argments.indexOf(" ")).toLowerCase(); - argments = argments.substring(argments.indexOf(" ")); - if (!subCommand.equals(Const.SET)) { - //TODO エラー返却 - } - - //Bookオブジェクト生成(&バリデート) - String[] params = argments.split(","); - if (params.equals("")) {//TODO key=valueの形式チェック - //TODO 構文エラー - } + String targetId = params[0]; + String[] keyValues = params[1].split(","); //更新項目mapを生成 Map updateParams = new HashMap<>(); - for (String param : params) { - updateParams.put(param.substring(0, param.indexOf("=")), param.substring(param.indexOf("=") + 1)); + for (String keyValue : keyValues) { + //TODO正規表現でkey=valueの形式チェック + updateParams.put(keyValue.substring(0, keyValue.indexOf("=")), + keyValue.substring(keyValue.indexOf("=") + 1)); } //更新実行