Skip to content

Commit

Permalink
Added solution
Browse files Browse the repository at this point in the history
  • Loading branch information
slaybrute committed Oct 26, 2023
1 parent 0f48631 commit 275c10b
Show file tree
Hide file tree
Showing 34 changed files with 940 additions and 14 deletions.
Empty file added readonly.csv
Empty file.
4 changes: 4 additions & 0 deletions report.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fruit,quantity
apple,160
banana,115
pear,140
7 changes: 0 additions & 7 deletions src/main/java/core/basesyntax/HelloWorld.java

This file was deleted.

48 changes: 48 additions & 0 deletions src/main/java/core/basesyntax/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package core.basesyntax;

import core.basesyntax.model.FruitTransaction;
import core.basesyntax.service.FileReader;
import core.basesyntax.service.FileReaderImpl;
import core.basesyntax.service.ParseService;
import core.basesyntax.service.ParseServiceImpl;
import core.basesyntax.service.PurchaseOperationHandler;
import core.basesyntax.service.RemnantOperationHandler;
import core.basesyntax.service.ReportService;
import core.basesyntax.service.ReportServiceImpl;
import core.basesyntax.service.SupplyOperationHandler;
import core.basesyntax.strategy.OperationStrategy;
import core.basesyntax.strategy.OperationStrategyImpl;
import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.List;

public class Main {
private static final String[] FILE_NAMES =
new String[]{"input1.csv", "input2.csv", "input3.csv"};

public static void main(String[] args) {
FileReader fileReader = new FileReaderImpl();
ParseService parseService = new ParseServiceImpl();
ReportService reportService = new ReportServiceImpl();
OperationStrategy operationStrategy = new OperationStrategyImpl(new HashMap<>() {{
put(FruitTransaction.Operation.BALANCE, new RemnantOperationHandler());
put(FruitTransaction.Operation.PURCHASE, new PurchaseOperationHandler());
put(FruitTransaction.Operation.RETURN, new SupplyOperationHandler());
put(FruitTransaction.Operation.SUPPLY, new SupplyOperationHandler());
}}
);
ClassLoader classLoader = Main.class.getClassLoader();
for (String fileName : FILE_NAMES) {
URL resources = classLoader.getResource(fileName);
List<FruitTransaction> fruitTransactions = parseService.parse(
fileReader.readFromFile(new File(resources.getFile())));
for (FruitTransaction fruitTransaction : fruitTransactions) {
operationStrategy
.get(fruitTransaction.getOperation())
.handle(fruitTransaction.getFruit(), fruitTransaction.getQuantity());
}
System.out.println(reportService.generateReport() + System.lineSeparator());
}
}
}
9 changes: 9 additions & 0 deletions src/main/java/core/basesyntax/dao/FruitDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package core.basesyntax.dao;

public interface FruitDao {
void add(String name, int quantity);

void set(String name, int quantity);

void remove(String name, int quantity);
}
42 changes: 42 additions & 0 deletions src/main/java/core/basesyntax/dao/FruitDaoImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package core.basesyntax.dao;

import java.util.HashMap;
import java.util.Map;

public class FruitDaoImpl implements FruitDao {
private static final Map<String, Integer> fruits = new HashMap<>();

public static Map<String, Integer> getFruits() {
Map<String, Integer> fruitsCopy = new HashMap<>();
for (String key : fruits.keySet()) {
fruitsCopy.put(key, fruits.get(key));

}
return fruitsCopy;
}

@Override
public void add(String name, int quantity) {
if (quantity < 0) {
throw new RuntimeException("Cannot add such quantity: " + quantity);
}
int currentAmount = fruits.getOrDefault(name, 0);
fruits.put(name, currentAmount + quantity);
}

@Override
public void remove(String name, int quantity) {
if (fruits.get(name) < quantity) {
throw new RuntimeException("Not enough " + name + " to purchase");
}
fruits.put(name, fruits.get(name) - quantity);
}

@Override
public void set(String name, int quantity) {
if (quantity < 0) {
throw new RuntimeException("Cannot put such quantity: " + quantity);
}
fruits.put(name, quantity);
}
}
80 changes: 80 additions & 0 deletions src/main/java/core/basesyntax/model/FruitTransaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package core.basesyntax.model;

