From 5a79d038eb9f835499a897b649a7c9de04a75416 Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Tue, 9 Jan 2024 00:55:04 +0300 Subject: [PATCH] Save Authors and Genres to DB during parsing --- .../marinesco/data/AuthorRepository.java | 6 +- .../ru/redrise/marinesco/library/Author.java | 2 - .../ru/redrise/marinesco/library/Genre.java | 3 + .../redrise/marinesco/library/InpEntry.java | 137 ++++++++++-------- .../marinesco/library/InpFileScanner.java | 36 ----- .../marinesco/library/InpxScanner.java | 55 +++++-- 6 files changed, 125 insertions(+), 114 deletions(-) delete mode 100644 src/main/java/ru/redrise/marinesco/library/InpFileScanner.java diff --git a/src/main/java/ru/redrise/marinesco/data/AuthorRepository.java b/src/main/java/ru/redrise/marinesco/data/AuthorRepository.java index f540035..23f23a4 100644 --- a/src/main/java/ru/redrise/marinesco/data/AuthorRepository.java +++ b/src/main/java/ru/redrise/marinesco/data/AuthorRepository.java @@ -1,11 +1,15 @@ package ru.redrise.marinesco.data; +import java.util.Optional; + import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; import ru.redrise.marinesco.library.Author; + @Repository -public interface AuthorRepository extends CrudRepository{ +public interface AuthorRepository extends CrudRepository{ + Optional findByAuthorName(String authorName); } diff --git a/src/main/java/ru/redrise/marinesco/library/Author.java b/src/main/java/ru/redrise/marinesco/library/Author.java index 72a5368..de61dc2 100644 --- a/src/main/java/ru/redrise/marinesco/library/Author.java +++ b/src/main/java/ru/redrise/marinesco/library/Author.java @@ -6,14 +6,12 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import lombok.AccessLevel; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @Entity @NoArgsConstructor(access = AccessLevel.PRIVATE, force = true) -@AllArgsConstructor public class Author { // private static final long serialVersionUID = 1L; diff --git a/src/main/java/ru/redrise/marinesco/library/Genre.java b/src/main/java/ru/redrise/marinesco/library/Genre.java index 0d4f13d..2810680 100644 --- a/src/main/java/ru/redrise/marinesco/library/Genre.java +++ b/src/main/java/ru/redrise/marinesco/library/Genre.java @@ -2,10 +2,13 @@ package ru.redrise.marinesco.library; import jakarta.persistence.Entity; import jakarta.persistence.Id; +import lombok.AccessLevel; import lombok.Data; +import lombok.NoArgsConstructor; @Data @Entity +@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true) public class Genre { @Id private String genreId; diff --git a/src/main/java/ru/redrise/marinesco/library/InpEntry.java b/src/main/java/ru/redrise/marinesco/library/InpEntry.java index 7fe8d95..559c5c6 100644 --- a/src/main/java/ru/redrise/marinesco/library/InpEntry.java +++ b/src/main/java/ru/redrise/marinesco/library/InpEntry.java @@ -14,6 +14,8 @@ import jakarta.persistence.Transient; import lombok.Data; import lombok.extern.slf4j.Slf4j; import ru.redrise.marinesco.RainbowDump; +import ru.redrise.marinesco.data.AuthorRepository; +import ru.redrise.marinesco.data.GenreRepository; @Slf4j @Entity @@ -22,9 +24,9 @@ public class InpEntry { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; - + @ManyToMany - private List authors; // Surname,name,by-father + private List authors; // Surname,name,by-father @ManyToMany private List genres; private String title; @@ -37,85 +39,96 @@ public class InpEntry { private String fileExtension; // - concatenate to fsFileName private LocalDate addedDate; private String container; - - @Transient - private int position; - public InpEntry(byte[] line, String container) throws Exception{ + @Transient + private int position = 0; + @Transient + private byte[] line; + + public InpEntry(byte[] line, + String container, + AuthorRepository authorRepository, + GenreRepository genreRepository) throws Exception { // AUTHOR;GENRE;TITLE;SERIES;SERNO;FILE;SIZE;LIBID;DEL;EXT;DATE; - this.container = container; + this.line = line; + this.container = container + ".zip"; this.authors = new ArrayList<>(); this.genres = new ArrayList<>(); - parseAuthors(line); - parseGenere(line); - this.title = parseNextString(line); - this.series = parseNextString(line); - this.serNo = parseNextString(line); - this.fsFileName = parseNextString(line); - this.fileSize = parseNextString(line); - this.libId = parseNextString(line); - this.deleted = parseNextString(line); - this.fileExtension = parseNextString(line); - this.addedDate = LocalDate.parse(parseNextString(line)); + parseAuthors(authorRepository); + parseGenere(genreRepository); + this.title = parseNextString(); + this.series = parseNextString(); + this.serNo = parseNextString(); + this.fsFileName = parseNextString(); + this.fileSize = parseNextString(); + this.libId = parseNextString(); + this.deleted = parseNextString(); + this.fileExtension = parseNextString(); + this.addedDate = LocalDate.parse(parseNextString()); - /* - for (Author author : authors) - log.info(author.getAuthorName()); - for (Genre gen : genres) - log.info(gen.getGenreId()); - - log.info(title); - log.info(series); - log.info(serNo); - log.info(fsFileName); - log.info(fileSize); - log.info(libId); - log.info(deleted); - log.info(fileExtension); - log.info(addedDate.toString()); - - log.info("-----------------"); - //*/ + /* + * for (Author author : authors) + * log.info(author.getAuthorName()); + * for (Genre gen : genres) + * log.info(gen.getGenreId()); + * + * log.info(title); + * log.info(series); + * log.info(serNo); + * log.info(fsFileName); + * log.info(fileSize); + * log.info(libId); + * log.info(deleted); + * log.info(fileExtension); + * log.info(addedDate.toString()); + * + * log.info("-----------------"); + * // + */ } - private void parseAuthors(byte[] line) throws Exception{ - for (int i = 0; i < line.length; i++){ - if (line[i] == 0x04){ - splitAuthors(new String(line, 0, i, StandardCharsets.UTF_8)); - position = i+1; + + private void parseAuthors(AuthorRepository authorRepository) throws Exception { + for (; position < line.length; position++) { + if (line[position] == 0x04) { + String allAuthors = new String(line, 0, position, StandardCharsets.UTF_8); + + for (String authorName : allAuthors.split(":")) { + Author author = authorRepository.findByAuthorName(authorName).orElse(new Author(authorName)); + + authors.add(authorRepository.save(author)); + } + + ++position; return; } } - + RainbowDump.hexDumpUTF8(line); throw new Exception("Invalid 'inp' file format (parse Authors)"); } - private void splitAuthors(String allAuthors){ - for (String author : allAuthors.split(":")){ - authors.add(new Author(author)); - } - } - private void parseGenere(byte[] line) throws Exception{ - for (int i = position; i < line.length; i++){ - if (line[i] == 0x04){ - splitGenres(new String(line, 0, i, StandardCharsets.UTF_8)); - position = i+1; + private void parseGenere(GenreRepository genreRepository) throws Exception { + for (int i = position; i < line.length; i++) { + if (line[i] == 0x04) { + String allGenres = new String(line, position, i - position, StandardCharsets.UTF_8); + + for (String genreName : allGenres.split(":")) { + Genre genre = new Genre(genreName); + genres.add(genreRepository.save(genre)); + } + + position = i + 1; return; } } RainbowDump.hexDumpUTF8(line); throw new Exception("Invalid 'inp' file format (parse Genere)"); } - private void splitGenres(String allGenres){ - for (String genre : allGenres.split(":")){ - genres.add(new Genre(genre)); - } - } - private String parseNextString(byte[] line) throws Exception{ - for (int i = position; i < line.length; i++){ - if (line[i] == 0x04){ - String resultingString = new String(line, position, i-position, StandardCharsets.UTF_8); - position = i+1; + private String parseNextString() throws Exception { + for (int i = position; i < line.length; i++) { + if (line[i] == 0x04) { + String resultingString = new String(line, position, i - position, StandardCharsets.UTF_8); + position = i + 1; return resultingString; } } diff --git a/src/main/java/ru/redrise/marinesco/library/InpFileScanner.java b/src/main/java/ru/redrise/marinesco/library/InpFileScanner.java deleted file mode 100644 index 36c41be..0000000 --- a/src/main/java/ru/redrise/marinesco/library/InpFileScanner.java +++ /dev/null @@ -1,36 +0,0 @@ -package ru.redrise.marinesco.library; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class InpFileScanner { - private String name; - - public InpFileScanner(byte[] content, String name) throws Exception{ - this.name = name.substring(0, name.lastIndexOf('.')); - log.info("FILE RELATED "+this.name); - parseContent(content); - } - - private void parseContent(byte[] content) throws Exception{ - int lastIndex = 0; - for (int i = 0; i < content.length; i++){ - if (content[i] == '\n'){ - byte[] line = new byte[i-lastIndex]; - System.arraycopy(content, lastIndex, line, 0, i-lastIndex-1); - new InpEntry(line, name); - //RainbowDump.hexDumpUTF8(line); - - if (isNextCarriageReturn(i, content)){ - i += 2; - lastIndex = i; - } - else - lastIndex = ++i; - } - } - } - private boolean isNextCarriageReturn(int i, byte[] content) { - return i + 1 < content.length && (content[i + 1] == '\r'); - } -} diff --git a/src/main/java/ru/redrise/marinesco/library/InpxScanner.java b/src/main/java/ru/redrise/marinesco/library/InpxScanner.java index 0b687c2..fe2812f 100644 --- a/src/main/java/ru/redrise/marinesco/library/InpxScanner.java +++ b/src/main/java/ru/redrise/marinesco/library/InpxScanner.java @@ -54,6 +54,7 @@ public class InpxScanner { try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(inpxFile))) { ZipEntry zipEntry = zipInputStream.getNextEntry(); + while (zipEntry != null) { if (zipEntry.isDirectory()) { zipEntry = zipInputStream.getNextEntry(); @@ -63,17 +64,19 @@ public class InpxScanner { if (zipEntry.getName().toLowerCase().contains("collection.info")) libraryMetadata.setCollectionInfo(readPlainText(zipInputStream)); - if (zipEntry.getName().toLowerCase().contains("version.info")) + else if (zipEntry.getName().toLowerCase().contains("version.info")) libraryMetadata.setVersionInfo(readPlainText(zipInputStream)); - if (zipEntry.getName().toLowerCase().endsWith(".inp")) { - /* - if (breaker) { - zipEntry = zipInputStream.getNextEntry(); - continue; - } - breaker = true;// */ - parseInp(zipInputStream, zipEntry.getSize(), zipEntry.getName()); + else if (zipEntry.getName().toLowerCase().endsWith(".inp")) { + //* + if (breaker) { + zipEntry = zipInputStream.getNextEntry(); + continue; + } + breaker = true;// + //*/ + byte[] content = inpToByteArray(zipInputStream, zipEntry.getSize()); + parseInpContent(content, zipEntry.getName()); } zipEntry = zipInputStream.getNextEntry(); @@ -92,7 +95,7 @@ public class InpxScanner { return stringBuilder.toString(); } - private void parseInp(ZipInputStream stream, long fileSize, String fileName) throws Exception { + private byte[] inpToByteArray(ZipInputStream stream, long fileSize) throws Exception { ByteBuffer inpByteBuffer = ByteBuffer.allocate((int) fileSize); int blockSize = 0x200; if (fileSize < 0x200) @@ -113,9 +116,35 @@ public class InpxScanner { block = new byte[blockSize]; } } - // TODO : FIX! - //inpFileRepository.save(new InpFile(inpByteBuffer.array(), fileName)); - new InpFileScanner(inpByteBuffer.array(), fileName); + return inpByteBuffer.array(); + } + + private void parseInpContent(byte[] content, String name) throws Exception { + name = name.substring(0, name.lastIndexOf('.')); + + log.info("FILE RELATED " + name); + int lastIndex = 0; + for (int i = 0; i < content.length; i++) { + if (content[i] == '\n') { + byte[] line = new byte[i - lastIndex]; + System.arraycopy(content, lastIndex, line, 0, i - lastIndex - 1); + + InpEntry book = new InpEntry(line, name, authorRepository, genreRepository); + //inpEntryRepository.save(book); + + // RainbowDump.hexDumpUTF8(line); + + if (isNextCarriageReturn(i, content)) { + i += 2; + lastIndex = i; + } else + lastIndex = ++i; + } + } + } + + private boolean isNextCarriageReturn(int i, byte[] content) { + return i + 1 < content.length && (content[i + 1] == '\r'); } public String getFilesLocation() {