package ru.ulstu.file.service; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import ru.ulstu.file.model.FileData; import ru.ulstu.file.model.FileDataDto; import ru.ulstu.file.repostory.FileRepository; import ru.ulstu.paper.model.PaperDto; import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; import static java.nio.charset.StandardCharsets.UTF_8; @Service public class FileService { private final static int META_FILE_NAME_INDEX = 0; private final static int META_FILE_SIZE_INDEX = 1; private String tmpDir; private FileRepository fileRepository; public FileService(FileRepository fileRepository) { tmpDir = System.getProperty("java.io.tmpdir"); this.fileRepository = fileRepository; } public FileData createFileFromTmp(String tmpFileName) throws IOException { FileData fileData = new FileData(); fileData.setData(getTmpFile(tmpFileName)); fileData.setSize(getTmpFileSize(tmpFileName)); fileData.setCreateDate(new Date()); return fileRepository.save(fileData); } public String uploadToTmpDir(MultipartFile multipartFile) throws IOException { String tmpFileName = String.valueOf(System.currentTimeMillis()) + UUID.randomUUID(); Files.write(getTmpFilePath(tmpFileName), multipartFile.getBytes()); String meta = multipartFile.getOriginalFilename() + "\n" + multipartFile.getSize(); Files.write(getTmpFileMetaPath(tmpFileName), meta.getBytes(UTF_8)); return tmpFileName; } private String[] getMeta(String tmpFileName) throws IOException { return new String(Files.readAllBytes(getTmpFileMetaPath(tmpFileName)), UTF_8) .split("\n"); } public long getTmpFileSize(String tmpFileName) throws IOException { return Long.valueOf(getMeta(tmpFileName)[META_FILE_SIZE_INDEX]).longValue(); } public String getTmpFileName(String tmpFileName) throws IOException { return getMeta(tmpFileName)[META_FILE_NAME_INDEX]; } public byte[] getTmpFile(String tmpFileName) throws IOException { return Files.readAllBytes(getTmpFilePath(tmpFileName)); } public FileData getFile(Integer fileId) { return fileRepository.findOne(fileId); } public void deleteTmpFile(String tmpFileName) throws IOException { Files.delete(getTmpFilePath(tmpFileName)); } private Path getTmpFilePath(String tmpFileName) { return Paths.get(tmpDir, tmpFileName); } private Path getTmpFileMetaPath(String tmpFileName) { return Paths.get(getTmpFilePath(tmpFileName) + ".meta"); } public void deleteFile(FileData fileData) { fileRepository.delete(fileData); } public List saveOrCreate(List fileDtos) throws IOException { List files = new ArrayList<>(); for (FileDataDto file : fileDtos) { files.add(file.getId() != null ? update(file) : create(file)); } return files; } @Transactional public FileData update(FileDataDto fileDataDto) { FileData file = fileRepository.findOne(fileDataDto.getId()); return fileRepository.save(copyFromDto(file, fileDataDto)); } @Transactional public FileData create(FileDataDto fileDataDto) throws IOException { FileData newFile = createFileFromTmp(fileDataDto.getTmpFileName()); copyFromDto(newFile, fileDataDto); return fileRepository.save(newFile); } private FileData copyFromDto(FileData fileData, FileDataDto fileDataDto) { fileData.setName(fileDataDto.getName()); fileData.setLatexAttach(fileDataDto.isLatexAttach()); return fileData; } @Transactional public void delete(Integer fileId) { fileRepository.delete(fileRepository.findOne(fileId)); } public FileDataDto createFromMultipartFile(MultipartFile multipartFile) throws IOException { return new FileDataDto(multipartFile.getOriginalFilename(), uploadToTmpDir(multipartFile)); } public void createLatexAttachs(PaperDto paper) throws IOException { for (FileDataDto fileDataDto : paper.getFiles() .stream() .filter(f -> (f.isLatexAttach() != null && f.isLatexAttach()) && !f.isDeleted()) .collect(Collectors.toList())) { if (fileDataDto.getId() == null) { File oldFile = getTmpFilePath(fileDataDto.getTmpFileName()).toFile(); File renamed = getTmpFilePath(fileDataDto.getName()).toFile(); oldFile.renameTo(renamed); } else { Files.write(getTmpFilePath(fileDataDto.getName()), fileRepository.findOne(fileDataDto.getId()).getData()); } } } public File createLatexFile(PaperDto paper) throws IOException { BufferedWriter writer = Files.newBufferedWriter(getTmpFilePath(paper.getTitle() + ".tex")); writer.write(paper.getLatexText()); writer.close(); return getTmpFilePath(paper.getTitle() + ".tex").toFile(); } }