import java.util.NoSuchElementException;
import java.util.Objects;

public class FruitTransaction {
private Operation operation;
private String fruit;
private int quantity;

public FruitTransaction(String fruit, int quantity, Operation operation) {
this.fruit = fruit;
this.quantity = quantity;
this.operation = operation;
}

public Operation getOperation() {
return operation;
}

public void setOperation(Operation operation) {
this.operation = operation;
}

public String getFruit() {
return fruit;
}

public void setFruit(String fruit) {
this.fruit = fruit;
}

public int getQuantity() {
return quantity;
}

public void setQuantity(int quantity) {
this.quantity = quantity;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || obj.getClass() != FruitTransaction.class) {
return false;
}
FruitTransaction fruitTransaction = (FruitTransaction) obj;
return Objects.equals(this.fruit, fruitTransaction.fruit)
&& Objects.equals(this.quantity, fruitTransaction.quantity)
&& Objects.equals(this.operation, fruitTransaction.operation);
}

public enum Operation {
BALANCE("b"),
SUPPLY("s"),
PURCHASE("p"),
RETURN("r");

private final String operation;

Operation(String operation) {
this.operation = operation;
}

public String getOperation() {
return operation;
}

public static Operation getByCode(String code) {
for (Operation operation : values()) {
if (operation.getOperation().equals(code)) {
return operation;
}
}
throw new NoSuchElementException("Unknown operation: " + code);
}
}
}
8 changes: 8 additions & 0 deletions src/main/java/core/basesyntax/service/FileReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package core.basesyntax.service;

import java.io.File;
import java.util.List;

public interface FileReader {
List<String> readFromFile(File file);
}
26 changes: 26 additions & 0 deletions src/main/java/core/basesyntax/service/FileReaderImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package core.basesyntax.service;

import core.basesyntax.model.FruitTransaction;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

public class FileReaderImpl implements FileReader {
private static final String SEPARATOR = ",";
private static final int HEADER_INDEX = 0;
private static final int OPERATION_INDEX = 0;
private static final int FRUIT_INDEX = 1;
private static final int AMOUNT_INDEX = 2;

@Override
public List<String> readFromFile(File file) {
ArrayList<FruitTransaction> fruitTransactions = new ArrayList<>();
try {
return Files.readAllLines(file.toPath());
} catch (IOException ioException) {
throw new RuntimeException("Cannot read data from file: " + file, ioException);
}
}
}
7 changes: 7 additions & 0 deletions src/main/java/core/basesyntax/service/FileWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package core.basesyntax.service;

import java.io.File;

public interface FileWriter {
void writeToFile(File file, String report);
}
17 changes: 17 additions & 0 deletions src/main/java/core/basesyntax/service/FileWriterImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package core.basesyntax.service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterImpl implements core.basesyntax.service.FileWriter {
@Override
public void writeToFile(File file, String report) {
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file))) {
bufferedWriter.write(report);
} catch (IOException ioException) {
throw new RuntimeException("Cannot write data to file: " + file, ioException);
}
}
}
5 changes: 5 additions & 0 deletions src/main/java/core/basesyntax/service/OperationHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package core.basesyntax.service;

public interface OperationHandler {
void handle(String name, int amount);
}
8 changes: 8 additions & 0 deletions src/main/java/core/basesyntax/service/ParseService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package core.basesyntax.service;

import core.basesyntax.model.FruitTransaction;
import java.util.List;

public interface ParseService {
List<FruitTransaction> parse(List<String> fruits);
}
41 changes: 41 additions & 0 deletions src/main/java/core/basesyntax/service/ParseServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package core.basesyntax.service;

import core.basesyntax.model.FruitTransaction;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;

