diff --git a/pom.xml b/pom.xml
index effc1bd..aa4cb24 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,6 +21,11 @@
1.18.34
provided
+
+ net.datafaker
+ datafaker
+ 2.3.0
+
org.junit.jupiter
junit-jupiter
diff --git a/src/main/java/org/writer/Main.java b/src/main/java/org/writer/Main.java
index 40e8213..ba0bd43 100644
--- a/src/main/java/org/writer/Main.java
+++ b/src/main/java/org/writer/Main.java
@@ -1,7 +1,30 @@
package org.writer;
+import net.datafaker.Faker;
+import org.writer.model.Months;
+import org.writer.model.Person;
+import org.writer.model.Student;
+
+import java.util.ArrayList;
+import java.util.List;
+
public class Main {
public static void main(String[] args) {
- System.out.println("Hello world!");
+ Faker faker = new Faker();
+ WritableImpl writableImpl = new WritableImpl();
+
+ List students = new ArrayList<>();
+ for (int i = 0; i < 5; i++) {
+ students.add(new Student(faker.name().firstName(), List.of(faker.size().adjective(), faker.size().adjective())));
+ }
+ writableImpl.writeToFile(students, "output.csv");
+
+
+ List persons = new ArrayList<>();
+ for (int i = 0; i < 5; i++) {
+ persons.add(new Person(faker.name().firstName(), faker.name().lastName(), 22, Months.APRIL, 1094));
+ }
+ writableImpl.writeToFile(persons, "output.csv");
+
}
}
\ No newline at end of file
diff --git a/src/main/java/org/writer/WritableImpl.java b/src/main/java/org/writer/WritableImpl.java
new file mode 100644
index 0000000..7005b62
--- /dev/null
+++ b/src/main/java/org/writer/WritableImpl.java
@@ -0,0 +1,86 @@
+package org.writer;
+
+import org.writer.exception.AccessFileException;
+import org.writer.exception.InvalidDataException;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+/**
+ * Класс реализации записи данных в файл в формате CSV
+ */
+
+public class WritableImpl implements Writable {
+ private final Logger logger = Logger.getLogger(WritableImpl.class.getName());
+ private final StringBuilder stringBuilder = new StringBuilder();
+
+
+ /**
+ * Вадидация входных даннных
+ * @param data - список обьектов
+ * @param fileName - имя файла для записи
+ * @throws InvalidDataException - бросает исключение
+ */
+ @Override
+ public void writeToFile(List> data, String fileName) {
+ if (validateMethod(data, fileName)) {
+ try (FileWriter fw = new FileWriter(fileName))
+ {
+ for (Object object : data) {
+ Class> aClass = object.getClass();
+ Field[] fields = aClass.getDeclaredFields();
+ for (Field field : fields) {
+ field.setAccessible(true);
+ Object valueField = field.get(object);
+ resolveFieldClass(valueField);
+ }
+ }
+ if (!stringBuilder.isEmpty()) {
+ stringBuilder.setLength(stringBuilder.length() - 1);
+ }
+ fw.write(stringBuilder.toString());
+ } catch (IllegalAccessException e) {
+ throw new InvalidDataException("Invalid data!");
+ } catch (IOException e) {
+ throw new AccessFileException("Access file error!");
+ }
+ } else {
+ throw new InvalidDataException("Invalid data!");
+ }
+ }
+
+ /**
+ * Вадидация входных даннных
+ * @param data - список обьектов
+ * @param fileName - имя файла для записи
+ */
+ private boolean validateMethod(List> data, String fileName) {
+ if (data == null || fileName == null) {
+ logger.warning("Data or File Name is null!");
+ return false;
+ } else if (data.isEmpty() || fileName.isEmpty()) {
+ logger.warning("Data or File Name is empty!");
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Проверка типа поля и заполнение stringbuilder
+ * @param valueField - поле обьекта
+ */
+ private void resolveFieldClass (Object valueField) {
+ if (valueField instanceof Collection) {
+ String collect = ((Collection>) valueField).stream().map(value -> value.toString()).collect(Collectors.joining("|"));
+ stringBuilder.append(collect).append(',');
+ } else {
+ stringBuilder.append(valueField).append(',');
+ }
+ }
+}
diff --git a/src/main/java/org/writer/exception/AccessFileException.java b/src/main/java/org/writer/exception/AccessFileException.java
new file mode 100644
index 0000000..ce6c44f
--- /dev/null
+++ b/src/main/java/org/writer/exception/AccessFileException.java
@@ -0,0 +1,10 @@
+package org.writer.exception;
+
+public class AccessFileException extends RuntimeException {
+ public AccessFileException(String message) {
+ super(message);
+ }
+ public AccessFileException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/org/writer/exception/InvalidDataException.java b/src/main/java/org/writer/exception/InvalidDataException.java
new file mode 100644
index 0000000..1da1e87
--- /dev/null
+++ b/src/main/java/org/writer/exception/InvalidDataException.java
@@ -0,0 +1,11 @@
+package org.writer.exception;
+
+public class InvalidDataException extends RuntimeException {
+
+ public InvalidDataException(String message) {
+ super(message);
+ }
+ public InvalidDataException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/org/writer/model/Months.java b/src/main/java/org/writer/model/Months.java
index cb7b9c1..b9e6b93 100644
--- a/src/main/java/org/writer/model/Months.java
+++ b/src/main/java/org/writer/model/Months.java
@@ -1,5 +1,9 @@
package org.writer.model;
+/**
+ * Enum с именами месяцев в году.
+ */
+
public enum Months {
JANUARY,
FEBRUARY,
diff --git a/src/main/java/org/writer/model/Person.java b/src/main/java/org/writer/model/Person.java
index ba8576b..d730d58 100644
--- a/src/main/java/org/writer/model/Person.java
+++ b/src/main/java/org/writer/model/Person.java
@@ -4,19 +4,26 @@
import lombok.Builder;
import lombok.Data;
+/**
+ * Класс сущности Person
+ */
+
@Data
@Builder
@AllArgsConstructor
public class Person {
-
+ /** Поле имя */
private String firstName;
+ /** Поле фамилия */
private String lastName;
+ /** Поле дата рождения */
private int dayOfBirth;
+ /** Поле месяц рождения */
private Months monthOfBirth;
+ /** Поле год рождения */
private int yearOfBirth;
-
}
diff --git a/src/main/java/org/writer/model/Student.java b/src/main/java/org/writer/model/Student.java
index 2b549c4..c81c6c0 100644
--- a/src/main/java/org/writer/model/Student.java
+++ b/src/main/java/org/writer/model/Student.java
@@ -6,12 +6,16 @@
import java.util.List;
+/**
+ * Класс сущности Student
+ */
+
@Data
@Builder
@AllArgsConstructor
public class Student {
-
+ /** Поле имя */
private String name;
-
+ /** Поле счета, представляет из себя список String */
private List score;
}
\ No newline at end of file
diff --git a/src/test/java/UnitTests/CSVWriterTest.java b/src/test/java/UnitTests/CSVWriterTest.java
new file mode 100644
index 0000000..6f687ef
--- /dev/null
+++ b/src/test/java/UnitTests/CSVWriterTest.java
@@ -0,0 +1,86 @@
+package UnitTests;
+
+
+import net.datafaker.Faker;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.writer.WritableImpl;
+import org.writer.exception.InvalidDataException;
+import org.writer.model.Months;
+import org.writer.model.Person;
+import org.writer.model.Student;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+class CSVWriterTest {
+ private final Faker faker = new Faker();
+ private final WritableImpl writable = new WritableImpl();
+ private final List persons = new ArrayList<>();
+ private final List students = new ArrayList<>();
+ private final String fileName = "output.csv";
+
+
+ @BeforeEach
+ void setUp() {
+ for (int i = 0; i < 5; i++) {
+ persons.add(new Person(faker.name().firstName(), faker.name().lastName(), 22, Months.APRIL, 1094));
+ }
+ persons.add(new Person("Egor", "Fillipov", 22, Months.APRIL, 1094));
+
+
+ for (int i = 0; i < 5; i++) {
+ students.add(new Student(faker.name().firstName(), List.of(faker.size().adjective(), faker.size().adjective())));
+ }
+ students.add(new Student("Egor", List.of("129", "200")));
+ }
+
+ @AfterEach
+ void tearDown() {
+ persons.clear();
+ students.clear();
+ }
+
+
+ @Test
+ void validPersonsWriteTest() throws IOException {
+ writable.writeToFile(persons, fileName);
+ Assertions.assertDoesNotThrow(() -> {});
+ FileReader fileReader = new FileReader(fileName);
+ BufferedReader bufferedReader = new BufferedReader(fileReader);
+ String s = bufferedReader.readLine();
+ Assertions.assertNotNull(s);
+ Assertions.assertTrue(s.contains("Egor"));
+ }
+
+ @Test
+ void validStudentsWriteTest() throws IOException {
+ writable.writeToFile(students, fileName);
+ Assertions.assertDoesNotThrow(() -> {});
+ FileReader fileReader = new FileReader(fileName);
+ BufferedReader bufferedReader = new BufferedReader(fileReader);
+ String s = bufferedReader.readLine();
+ Assertions.assertNotNull(s);
+ Assertions.assertTrue(s.contains("Egor"));
+ }
+
+ @Test
+ void invalidPersonsWriteTest() {
+ Assertions.assertThrows(InvalidDataException.class, () -> writable.writeToFile(null, fileName));
+ }
+
+ @Test
+ void invalidStudentsWriteTest() {
+ Assertions.assertThrows(InvalidDataException.class, () -> writable.writeToFile(null, fileName));
+ }
+
+ @Test
+ void invalidFileNameTest() {
+ Assertions.assertThrows(InvalidDataException.class, () -> writable.writeToFile(persons, null));
+ }
+}