Skip to content
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
20 changes: 20 additions & 0 deletions src/main/java/org/writer/Csv.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.writer;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Аннотация для помечания полей,
* которые необходимо сохранять в
* CSV файл
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Csv {
/**
* Имя колонки в CSV файле
*/
String name() default "";
}
22 changes: 21 additions & 1 deletion src/main/java/org/writer/Main.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
package org.writer;

import org.writer.model.Months;
import org.writer.model.Person;
import org.writer.model.Student;

import java.util.List;

public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
Writable writable = new WritableImpl();

List<Student> students = List.of(
new Student("Nick", List.of("5,4,3,3,4")),
new Student("Paul", List.of("4,4,4,4,4")),
new Student("Ann", List.of("5,5,5,5,5"))
);

List<Person> persons = List.of(
new Person("John", "Doe", 1, Months.JANUARY, 1991),
new Person("Alexandr", "Pushkin", 6, Months.JUNE, 1799)
);

writable.writeToFile(students, "students.csv");
writable.writeToFile(persons, "persons.csv");
}
}
67 changes: 67 additions & 0 deletions src/main/java/org/writer/WritableImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.writer;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
* Класс, предназанченный для записи коллекции объектов в CSV-файл
*/
public class WritableImpl implements Writable {

/**
* Метод, для записи коллекуии в файл формата CSV
*
* @param data - коллекция объектов для сохранения
* @param fileName - имя файла, в который будут сохранены данные
*/
@Override
public void writeToFile(List<?> data, String fileName) {
if (data == null || data.isEmpty()) {
throw new IllegalArgumentException("data is null or empty");
}

Class<?> clazz = data.get(0).getClass();
List<Field> fields = fieldsToCsv(clazz);

try (
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(fileName))
) {
fileWriter.write(
fields.stream()
.map(f -> f.getAnnotation(Csv.class).name())
.collect(Collectors.joining(",")));

fileWriter.newLine();

for (Object o : data) {
List<String> values = new ArrayList<>();
for (Field f : o.getClass().getDeclaredFields()) {
if (f.isAnnotationPresent(Csv.class)) {
f.setAccessible(true);
Object val = f.get(o);
if (val != null) {
values.add(val.toString());
}
}
}
fileWriter.write(String.join(",", values));
fileWriter.newLine();
}

} catch (IOException | IllegalAccessException e) {
throw new RuntimeException(e.getMessage());
}
}

private List<Field> fieldsToCsv(Class<?> clazz) {
return Arrays.stream(clazz.getDeclaredFields())
.filter(field -> field.isAnnotationPresent(Csv.class))
.toList();
}
}
6 changes: 5 additions & 1 deletion src/main/java/org/writer/model/Person.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.writer.Csv;

@Data
@Builder
@AllArgsConstructor
public class Person {

private String firstName;

@Csv(name = "lastName")
private String lastName;

@Csv(name = "dayOfBirth")
private int dayOfBirth;

@Csv(name = "monthOfBirth")
private Months monthOfBirth;

@Csv(name = "yearOfBirth")
private int yearOfBirth;

}
3 changes: 3 additions & 0 deletions src/main/java/org/writer/model/Student.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.writer.Csv;

import java.util.List;

Expand All @@ -11,7 +12,9 @@
@AllArgsConstructor
public class Student {

@Csv(name = "name")
private String name;

@Csv(name = "score")
private List<String> score;
}
65 changes: 65 additions & 0 deletions src/test/java/org/writer/WritableImplTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.writer;

import org.junit.jupiter.api.Test;

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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class WritableImplTest {
private final Writable writable = new WritableImpl();

static class TestData{
@Csv(name = "name")
private final String name;
@Csv(name = "age")
private final int age;

private byte ignoredData;

public TestData(String name, int age){
this.name = name;
this.age = age;
}
}

@Test
void testWriteWithNullData() {

assertThrows(IllegalArgumentException.class,
() -> writable.writeToFile(null, "some.csv"));

}

@Test
void testWriteWithEmptyData() {

assertThrows(IllegalArgumentException.class,
() -> writable.writeToFile(new ArrayList<>(), "some.csv"));

}

@Test
void testWriteSuccess() throws IOException {
String fileName = "some.csv";
List<TestData> testData = new ArrayList<>();
testData.add(new TestData("name1", 1));
testData.add(new TestData("name2", 2));
testData.add(new TestData("name3", 3));

writable.writeToFile(testData, fileName);

List<String> lines = Files.readAllLines(Path.of(fileName));

assertEquals(4, lines.size());
assertEquals("name,age", lines.get(0));
assertEquals("name1,1", lines.get(1));
assertEquals("name2,2", lines.get(2));
assertEquals("name3,3", lines.get(3));
}
}