From 9a015dae599d049b12d2e2fd3ddb2fdf18fd44a1 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 15 Mar 2026 18:19:16 +0100 Subject: [PATCH] Feat: Updated fileconverter and fileparser. --- .../idatt2003/g40/mappe/FileConverter.java | 60 +++++++- .../idi/idatt2003/g40/mappe/FileParser.java | 130 +++++++++++++++++- 2 files changed, 178 insertions(+), 12 deletions(-) diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/FileConverter.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/FileConverter.java index 936a9d4..6075200 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/FileConverter.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/FileConverter.java @@ -1,23 +1,73 @@ package edu.ntnu.idi.idatt2003.g40.mappe; -import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; +/** + * Converts stock objects to/from string format for file handling. + * + *

Responsibilities:

+ * + * + *

Used with {@link FileParser}

+ * + * @see FileParser + * @author tohja + * @version 1.0.0 + * + * */ public class FileConverter { - public List getStocksFromFile(FileParser fileParser) throws IOException { - List strings = fileParser.readFile(); + /** + * Turns a list of valid string representations + * of stock objects to a list of stock objects. + * + * @param validStocks list of string elements properly + * representing stock objects. + * + * @return {@link List} + * */ + public List getStocksFromStrings(final List validStocks) { List stocksFromFile = new ArrayList<>(); + List stockSymbols = new ArrayList<>(); - strings.forEach(s -> { + validStocks.forEach(s -> { String[] lineElements = s.split(","); String stockSymbol = lineElements[0].trim(); String stockName = lineElements[1].trim(); BigDecimal stockPrice = new BigDecimal(lineElements[2].trim()); - stocksFromFile.add(new Stock(stockSymbol, stockName, stockPrice)); + // TODO: try-catch + Stock stockObject = new Stock(stockSymbol, stockName, stockPrice); + if (!stockSymbols.contains(stockSymbol)) { + stockSymbols.add(stockSymbol); + stocksFromFile.add(stockObject); + } }); return stocksFromFile; } + + /** + * Converts a list of stocks to string representations of that stock. + * + *

format: SYMBOL, NAME, PRICE

+ * + * @param stocks a list of {@link Stock} objects. + * + * @return a list of string representation of the stock objects. + * */ + public List stocksToStrings(final List stocks) { + ArrayList stringList = new ArrayList<>(); + stocks.forEach(s -> + stringList.add(s.getSymbol().trim() + "," + s.getCompany().trim() + + "," + s.getSalesPrice().toString()) + ); + return stringList; + } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/FileParser.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/FileParser.java index 23c8f8a..d0d0279 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/FileParser.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/FileParser.java @@ -1,23 +1,74 @@ package edu.ntnu.idi.idatt2003.g40.mappe; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.IOException; import java.math.BigDecimal; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.List; import java.util.function.Predicate; +/** + * Class used to parse (filter) valid stocks from a .txt file. + * + *

Responsibilities:

+ *
    + *
  • Read file and return a filtered list of string elements, + * where each element represents a valid stock line.
  • + * + *
  • Write a list of string representations of stock objects + * to file, each stock separated by a line.
  • + *
+ * + *

Used with {@link FileConverter}

+ * + * @see FileConverter + * @author tohja + * @version 1.0.0 + * */ public class FileParser { + /** The path name this parser is using.*/ private final String pathName; + /** + * Rule set for validating lines and strings. + * + *

Uses predicates.

+ * */ private enum ParserRuleSet { + + /** + * Rule for whether string is empty or not. + * */ NOT_EMPTY(s -> !s.trim().isEmpty()), + + /** + * Rule for if string is comment or not. + * */ NOT_COMMENT(s -> !s.startsWith("#")), + + /** + * Rule for if line is in valid format. + * */ VALID_FORMAT(NOT_EMPTY.rule.and(NOT_COMMENT.rule)), + + /** + * Rule for if string is considered a valid company symbol. + * */ VALID_CODE(s -> s.matches("[A-Z]{4}")), + + /** + * Rule for if string is a valid company name. + * */ VALID_NAME(s -> s.matches(".*")), + + /** + * Rule for if string can be parsed to a {@link BigDecimal} object. + * */ CAN_PARSE_TO_BIG_DECIMAL(s -> { try { new BigDecimal(s); @@ -26,9 +77,20 @@ private enum ParserRuleSet { return false; } }), + + /** + * Rule for if string is in a valid price format. + * */ VALID_PRICE_FORMAT(s -> s.matches("[^a-zA-Z]+")), + + /** + * Rule for if string is a valid price. + * */ VALID_PRICE(VALID_PRICE_FORMAT.rule.and(CAN_PARSE_TO_BIG_DECIMAL.rule)); + /** + * The constants' rules as predicates with input of type string. + * */ private final Predicate rule; ParserRuleSet(final Predicate rule) { @@ -36,15 +98,35 @@ private enum ParserRuleSet { } } + /** + * Constructor. + * + * @param pathName the file path name to read. + * */ public FileParser(final String pathName) { this.pathName = pathName; } + /** + * Reads the file and returns a list element of all valid stocks as strings. + * + *

Uses {@link BufferedReader} for opening a file stream.

+ * + * @return {@link List} object of all valid stock strings in file. + * + * @throws IOException if path cannot be read. + * + * @see Path + * */ + public List readFile() throws IOException { - try { - Path path = Paths.get(pathName); - List allLines = Files.readAllLines(path); - List readableLines = allLines.stream().filter(ParserRuleSet.VALID_FORMAT.rule).toList(); + Path path = Paths.get(pathName); + try (BufferedReader bufferedReader = Files.newBufferedReader(path)) { + + List allLines = bufferedReader.readAllLines(); + List readableLines = + allLines.stream() + .filter(ParserRuleSet.VALID_FORMAT.rule).toList(); // Valid lines (following the correct regular expressions) return readableLines.stream().filter(s -> { @@ -54,9 +136,14 @@ public List readFile() throws IOException { return false; } - boolean validCode = ParserRuleSet.VALID_CODE.rule.test(parts[0].trim()); - boolean validName = ParserRuleSet.VALID_NAME.rule.test(parts[1].trim()); - boolean validPrice = ParserRuleSet.VALID_PRICE.rule.test(parts[2].trim()); + boolean validCode = ParserRuleSet + .VALID_CODE.rule.test(parts[0].trim()); + + boolean validName = ParserRuleSet + .VALID_NAME.rule.test(parts[1].trim()); + + boolean validPrice = ParserRuleSet + .VALID_PRICE.rule.test(parts[2].trim()); return validCode && validName && validPrice; }).toList(); @@ -65,4 +152,33 @@ public List readFile() throws IOException { throw new IOException("File parser could not parse file!"); } } + + /** + * Writes a given lists of stocks to the file. + * + *

Uses {@link BufferedWriter}.

+ * + * @param stringList list of strings representing stocks in the format + * SYMBOL, NAME, PRICE + * + * @throws IOException if writing process throws error. + * */ + public void writeStocksToFile(final List stringList) + throws IOException { + Path path = Paths.get(pathName); + + try (BufferedWriter writer = Files.newBufferedWriter(path, + StandardOpenOption.CREATE, + StandardOpenOption.APPEND)) { + + writer.newLine(); + + for (String line : stringList) { + writer.write(line); + writer.newLine(); + } + } catch (IOException e) { + throw new IOException("Error during buffered write", e); + } + } }