diff options
Diffstat (limited to 'src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java')
| -rw-r--r-- | src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java new file mode 100644 index 0000000..2c6e6e9 --- /dev/null +++ b/src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java @@ -0,0 +1,383 @@ +package com.mesasoft.cn.service.impl; + +import com.mesasoft.cn.SketchApplication; +import com.mesasoft.cn.dao.DownloadedDAO; +import com.mesasoft.cn.dao.FileDAO; +import com.mesasoft.cn.util.BeanUtils; +import com.mesasoft.cn.config.SettingConfig; +import com.mesasoft.cn.entity.Category; +import com.mesasoft.cn.entity.File; +import com.mesasoft.cn.entity.User; +import com.mesasoft.cn.model.AuthRecord; +import com.mesasoft.cn.model.BaseAuthRecord; +import com.mesasoft.cn.model.FileBasicRecord; +import com.mesasoft.cn.model.FileRecord; +import com.mesasoft.cn.modules.constant.ConfigConsts; +import com.mesasoft.cn.modules.constant.DefaultValues; +import com.mesasoft.cn.service.IAuthService; +import com.mesasoft.cn.service.ICategoryService; +import com.mesasoft.cn.service.IFileService; +import com.mesasoft.cn.util.ServiceUtils; +import com.zhazhapan.modules.constant.ValueConsts; +import com.zhazhapan.util.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.Date; +import java.util.List; +import java.util.regex.Pattern; + +/** + * @author pantao + * @since 2018/1/29 + */ +@Service +public class FileServiceImpl implements IFileService { + + private final static Logger logger = LoggerFactory.getLogger(FileServiceImpl.class); + + private static final String FILE_SUFFIX = "{fileSuffix}"; + + private static final String RANDOM_ID = "{randomId}"; + + private static final String YEAR = "{year}"; + + private static final String MONTH = "{month}"; + + private static final String DAY = "{day}"; + + private static final String AUTHOR = "{author}"; + + private static final String FILE_NAME = "{fileName}"; + + private static final String CATEGORY_NAME = "{categoryName}"; + + private final FileDAO fileDAO; + + private final ICategoryService categoryService; + + private final IAuthService authService; + + private final DownloadedDAO downloadDAO; + + @Autowired + public FileServiceImpl(FileDAO fileDAO, ICategoryService categoryService, IAuthService authService, + DownloadedDAO downloadDAO) { + this.fileDAO = fileDAO; + this.categoryService = categoryService; + this.authService = authService; + this.downloadDAO = downloadDAO; + } + + @Override + public boolean updateAuth(long id, String auth) { + int[] au = BeanUtils.getAuth(auth); + return fileDAO.updateAuthById(id, au[0], au[1], au[2], au[3], au[4]); + } + + @Override + public BaseAuthRecord getAuth(long id) { + return fileDAO.getAuth(id); + } + + @Override + @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = + Exception.class) + public boolean deleteFiles(String ids) { + if (Checker.isNotEmpty(ids)) { + String[] id = ids.split(ValueConsts.COMMA_SIGN); + for (String s : id) { + long fileId = Formatter.stringToLong(s); + String localUrl = fileDAO.getLocalUrlById(fileId); + FileExecutor.deleteFile(localUrl); + removeById(fileId); + } + return true; + } + return false; + } + + @Override + @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = + Exception.class) + public boolean[] updateUrl(int id, String oldLocalUrl, String localUrl, String visitUrl) { + boolean[] b = new boolean[]{false, false}; + boolean canUpdateLocalUrl = Checker.isExists(oldLocalUrl) && Checker.isNotEmpty(localUrl) && Checker + .isNotExists(localUrl) && !localUrlExists(localUrl); + if (canUpdateLocalUrl) { + FileExecutor.renameTo(oldLocalUrl, localUrl); + fileDAO.updateLocalUrlById(id, localUrl); + b[0] = true; + } + if (Checker.isNotEmpty(visitUrl) && !visitUrlExists(visitUrl)) { + fileDAO.updateVisitUrlById(id, visitUrl); + b[1] = true; + } + return b; + } + + @Override + @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = + Exception.class) + public boolean updateFileInfo(long id, User user, String name, String category, String tag, String description) { + File file = fileDAO.getById(id); + if (Checker.isNotNull(file) && file.getIsUpdatable() == 1) { + AuthRecord authRecord = authService.getByFileIdAndUserId(id, user.getId()); + String suffix = FileExecutor.getFileSuffix(name); + boolean canUpdate = (Checker.isNull(authRecord) ? user.getIsUpdatable() == 1 : + authRecord.getIsUpdatable() == 1) && Checker.isNotEmpty(name) && Pattern.compile(SketchApplication.settings.getStringUseEval(ConfigConsts.FILE_SUFFIX_MATCH_OF_SETTING)).matcher(suffix).matches(); + if (canUpdate) { + String localUrl = file.getLocalUrl(); + java.io.File newFile = new java.io.File(localUrl); + String visitUrl = file.getVisitUrl(); + String newLocalUrl = localUrl.substring(0, localUrl.lastIndexOf(ValueConsts.SEPARATOR) + 1) + name; + String newVisitUrl = visitUrl.substring(0, visitUrl.lastIndexOf(ValueConsts.SPLASH_STRING) + 1) + name; + file.setName(name); + file.setSuffix(suffix); + file.setLocalUrl(newLocalUrl); + file.setVisitUrl(newVisitUrl); + file.setCategoryId(categoryService.getIdByName(category)); + file.setTag(tag); + file.setDescription(description); + boolean isValid = (localUrl.endsWith(ValueConsts.SEPARATOR + name) || (!Checker.isExists(newLocalUrl) + && !localUrlExists(newLocalUrl) && !visitUrlExists(newVisitUrl))); + if (isValid && fileDAO.updateFileInfo(file)) { + return newFile.renameTo(new java.io.File(newLocalUrl)); + } + } + } + return false; + } + + @Override + public boolean removeFile(User user, long fileId) { + File file = fileDAO.getById(fileId); + boolean isDeleted = false; + if (Checker.isNotNull(file) && file.getIsDeletable() == 1) { + AuthRecord authRecord = authService.getByFileIdAndUserId(fileId, user.getId()); + String localUrl = fileDAO.getLocalUrlById(fileId); + isDeleted = (Checker.isNull(authRecord) ? user.getIsDeletable() == 1 : authRecord.getIsDeletable() == 1) + && removeById(fileId); + if (isDeleted) { + FileExecutor.deleteFile(localUrl); + } + } + return isDeleted; + } + + @Override + public List<FileRecord> listUserDownloaded(int userId, int offset, String search) { + return fileDAO.listUserDownloaded(userId, offset, search); + } + + @Override + public List<FileRecord> listUserUploaded(int userId, int offset, String search) { + return fileDAO.listUserUploaded(userId, offset, search); + } + + @Override + @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = + Exception.class) + public boolean removeById(long id) { + downloadDAO.removeByFileId(id); + authService.removeByFileId(id); + return fileDAO.removeById(id); + } + + @Override + public boolean removeByVisitUrl(String visitUrl) { + long fileId = fileDAO.getIdByVisitUrl(visitUrl); + return removeById(fileId); + } + + @Override + public boolean removeByLocalUrl(String localUrl) { + long fileId = fileDAO.getIdByLocalUrl(localUrl); + return removeById(fileId); + } + + @Override + public String getResource(String visitUrl, HttpServletRequest request) { + logger.info("visit url: " + visitUrl); + boolean downloadable = SketchApplication.settings.getBooleanUseEval(ConfigConsts + .ANONYMOUS_DOWNLOADABLE_OF_SETTING); + User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING); + File file = fileDAO.getFileByVisitUrl(visitUrl); + AuthRecord authRecord = null; + if (Checker.isNotNull(file)) { + authRecord = authService.getByFileIdAndUserId(file.getId(), Checker.isNull(user) ? 0 : user.getId()); + } + boolean canDownload = Checker.isNotNull(file) && file.getIsDownloadable() == 1 && (downloadable || (Checker + .isNull(authRecord) ? (Checker.isNotNull(user) && user.getIsDownloadable() == 1) : authRecord + .getIsDownloadable() == 1)); + if (canDownload) { + fileDAO.updateDownloadTimesById(file.getId()); + if (Checker.isNotNull(user)) { + downloadDAO.insertDownload(user.getId(), file.getId()); + } + return file.getLocalUrl(); + } + return ""; + } + + @Override + public String getLocalUrlByVisitUrl(String visitUrl) { + return fileDAO.getLocalUrlByVisitUrl(Checker.checkNull(visitUrl)); + } + + @Override + public List<FileRecord> listAll(int userId, int offset, int categoryId, String orderBy, String search) { + return fileDAO.listAll(userId, offset, categoryId, orderBy, search); + } + + @Override + @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = + Exception.class) + public boolean upload(int categoryId, String tag, String description, String prefix, MultipartFile multipartFile, + User user) { + if (user.getIsUploadable() == 1) { + String name = multipartFile.getOriginalFilename(); + String suffix = FileExecutor.getFileSuffix(name); + String localUrl = SettingConfig.getUploadStoragePath() + ValueConsts.SEPARATOR + name; + Category category = categoryService.getById(categoryId); + long maxSize = Formatter.sizeToLong(SketchApplication.settings.getStringUseEval(ConfigConsts + .FILE_MAX_SIZE_OF_SETTING)); + long size = multipartFile.getSize(); + boolean fileExists = localUrlExists(localUrl); + //检测标签是否合法 + if (SketchApplication.settings.getBooleanUseEval(ConfigConsts.TAG_REQUIRE_OF_SETTING)) { + String[] tags = Checker.checkNull(tag).split(ValueConsts.SPACE); + if (tags.length <= SketchApplication.settings.getIntegerUseEval(ConfigConsts.TAG_SIZE_OF_SETTING)) { + int maxLength = SketchApplication.settings.getIntegerUseEval(ConfigConsts.TAG_LENGTH_OF_SETTING); + for (String t : tags) { + if (t.length() > maxLength) { + return false; + } + } + } else { + return false; + } + } + //是否可以上传 + boolean canUpload = !multipartFile.isEmpty() && size <= maxSize && Pattern.compile(SketchApplication + .settings.getStringUseEval(ConfigConsts.FILE_SUFFIX_MATCH_OF_SETTING)).matcher(suffix).matches() + && (Checker.isNotExists(localUrl) || !fileExists || SketchApplication.settings.getBooleanUseEval + (ConfigConsts.FILE_COVER_OF_SETTING)); + logger.info("is empty [" + multipartFile.isEmpty() + "], file size [" + size + "], max file size [" + + maxSize + "]"); + if (canUpload) { + String visitUrl = getRegularVisitUrl(Checker.isNotEmpty(prefix) && user.getPermission() > 1 ? prefix + : SketchApplication.settings.getStringUseEval(ConfigConsts.CUSTOM_LINK_RULE_OF_SETTING), user, + name, suffix, category); + if (fileExists) { + removeByLocalUrl(localUrl); + } + if (visitUrlExists(visitUrl)) { + removeByVisitUrl(visitUrl); + } + try { + multipartFile.transferTo(new java.io.File(localUrl)); + logger.info("local url of upload file: " + localUrl); + File file = new File(name, suffix, localUrl, visitUrl, WebUtils.scriptFilter(description), + WebUtils.scriptFilter(tag), user.getId(), categoryId); + int[] auth = SettingConfig.getAuth(ConfigConsts.FILE_DEFAULT_AUTH_OF_SETTING); + file.setAuth(auth[0], auth[1], auth[2], auth[3], auth[4]); + boolean isSuccess = fileDAO.insertFile(file); + if (isSuccess) { + long fileId = fileDAO.getIdByLocalUrl(localUrl); + if (fileId > 0) { + authService.insertDefaultAuth(user.getId(), fileId); + } + } else { + FileExecutor.deleteFile(localUrl); + } + return isSuccess; + } catch (Exception e) { + FileExecutor.deleteFile(localUrl); + logger.error("save file error: " + e.getMessage()); + } + } + } + return false; + } + + private String getRegularVisitUrl(String customUrl, User user, String fileName, String suffix, Category category) { + Date date = new Date(); + suffix = suffix.startsWith(".") ? "" : "." + suffix; + if (Checker.isNotEmpty(customUrl)) { + try { + customUrl = URLDecoder.decode(customUrl, "utf-8"); + } catch (UnsupportedEncodingException e) { + logger.error(e.getMessage()); + } + } + if (!customUrl.contains(FILE_NAME) && !customUrl.contains(RANDOM_ID)) { + customUrl += (customUrl.endsWith("/") ? "" : "/") + fileName; + } + customUrl = customUrl.replace(YEAR, DateUtils.getYear(date)).replace(MONTH, DateUtils.getMonth(date)).replace + (DAY, DateUtils.getDay(date)).replace(AUTHOR, user.getUsername()).replace(FILE_NAME, fileName) + .replace(CATEGORY_NAME, Checker.checkNull(Checker.isNull(category) ? "uncategorized" : category + .getName())).replace(RANDOM_ID, String.valueOf(RandomUtils.getRandomInteger(ValueConsts + .NINE_INT))).replace(FILE_SUFFIX, suffix); + return "/file" + (customUrl.startsWith("/") ? "" : "/") + customUrl; + } + + @Override + @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = + Exception.class) + public boolean shareFiles(String prefix, String files, User user) { + if (Checker.isNotEmpty(files)) { + String[] paths = files.split(ValueConsts.COMMA_SIGN); + for (String path : paths) { + java.io.File f = new java.io.File(path); + String name = f.getName(); + String suffix = FileExecutor.getFileSuffix(name); + String visitUrl = getRegularVisitUrl(prefix, user, name, suffix, null); + if (f.exists() && f.isFile() && !localUrlExists(path) && !visitUrlExists(visitUrl)) { + File file = new File(name, suffix, path, visitUrl, ValueConsts.EMPTY_STRING, + ValueConsts.EMPTY_STRING, user.getId(), + categoryService.getIdByName(DefaultValues.UNCATEGORIZED)); + file.setAuth(ValueConsts.ONE_INT, ValueConsts.ZERO_INT, ValueConsts.ZERO_INT, + ValueConsts.ZERO_INT, ValueConsts.ONE_INT); + fileDAO.insertFile(file); + } + } + } + return true; + } + + @Override + public boolean localUrlExists(String localUrl) { + return fileDAO.checkLocalUrl(localUrl) > 0; + } + + @Override + public boolean visitUrlExists(String visitUrl) { + return fileDAO.checkVisitUrl(visitUrl) > 0; + } + + @Override + public long getFileId(String localUrl) { + try { + return fileDAO.getIdByLocalUrl(localUrl); + } catch (Exception e) { + return 0; + } + } + + @SuppressWarnings("unchecked") + @Override + public List<FileBasicRecord> listBasicAll(String user, String file, String category, int offset) { + return (List<FileBasicRecord>) ServiceUtils.invokeFileFilter(fileDAO, "listBasicBy", user, file, category, + offset); + } +} |
