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