AttachmentServiceImpl.java 5.93 KB
package isa.qa.service.impl;

import isa.qa.core.ServiceException;
import isa.qa.dao.ApplicationDao;
import isa.qa.dao.AttachmentDao;
import isa.qa.dto.response.AttachmentResponseDTO;
import isa.qa.entity.Application;
import isa.qa.entity.Attachment;
import isa.qa.properties.FileProperties;
import isa.qa.properties.JwtProperties;
import isa.qa.service.AttachmentService;
import isa.qa.utils.FileUtils;
import isa.qa.utils.JwtTokenUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import static com.google.common.base.Preconditions.checkArgument;
import static java.io.File.separator;
import static java.util.stream.Collectors.toList;

/**
 * Attachment service implements
 *
 * @author May
 * @version 1.0
 * @date 2018/12/28 16:41
 */
@Service
@AllArgsConstructor
public class AttachmentServiceImpl implements AttachmentService {

    private final FileProperties fileProperties;

    private final AttachmentDao attachmentDao;

    private final ApplicationDao applicationDao;

    private final JwtTokenUtil jwtTokenUtil;

    private final JwtProperties jwtProperties;

    @Override
    @Transactional(rollbackFor = TransactionException.class)
    public AttachmentResponseDTO uploadFile(String accessKey, MultipartFile file) throws IOException {
        String appKey = jwtTokenUtil.getAppKeyFromToken(accessKey.substring(jwtProperties.getTokenHead().length()));

        Application application = applicationDao.findById(appKey).orElseThrow(() -> new ServiceException("Application miss"));

        Date now = Date.from(Instant.now());
        String relativePath = application.getName() + separator;
        String fileName = application.getName() + now.toInstant().toEpochMilli() + FileUtils.getFileSuffix(file.getOriginalFilename());

        Attachment attachment = new Attachment();

        attachment.setSize(file.getSize());
        file.transferTo(new File(fileProperties.getBasePath() + relativePath + fileName));

        attachment.setContentType(file.getContentType());
        attachment.setName(fileName);
        attachment.setOriginalName(file.getOriginalFilename());
        attachment.setRelativePath(relativePath);
        attachment.setAccessUrl(fileProperties.getBaseAccessUrl() + application.getName() + "/" + fileName);
        attachment.setCreateTime(now);
        attachment.setUpdateTime(now);

        attachmentDao.save(attachment);

        return new AttachmentResponseDTO(attachment.getId(), attachment.getName(), attachment.getAccessUrl());
    }

    @Override
    @Transactional(rollbackFor = TransactionException.class)
    public List<AttachmentResponseDTO> uploadFiles(String accessKey, List<MultipartFile> files) throws IOException {
        String appKey = jwtTokenUtil.getAppKeyFromToken(accessKey.substring(jwtProperties.getTokenHead().length()));

        Application application = applicationDao.findById(appKey).orElseThrow(() -> new ServiceException("Application miss"));
        Date now = Date.from(Instant.now());
        String relativePath = application.getName() + separator;

        Integer length = files.size();
        List<Attachment> attachments = new ArrayList<>(length);
        for (int i = 0; i < length; i++) {
            String fileName = application.getName() + now.toInstant().toEpochMilli() + i + FileUtils.getFileSuffix(files.get(i).getOriginalFilename());

            Attachment attachment = new Attachment();
            attachment.setSize(files.get(i).getSize());

            files.get(i).transferTo(new File(fileProperties.getBasePath() + relativePath + fileName));

            attachment.setContentType(files.get(i).getContentType());
            attachment.setName(fileName);
            attachment.setOriginalName(files.get(i).getOriginalFilename());

            attachment.setRelativePath(relativePath);
            attachment.setAccessUrl(fileProperties.getBaseAccessUrl() + application.getName() + "/" + fileName);
            attachment.setCreateTime(now);
            attachment.setUpdateTime(now);

            attachments.add(attachment);
        }

        attachmentDao.saveAll(attachments);

        return attachments.stream().map(attachment -> new AttachmentResponseDTO(attachment.getId(), attachment.getName(), attachment.getAccessUrl())).collect(toList());
    }

    @Override
    @Transactional(rollbackFor = TransactionException.class)
    public boolean deleteFile(String accessKey, String fileName) {
        String appKey = jwtTokenUtil.getAppKeyFromToken(accessKey.substring(jwtProperties.getTokenHead().length()));
        Attachment attachment = attachmentDao.findByName(fileName).orElseThrow(() -> new ServiceException("File not found"));

        Application application = applicationDao.findById(appKey).orElseThrow(() -> new ServiceException("Application miss"));

        checkArgument(Objects.equals(attachment.getRelativePath().replace(separator, ""), application.getName()), "Can't remove the other application's attachment");

        String filePath = fileProperties.getBasePath() + attachment.getRelativePath() + attachment.getName();
        boolean result = FileUtils.delFile(filePath);

        attachmentDao.delete(attachment);

        return result;
    }

    @Override
    @Transactional(rollbackFor = TransactionException.class)
    public boolean deleteFile(String fileName) {
        Attachment attachment = attachmentDao.findByName(fileName).orElseThrow(() -> new ServiceException("File not found"));

        String filePath = fileProperties.getBasePath() + attachment.getRelativePath() + attachment.getName();
        boolean result = FileUtils.delFile(filePath);

        attachmentDao.delete(attachment);

        return result;
    }

}