Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hw 1 solution #1233

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions src/main/java/core/basesyntax/HelloWorld.java

This file was deleted.

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

import core.basesyntax.file.FileReader;
import core.basesyntax.file.FileReaderImpl;
import core.basesyntax.file.FileWriter;
import core.basesyntax.file.FileWriterImpl;
import core.basesyntax.model.OperationType;
import core.basesyntax.model.ShopOperation;
import core.basesyntax.service.DataConverter;
import core.basesyntax.service.ReportGenerator;
import core.basesyntax.service.ShopService;
import core.basesyntax.service.StrategyOperationService;
import core.basesyntax.service.impl.DataConverterImpl;
import core.basesyntax.service.impl.ReportGeneratorImpl;
import core.basesyntax.service.impl.ShopServiceImpl;
import core.basesyntax.service.impl.StrategyOperationServiceImpl;
import core.basesyntax.strategy.BalanceOperation;
import core.basesyntax.strategy.OperationHandler;
import core.basesyntax.strategy.PurchaseOperation;
import core.basesyntax.strategy.ReturnOperation;
import core.basesyntax.strategy.SupplyOperation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
private static final String PATH_TO_FILE = "src/main/resources/reportToRead.csv";
private static final String PATH_TO_REPORT_FILE = "src/main/resources/finalReport.csv";

public static void main(String[] args) {
FileReader fileReader = new FileReaderImpl();
List<String> inputReport = fileReader.read(PATH_TO_FILE);

DataConverter dataConverter = new DataConverterImpl();

Map<OperationType, OperationHandler> operationHandlers = new HashMap<>();
operationHandlers.put(OperationType.BALANCE, new BalanceOperation());
operationHandlers.put(OperationType.PURCHASE, new PurchaseOperation());
operationHandlers.put(OperationType.SUPPLY, new SupplyOperation());
operationHandlers.put(OperationType.RETURN, new ReturnOperation());
StrategyOperationService operationStrategy = new StrategyOperationServiceImpl(
operationHandlers);

List<ShopOperation> operations = dataConverter.convertToOperation(inputReport);

ShopService shopService = new ShopServiceImpl(operationStrategy);
shopService.process(operations);

ReportGenerator reportGenerator = new ReportGeneratorImpl();
String resultingReport = reportGenerator.getReport();

FileWriter fileWriter = new FileWriterImpl();
fileWriter.write(PATH_TO_REPORT_FILE, resultingReport);
}
}
12 changes: 12 additions & 0 deletions src/main/java/core/basesyntax/db/Storage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package core.basesyntax.db;

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

public class Storage {
public static final Map<String, Integer> fruitsStorage = new HashMap<>();

public Map<String, Integer> getFruitsStorage() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove this method because your map is public ;)

return fruitsStorage;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning a direct reference to the fruitsStorage map can lead to unintended modifications from outside the class. Consider returning an unmodifiable view or a copy of the map to prevent external modifications.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exposing the internal storage map directly through getFruitsStorage can lead to unintended modifications from outside the class. Consider providing specific methods for adding, removing, or updating entries in the storage to maintain better control over the data.

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

import java.util.List;

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

import exception.FileException;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the FileException class is correctly defined and imported. If it is not present in the project, you need to create it to handle file-related exceptions properly.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

public class FileReaderImpl implements FileReader {
@Override
public List<String> read(String filePath) {
List<String> reportList;
try {
reportList = Files.readAllLines(Path.of(filePath));
} catch (IOException e) {
throw new FileException("Can't read data from file: " + filePath);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the FileException class is defined in your project. If not, you need to create this custom exception class to handle file-related errors appropriately.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider including the original exception e as a cause in the FileException to provide more context about the error. For example: throw new FileException("Can't read data from file: " + filePath, e);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new FileException("Can't read data from file: " + filePath);
throw new FileException("Can't read data from file: " + filePath, e);

}
return reportList;
}
}
5 changes: 5 additions & 0 deletions src/main/java/core/basesyntax/file/FileWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package core.basesyntax.file;

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