public class ParseServiceImpl implements ParseService {
private static final String SEPARATOR = ",";
private static final int HEADER_INDEX = 0;
private static final int OPERATION_INDEX = 0;
private static final int FRUIT_INDEX = 1;
private static final int AMOUNT_INDEX = 2;

@Override
public List<FruitTransaction> parse(List<String> fruits) {
ArrayList<FruitTransaction> fruitTransactions = new ArrayList<>();
fruits.remove(HEADER_INDEX);
for (String fruit : fruits) {
String[] parsedFruit = fruit.split(SEPARATOR);
try {
int amount = Integer.parseInt(parsedFruit[AMOUNT_INDEX]);
if (amount < 0) {
throw new NumberFormatException();
}
FruitTransaction.Operation operation
= FruitTransaction.Operation.getByCode(parsedFruit[OPERATION_INDEX]);
fruitTransactions.add(new FruitTransaction(parsedFruit[FRUIT_INDEX],
amount, operation));
} catch (NumberFormatException numberFormatException) {
throw new RuntimeException("Invalid amount: " + parsedFruit[AMOUNT_INDEX],
numberFormatException);
} catch (NoSuchElementException noSuchElementException) {
throw new RuntimeException("No such operation code: "
+ parsedFruit[OPERATION_INDEX],
noSuchElementException);
}
}
return fruitTransactions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package core.basesyntax.service;

import core.basesyntax.dao.FruitDao;
import core.basesyntax.dao.FruitDaoImpl;

public class PurchaseOperationHandler implements OperationHandler {
private FruitDao fruitDao = new FruitDaoImpl();

@Override
public void handle(String name, int amount) {
fruitDao.remove(name, amount);
}
}
13 changes: 13 additions & 0 deletions src/main/java/core/basesyntax/service/RemnantOperationHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package core.basesyntax.service;

import core.basesyntax.dao.FruitDao;
import core.basesyntax.dao.FruitDaoImpl;

public class RemnantOperationHandler implements OperationHandler {
private FruitDao fruitDao = new FruitDaoImpl();

@Override
public void handle(String name, int amount) {
fruitDao.set(name, amount);
}
}
5 changes: 5 additions & 0 deletions src/main/java/core/basesyntax/service/ReportService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package core.basesyntax.service;

public interface ReportService {
public String generateReport();
}
21 changes: 21 additions & 0 deletions src/main/java/core/basesyntax/service/ReportServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package core.basesyntax.service;

import core.basesyntax.dao.FruitDaoImpl;
import java.util.TreeSet;

public class ReportServiceImpl implements ReportService {
private static final String SEPARATOR = ",";
private static final String HEADER = "fruit,quantity";
private FruitDaoImpl fruitDao = new FruitDaoImpl();

@Override
public String generateReport() {
StringBuilder stringBuilder = new StringBuilder(HEADER);
for (String key : new TreeSet<>(fruitDao.getFruits().keySet())) {
stringBuilder.append(System.lineSeparator())
.append(key)
.append(SEPARATOR).append(fruitDao.getFruits().get(key));
}
return stringBuilder.toString();
}
}
13 changes: 13 additions & 0 deletions src/main/java/core/basesyntax/service/SupplyOperationHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package core.basesyntax.service;

import core.basesyntax.dao.FruitDao;
import core.basesyntax.dao.FruitDaoImpl;

public class SupplyOperationHandler implements OperationHandler {
private FruitDao fruitDao = new FruitDaoImpl();

@Override
public void handle(String name, int amount) {
fruitDao.add(name, amount);
}
}
8 changes: 8 additions & 0 deletions src/main/java/core/basesyntax/strategy/OperationStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package core.basesyntax.strategy;

import core.basesyntax.model.FruitTransaction;
import core.basesyntax.service.OperationHandler;

public interface OperationStrategy {
OperationHandler get(FruitTransaction.Operation operation);
}
Loading

0 comments on commit 275c10b

Please sign in to comment.