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

create fruit shop #1229

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,42 @@ public class FruitTransaction {
}
```

Also, here is an example of what the `main` method may look like:
```java
public class Main {
public static void main(String[] arg) {
// 1. Read the data from the input CSV file
FileReader fileReader = new FileReaderImpl();
List<String> inputReport = fileReader.read("reportToRead.csv");

// 2. Convert the incoming data into FruitTransactions list
DataConverter dataConverter = new DataConverterImpl();
List<FruitTransaction> transactions = dataConverter.convertToTransaction(inputReport);

// 3. Create and feel the map with all OperationHandler implementations
Map<FruitTransaction.Operation, OperationHandler> operationHandlers = new HashMap<>();
operationHandlers.put(FruitTransaction.Operation.BALANCE, new BalanceOperation());
operationHandlers.put(FruitTransaction.Operation.PURCHASE, new PurchaseOperation());
operationHandlers.put(FruitTransaction.Operation.RETURN, new ReturnOperation());
operationHandlers.put(FruitTransaction.Operation.SUPPLY, new SupplyOperation());
OperationStrategy operationStrategy = new OperationStrategyImpl(operationHandlers);

// 4. Process the incoming transactions with applicable OperationHandler implementations
ShopService shopService = new ShopServiceImpl(operationStrategy);
shopService.process(transactions);

// 5.Generate report based on the current Storage state
ReportGenerator reportGenerator = new ReportGeneratorImpl();
String resultingReport = reportGenerator.getReport();

// 6. Write the received report into the destination file
FileWriter fileWriter = new FileWriterImpl();
fileWriter.write(resultingReport, "finalReport.csv");
}
}
```


#### [Try to avoid these common mistakes while solving task](./checklist.md)

<details>
Expand Down
9 changes: 0 additions & 9 deletions src/main/java/core/basesyntax/HelloWorld.java

This file was deleted.

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

import core.basesyntax.file.DataConverter;
import core.basesyntax.file.DataConverterImpl;
import core.basesyntax.file.FileReader;
import core.basesyntax.file.FileReaderImpl;
import core.basesyntax.file.FileWriter;
import core.basesyntax.file.FileWriterImpl;
import core.basesyntax.service.FruitTransaction;
import core.basesyntax.service.ReportGenerator;
import core.basesyntax.service.ReportGeneratorImpl;
import core.basesyntax.service.ShopService;
import core.basesyntax.service.ShopServiceImpl;
import core.basesyntax.strategy.BalanceOperation;
import core.basesyntax.strategy.OperationHandler;
import core.basesyntax.strategy.OperationStrategy;
import core.basesyntax.strategy.OperationStrategyImpl;
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 {
public static void main(String[] args) {
// 1. Read the data from the input CSV file
FileReader fileReader = new FileReaderImpl();
List<String> inputReport = fileReader.read(
"src/main/java/core/basesyntax/reportToRead.csv");
Comment on lines +29 to +30

Choose a reason for hiding this comment

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

Ensure that the file path is correct and that the file exists to avoid runtime errors. Consider adding error handling for file reading operations.

Comment on lines +29 to +30

Choose a reason for hiding this comment

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

Verify that the file path 'src/main/java/core/basesyntax/reportToRead.csv' is correct and that the file exists at this location. Otherwise, the FileReader may throw an error.


// 2. Convert the incoming data into FruitTransactions list

Choose a reason for hiding this comment

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

It seems like the step to convert the incoming data into a list of FruitTransaction objects is missing. Ensure that you implement this step using the DataConverter instance.


// 3. Create and feel the map with all OperationHandler implementations
Map<FruitTransaction.Operation, OperationHandler> operationHandlers = new HashMap<>();
OperationStrategy operationStrategy = new OperationStrategyImpl(operationHandlers);
ShopService shopService = new ShopServiceImpl(operationStrategy);
operationHandlers.put(FruitTransaction.Operation.BALANCE,
new BalanceOperation(shopService));
operationHandlers.put(FruitTransaction.Operation.PURCHASE,
new PurchaseOperation(shopService));
operationHandlers.put(FruitTransaction.Operation.RETURN,
new ReturnOperation(shopService));
operationHandlers.put(FruitTransaction.Operation.SUPPLY,
new SupplyOperation(shopService));

// 4. Process the incoming transactions with applicable OperationHandler implementations
DataConverter dataConverter = new DataConverterImpl();
List<FruitTransaction> transactions = dataConverter.convertToTransaction(inputReport);

Choose a reason for hiding this comment

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

Ensure that the convertToTransaction method correctly handles any potential formatting issues in the input data to avoid runtime exceptions.

shopService.process(transactions);

// 5.Generate report based on the current Storage state
ReportGenerator reportGenerator = new ReportGeneratorImpl();
String resultingReport = reportGenerator.getReport(shopService);

// 6. Write the received report into the destination file
FileWriter fileWriter = new FileWriterImpl();
fileWriter.write(resultingReport, "src/main/java/core/basesyntax/finalReport.csv");

Choose a reason for hiding this comment

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

Verify that the file path 'src/main/java/core/basesyntax/finalReport.csv' is correct and that you have write permissions to this location. Otherwise, the FileWriter may throw an error.

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

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

public interface DataConverter {
List<FruitTransaction> convertToTransaction(List<String> inputReport);
}
34 changes: 34 additions & 0 deletions src/main/java/core/basesyntax/file/DataConverterImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package core.basesyntax.file;

import core.basesyntax.service.FruitTransaction;
import java.util.ArrayList;
import java.util.List;

public class DataConverterImpl implements DataConverter {
@Override
public List<FruitTransaction> convertToTransaction(List<String> inputReport) {
List<FruitTransaction> transactions = new ArrayList<>();
for (String line : inputReport) {
if (line.startsWith("type")) {
continue;
}
String[] parts = line.split(",");

Choose a reason for hiding this comment

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

Consider adding validation to check if the parts array has the expected number of elements before accessing them. This will prevent ArrayIndexOutOfBoundsException if the input data is malformed.

String operationCode = parts[0];
String fruit = parts[1];
int quantity = Integer.parseInt(parts[2]);

Choose a reason for hiding this comment

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

Add error handling for Integer.parseInt(parts[2]) to catch NumberFormatException in case 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[2]) to manage cases where the quantity is not a valid integer. This will prevent the application from crashing due to malformed input data.

FruitTransaction.Operation operation = getOperationFromCode(operationCode);
transactions.add(new FruitTransaction(operation, fruit, quantity));
}
return transactions;
}

private FruitTransaction.Operation getOperationFromCode(String code) {
for (FruitTransaction.Operation operation : FruitTransaction.Operation.values()) {
if (operation.getCode().equals(code)) {
return operation;
}
}
throw new IllegalArgumentException("Invalid operation code: " + code);

Choose a reason for hiding this comment

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

The method getOperationFromCode throws an IllegalArgumentException for invalid operation codes. Ensure that this exception is handled appropriately in the calling code to prevent the application from crashing.

Choose a reason for hiding this comment

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

Throwing an IllegalArgumentException is appropriate here, but consider providing more context in the error message, such as the line number or content, to aid in debugging.


}
}
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);
}
17 changes: 17 additions & 0 deletions src/main/java/core/basesyntax/file/FileReaderImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package core.basesyntax.file;

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

public class FileReaderImpl implements FileReader {
@Override
public List<String> read(String filePath) {
try {
return Files.readAllLines(Paths.get(filePath));
} catch (IOException e) {
throw new RuntimeException("Can't read file at " + filePath,e);

Choose a reason for hiding this comment

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

Throwing a RuntimeException for an IOException might not be the best approach as it can terminate the application abruptly. Consider using a custom exception or handling the error more gracefully to provide better feedback to the user.

}
}
}
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 resultingReport, String filePath);
}
18 changes: 18 additions & 0 deletions src/main/java/core/basesyntax/file/FileWriterImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package core.basesyntax.file;

import java.io.BufferedWriter;
import java.io.IOException;

public class FileWriterImpl implements FileWriter {
@Override
public void write(String resultingReport, String filePath) {
try (BufferedWriter bufferedWriter =
new BufferedWriter(new java.io.FileWriter(filePath, false))) {
bufferedWriter.write(resultingReport);
bufferedWriter.newLine();
} catch (IOException e) {
throw new RuntimeException("Can't write data to file", e);

Choose a reason for hiding this comment

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

Throwing a RuntimeException for an IOException might not be the best approach as it can terminate the application abruptly. Consider using a custom exception or handling the error more gracefully to provide better feedback to the user.

}

}
}
9 changes: 9 additions & 0 deletions src/main/java/core/basesyntax/reportToRead.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type,fruit,quantity
b,banana,20
b,apple,100
s,banana,100
p,banana,13
r,apple,10
p,apple,20
p,banana,5
s,banana,50
54 changes: 54 additions & 0 deletions src/main/java/core/basesyntax/service/FruitTransaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package core.basesyntax.service;

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

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

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;
}

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

private String code;

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

public String getCode() {
return code;
}
}
}
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(ShopService shopService);
}
18 changes: 18 additions & 0 deletions src/main/java/core/basesyntax/service/ReportGeneratorImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package core.basesyntax.service;

import java.util.Map;

public class ReportGeneratorImpl implements ReportGenerator {

@Override
public String getReport(ShopService shopService) {
StringBuilder stringBuilder = new StringBuilder("fruit,quantity \n");
for (Map.Entry<String, Integer> entry: shopService.getFruits().entrySet()) {
stringBuilder.append(entry.getKey())
.append(",")
.append(entry.getValue())
.append("\n");
}
return stringBuilder.toString();
}
}
14 changes: 14 additions & 0 deletions src/main/java/core/basesyntax/service/ShopService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package core.basesyntax.service;

import java.util.List;
import java.util.Map;

public interface ShopService {
void process(List<FruitTransaction> transactions);

void addFruits(String fruit, int quantity);

int getQuantity(String fruit);

Map<String, Integer> getFruits();
}
37 changes: 37 additions & 0 deletions src/main/java/core/basesyntax/service/ShopServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package core.basesyntax.service;

import core.basesyntax.strategy.OperationStrategy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ShopServiceImpl implements ShopService {
private OperationStrategy operationStrategy;
private Map<String, Integer> fruits = new HashMap<>();

Choose a reason for hiding this comment

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

Consider using a thread-safe collection like ConcurrentHashMap if this service is intended to be used in a multi-threaded environment.


public ShopServiceImpl(OperationStrategy operationStrategy) {
this.operationStrategy = operationStrategy;
}

@Override
public void process(List<FruitTransaction> transactions) {
for (FruitTransaction transaction : transactions) {
operationStrategy.get(transaction.getOperation()).handle(transaction);

Choose a reason for hiding this comment

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

Ensure that operationStrategy.get(transaction.getOperation()) does not return null. If it does, calling handle(transaction) will result in a NullPointerException. Consider adding a null check or handling this case appropriately.

}
}

@Override
public void addFruits(String fruit, int quantity) {
fruits.put(fruit,fruits.getOrDefault(fruit,0) + quantity);
}

@Override
public int getQuantity(String fruit) {
return fruits.getOrDefault(fruit,0);
}

@Override
public Map<String, Integer> getFruits() {
return fruits;
}
}
23 changes: 23 additions & 0 deletions src/main/java/core/basesyntax/strategy/BalanceOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package core.basesyntax.strategy;

import core.basesyntax.service.FruitTransaction;
import core.basesyntax.service.ShopService;

public class BalanceOperation implements OperationHandler {
private ShopService shopService;

public BalanceOperation(ShopService shopService) {
this.shopService = shopService;
}

@Override
public void handle(FruitTransaction transaction) {
if (transaction.getOperation() == FruitTransaction.Operation.BALANCE) {
String fruit = transaction.getFruit();
int quantity = transaction.getQuantity();
shopService.addFruits(fruit, quantity);
} else {
throw new RuntimeException("Unsupported operation for BalanceHandler");

Choose a reason for hiding this comment

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

Throwing a RuntimeException for unsupported operations might not be the best approach as it can terminate the application abruptly. Consider using a custom exception or handling the error more gracefully to provide better feedback to the user.

}
}
}
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.service.FruitTransaction;

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

import core.basesyntax.service.FruitTransaction;

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