import exception.FileException;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the FileException class is correctly defined and imported. If it is not present in the project, you need to create it to handle file-related exceptions properly.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class FileWriterImpl implements FileWriter {
@Override
public void write(String filePath, String report) {
try {
Files.writeString(Path.of(filePath), report);
} catch (IOException e) {
throw new FileException("Can't write data to file: " + filePath);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the FileException class is defined in your project. If not, you need to create this custom exception class to handle file-related errors appropriately.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider including the original exception e as a cause in the FileException to provide more context about the error. For example: throw new FileException("Can't write data to file: " + filePath, e);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same

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

import exception.OperationException;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the OperationException class is correctly defined and imported. If it is not present in the project, you need to create it to handle cases where an invalid operation code is provided.


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

private final String codeOperation;

OperationType(String codeOperation) {
this.codeOperation = codeOperation;
}

public String getCodeOperation() {
return codeOperation;
}

public static OperationType getOperationType(String codeOperation) {
for (OperationType type : OperationType.values()) {
if (type.getCodeOperation().equals(codeOperation)) {
return type;
}
}
throw new OperationException("Operation not found by code: " + codeOperation);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the OperationException class is defined in your project. If not, you need to create this custom exception class to handle invalid operation codes appropriately.

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

public class ShopOperation {
private final OperationType type;
private final String fruit;
private final int quantity;

public ShopOperation(OperationType type, String fruit, int quantity) {
this.type = type;
this.fruit = fruit;
this.quantity = quantity;
}

public OperationType getType() {
return type;
}

public String getFruit() {
return fruit;
}

public int getQuantity() {
return quantity;
}

@Override
public String toString() {
return "ShopOperation{"
+ "type=" + type
+ ", fruit='" + fruit + '\''
+ ", quantity=" + quantity + '}';
}
}
8 changes: 8 additions & 0 deletions src/main/java/core/basesyntax/service/DataConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package core.basesyntax.service;

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

public interface DataConverter {
List<ShopOperation> convertToOperation(List<String> reportList);
}
5 changes: 5 additions & 0 deletions src/main/java/core/basesyntax/service/ReportGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package core.basesyntax.service;

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

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

public interface ShopService {
void process(List<ShopOperation> operations);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package core.basesyntax.service;

import core.basesyntax.model.OperationType;
import core.basesyntax.strategy.OperationHandler;

public interface StrategyOperationService {
OperationHandler get(OperationType operationType);
}
30 changes: 30 additions & 0 deletions src/main/java/core/basesyntax/service/impl/DataConverterImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package core.basesyntax.service.impl;

import core.basesyntax.model.OperationType;
import core.basesyntax.model.ShopOperation;
import core.basesyntax.service.DataConverter;
import java.util.ArrayList;
import java.util.List;

public class DataConverterImpl implements DataConverter {
private static final int LIST_START = 1;
private static final int OPERATION_INDEX = 0;
private static final int FRUIT_INDEX = 1;
private static final int QUANTITY_INDEX = 2;
private static final String COMMA = ",";

@Override
public List<ShopOperation> convertToOperation(List<String> reportList) {
List<ShopOperation> shopOperationList = new ArrayList<>();
for (String line : reportList.subList(LIST_START, reportList.size())) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method skips the first line of the reportList, assuming it is a header. Ensure that the input data format always includes a header to avoid missing data.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method assumes that the input list reportList has at least one line to skip (likely a header). Ensure that the input list is validated to prevent IndexOutOfBoundsException if the list is empty or has fewer lines than expected.

String[] parts = line.split(COMMA);
String codeOperation = parts[OPERATION_INDEX];
String fruit = parts[FRUIT_INDEX];
int quantity = Integer.parseInt(parts[QUANTITY_INDEX]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding error handling for Integer.parseInt to manage potential NumberFormatException if the quantity is not a valid integer.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding error handling for Integer.parseInt(parts[QUANTITY_INDEX]) to manage potential NumberFormatException if the quantity is not a valid integer.

shopOperationList.add(
new ShopOperation(OperationType.getOperationType(codeOperation),
fruit, quantity));
}
return shopOperationList;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package core.basesyntax.service.impl;

import core.basesyntax.db.Storage;
import core.basesyntax.service.ReportGenerator;
import java.util.Map;

public class ReportGeneratorImpl implements ReportGenerator {
private static final String LINE_SEPARATOR = System.lineSeparator();
private static final String COMMA = ",";
private static final String HEADER = "fruit,quantity";

@Override
public String getReport() {
StringBuilder stringBuilder = new StringBuilder(HEADER + LINE_SEPARATOR);
for (Map.Entry<String, Integer> entry : Storage.fruitsStorage.entrySet()) {
stringBuilder.append(entry.getKey())
.append(COMMA)
.append(entry.getValue())
.append(LINE_SEPARATOR);
}
return stringBuilder.toString();
}
}
21 changes: 21 additions & 0 deletions src/main/java/core/basesyntax/service/impl/ShopServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package core.basesyntax.service.impl;

import core.basesyntax.model.ShopOperation;
import core.basesyntax.service.ShopService;
import core.basesyntax.service.StrategyOperationService;
import java.util.List;

public class ShopServiceImpl implements ShopService {
private final StrategyOperationService strategyOperationService;

public ShopServiceImpl(StrategyOperationService strategyOperationService) {
this.strategyOperationService = strategyOperationService;
}

@Override
public void process(List<ShopOperation> operations) {
for (ShopOperation operation : operations) {
strategyOperationService.get(operation.getType()).handle(operation);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package core.basesyntax.service.impl;

import core.basesyntax.model.OperationType;
import core.basesyntax.service.StrategyOperationService;
import core.basesyntax.strategy.OperationHandler;
import java.util.Map;

public class StrategyOperationServiceImpl implements StrategyOperationService {
private Map<OperationType, OperationHandler> operationHandlerMap;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making operationHandlerMap final to indicate that it should not be reassigned after initialization. This can help prevent accidental modifications to the map reference.


public StrategyOperationServiceImpl(Map<OperationType, OperationHandler> operationHandlerMap) {
this.operationHandlerMap = operationHandlerMap;
}

@Override
public OperationHandler get(OperationType operationType) {
return operationHandlerMap.get(operationType);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a check to handle cases where operationType is not present in the operationHandlerMap. This will prevent potential NullPointerException if an unregistered operation type is requested.

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

import core.basesyntax.db.Storage;
import core.basesyntax.model.ShopOperation;

public class BalanceOperation implements OperationHandler {
@Override
public void handle(ShopOperation shopOperation) {
Storage.fruitsStorage.put(shopOperation.getFruit(), shopOperation.getQuantity());
}
}
7 changes: 7 additions & 0 deletions src/main/java/core/basesyntax/strategy/OperationHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package core.basesyntax.strategy;

import core.basesyntax.model.ShopOperation;

public interface OperationHandler {
void handle(ShopOperation shopOperation);
}
19 changes: 19 additions & 0 deletions src/main/java/core/basesyntax/strategy/PurchaseOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package core.basesyntax.strategy;

import core.basesyntax.db.Storage;
import core.basesyntax.model.ShopOperation;
import exception.OperationException;

public class PurchaseOperation implements OperationHandler {
@Override
public void handle(ShopOperation shopOperation) {
String fruit = shopOperation.getFruit();
int quantity = Storage.fruitsStorage.get(fruit);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a check to handle cases where the fruit is not present in the fruitsStorage. This will prevent potential NullPointerException if a purchase operation is attempted for a fruit not in storage.

int quantityToBuy = shopOperation.getQuantity();
if (quantity < quantityToBuy) {
throw new OperationException("Operation is impossible, not enough quantity of: "
+ fruit);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the OperationException class is defined in your project. If not, you need to create this custom exception class to handle operation-related errors appropriately.

}
Storage.fruitsStorage.put(fruit, quantity - quantityToBuy);
}
}
13 changes: 13 additions & 0 deletions src/main/java/core/basesyntax/strategy/ReturnOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package core.basesyntax.strategy;

import core.basesyntax.db.Storage;
import core.basesyntax.model.ShopOperation;

public class ReturnOperation implements OperationHandler {
@Override
public void handle(ShopOperation shopOperation) {
String fruit = shopOperation.getFruit();
int quantity = Storage.fruitsStorage.get(fruit);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a check to handle cases where the fruit is not present in the fruitsStorage. This will prevent potential NullPointerException if a return operation is attempted for a fruit not in storage.

Storage.fruitsStorage.put(fruit, quantity + shopOperation.getQuantity());
}
}
13 changes: 13 additions & 0 deletions src/main/java/core/basesyntax/strategy/SupplyOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package core.basesyntax.strategy;

import core.basesyntax.db.Storage;
import core.basesyntax.model.ShopOperation;

public class SupplyOperation implements OperationHandler {
@Override
public void handle(ShopOperation shopOperation) {
String fruit = shopOperation.getFruit();
int quantity = Storage.fruitsStorage.get(fruit);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a check to handle cases where the fruit is not present in the fruitsStorage. This will prevent potential NullPointerException if a supply operation is attempted for a fruit not in storage.

Storage.fruitsStorage.put(fruit, quantity + shopOperation.getQuantity());
}
}
Loading
Loading