summaryrefslogtreecommitdiff
path: root/src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java
diff options
context:
space:
mode:
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.java383
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);
+ }
+}