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 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 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()); fileRepository.save(copyFromDto(file, fileDataDto)); return file; } @Transactional public FileData create(FileDataDto fileDataDto) throws IOException { FileData newFile = null; newFile = createFileFromTmp(fileDataDto.getTmpFileName()); copyFromDto(newFile, fileDataDto); newFile = fileRepository.save(newFile); return newFile; } private FileData copyFromDto(FileData fileData, FileDataDto fileDataDto) { fileData.setName(fileDataDto.getName()); 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)); } }