|
- /*******************************************************************************
- * Copyright 2Fi Business Solutions Ltd.
- *
- * This code is copyrighted. Under no circumstances should any party, people,
- * or organization should redistribute any portions of this code in any form,
- * either verbatim or through electronic media, to any third parties, unless
- * under explicit written permission by 2Fi Business Solutions Ltd.
- ******************************************************************************/
- package com.ffii.tbms.file.service;
-
- import java.awt.image.BufferedImage;
- import java.io.ByteArrayInputStream;
- import java.io.IOException;
- import java.util.List;
- import java.util.Map;
-
- import javax.imageio.ImageIO;
-
- import org.apache.commons.lang3.RandomStringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Isolation;
- import org.springframework.transaction.annotation.Transactional;
-
- import com.ffii.core.dao.JdbcDao;
- import com.ffii.core.utils.FileUtils;
- import com.ffii.core.utils.MapUtils;
- import com.ffii.core.web.AbstractService;
- import com.ffii.core.web.view.AbstractView;
- import com.ffii.tbms.file.File;
- import com.ffii.tbms.file.FileBlob;
- import com.ffii.tbms.file.FileRef;
- import com.ffii.tbms.file.dao.FileBlobDao;
- import com.ffii.tbms.file.dao.FileDao;
- import com.ffii.tbms.file.dao.FileRefDao;
-
- /**
- * @author Patrick
- */
- @Service
- public class FileService extends AbstractService {
-
- @Autowired
- private JdbcDao jdbcDao;
-
- @Autowired
- private FileDao fileDao;
-
- @Autowired
- private FileBlobDao fileBlobDao;
-
- @Autowired
- private FileRefDao fileRefDao;
-
- /**
- * Save File, FileBlob, and FileRef in one go
- *
- * @param filename
- * the filename, cannot be null
- * @param description
- * optional File description
- * @param refType
- * the File reference type, should not be empty
- * @param refId
- * mandatory, use 0 if N/A
- * @param refCode
- * optional
- * @param bytes
- * the File byte array
- *
- * @return File ID
- */
- @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
- public Integer saveFile(String filename, String description, String refType, int refId, String refCode, byte[] bytes) {
- File file = new File();
- file.setFilename(filename);
- file.setDescription(description);
- file.setMimetype(FileUtils.guessMimetype(filename));
- file.setFilesize(bytes.length);
- file.setSkey(RandomStringUtils.randomAlphanumeric(16));
-
- FileBlob fileBlob = new FileBlob();
- fileBlob.setBytes(bytes);
-
- FileRef fileRef = new FileRef();
- fileRef.setRefId(refId);
- fileRef.setRefType(refType);
- fileRef.setRefCode(refCode);
-
- // try to get width and height if mimetype is png or jpeg
- if (AbstractView.CONTENT_TYPE_PNG.equals(file.getMimetype()) || AbstractView.CONTENT_TYPE_JPEG.equals(file.getMimetype())) {
- BufferedImage image;
- try {
- image = ImageIO.read(new ByteArrayInputStream(bytes));
- if (image != null) {
- file.setImageWidth(image.getWidth());
- file.setImageHeight(image.getHeight());
- }
- } catch (IOException e) {
- // ignore
- }
- }
-
- // save File
- saveFile(file);
-
- // save FileBlob
- fileBlob.setFileId(file.getId());
- saveFileBlob(fileBlob);
-
- // save FileRef
- fileRef.setFileId(file.getId());
- saveFileRef(fileRef);
-
- return file.getId();
- }
-
- @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
- public Integer saveFile(File instance) {
- return fileDao.saveOrUpdate(instance);
- }
-
- @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
- public Integer saveFileBlob(FileBlob instance) {
- return fileBlobDao.saveOrUpdate(instance);
- }
-
- @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
- public Integer saveFileRef(FileRef instance) {
- return fileRefDao.saveOrUpdate(instance);
- }
-
- @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
- public File findFileByIdAndKey(int id, String skey) {
- return fileDao.findByQuery("from com.ffii.tbms.file.File f where f.id = ? and f.skey = ?", id, skey);
- }
-
- @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
- public File findFileById(int id) {
- return fileDao.findByQuery("from com.ffii.tbms.file.File f where f.id = ? ", id);
- }
-
- @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
- public FileRef findFileRefByTypeAndId(String refType, int refId) {
- return fileRefDao.findByQuery("from com.ffii.tbms.file.FileRef where refType = ? and refId = ?", refType, refId);
- }
-
- @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
- public FileRef findFileRefByfileId(int fileId) {
- return fileRefDao.findByQuery("from com.ffii.tbms.file.FileRef where fileId = ?", fileId);
- }
-
- @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
- public FileBlob findFileBlobByFileId(int fileId) {
- return fileBlobDao.findByQuery("from com.ffii.tbms.file.FileBlob fb where fb.fileId = ?", fileId);
- }
-
- @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
- public boolean isFileExists(int id, String skey) {
-
- String sql = "SELECT"
- + " COUNT(1)"
- + " FROM files f"
- + " WHERE f.deleted = 0"
- + " AND f.id = :id"
- + " AND f.skey = :skey";
-
- int count = jdbcDao.queryForInt(sql, MapUtils.toHashMap("id", id, "skey", skey));
-
- return (count > 0);
- }
-
- @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
- public List<Map<String, Object>> searchFiles(Map<String, Object> args) {
-
- StringBuilder sql = new StringBuilder("SELECT"
- + " f.id,"
- + " f.filename,"
- + " f.filesize,"
- + " f.mimetype, "
- + " f.skey,"
- + " fr.refId,"
- + " fr.refType,"
- + " f.created,"
- + " f.imageWidth,"
- + " f.imageHeight,"
- + " u.fullname AS createdByName,"
- + " f.description"
- + " FROM files f"
- + " LEFT JOIN files_ref fr ON f.id = fr.fileId"
- + " LEFT JOIN users u ON f.createdBy = u.id"
- + " WHERE f.deleted = 0 AND fr.deleted =0 ");
-
- if (args.containsKey("filename")) sql.append(" AND f.filename = :filename");
-
- if (args.containsKey("refType")) sql.append(" AND fr.refType = :refType");
-
- if (args.containsKey("refId")) sql.append(" AND fr.refId = :refId");
-
- if (args.containsKey("startDate")) sql.append(" AND f.created >= :startDate");
-
- if (args.containsKey("endDate")) sql.append(" AND f.created < :endDate");
-
- if (args.containsKey("fileId")) sql.append(" AND f.id = :fileId");
-
-
- sql.append(" ORDER BY f.created DESC");
-
- return jdbcDao.queryForList(sql.toString(), args);
- }
-
- @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
- public List<Map<String, Object>> searchFilesFromDocument(Map<String, Object> args) {
-
- StringBuilder sql = new StringBuilder("SELECT"
- + " f.id,"
- + " f.filename,"
- + " f.filesize,"
- + " f.mimetype,"
- + " f.skey,"
- + " fr.refId,"
- + " fr.refType,"
- + " f.created,"
- + " u.fullname AS createdByName,"
- + " f.description"
- + " FROM files_ref fr"
- + " LEFT JOIN files f ON f.id = fr.fileId"
- + " LEFT JOIN users u ON f.createdBy = u.id"
- + " LEFT JOIN document_ref dr ON dr.documentId = fr.refId AND fr.refType = 'document'"
- + " WHERE 1 = 1"
- + " AND f.deleted = 0"
- + " AND fr.deleted = 0"
- + " AND dr.deleted = 0");
-
- if (args != null) {
- if (args.containsKey("filename")) sql.append(" AND f.filename = :filename");
- if (args.containsKey("refType")) sql.append(" AND fr.refType = :refType");
- if (args.containsKey("refId")) sql.append(" AND fr.refId = :refId");
- if (args.containsKey("startDate")) sql.append(" AND f.created >= :startDate");
- if (args.containsKey("endDate")) sql.append(" AND f.created < :endDate");
- if (args.containsKey("documentRefType")) sql.append(" AND dr.refType = :documentRefType");
- if (args.containsKey("documentRefId")) sql.append(" AND dr.refId = :documentRefId");
- }
-
- sql.append(" GROUP BY f.id"
- + " ORDER BY f.created DESC");
-
- return jdbcDao.queryForList(sql.toString(), args);
- }
-
- /**
- * Delete <code>FileRef</code> by <code>fileId</code>, <code>refId</code>, <code>refType</code>, and <code>skey</code>
- */
- @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
- public void deleteFile(Integer fileId, Integer refId, String refType, String skey) {
- Map<String, ?> args = MapUtils.toHashMap("fileId", fileId, "refId", refId, "refType", refType, "skey", skey);
-
- jdbcDao.executeUpdate("DELETE FROM files_ref"
- + " WHERE fileId = :fileId"
- + " AND refId = :refId"
- + " AND refType = :refType"
- + " AND EXISTS (SELECT 1 FROM files WHERE id = files_ref.fileId AND skey = :skey)",
- args);
- jdbcDao.executeUpdate("DELETE FROM files_blob WHERE id = :fileId ",args);
- }
-
- /**
- * Scheduled daily job
- *
- * Delete all orphan (without any <code>FileRef</code>) <code>File</code>s and <code>FileBlob</code>s
- */
- @Scheduled(cron = "0 0 0 * * ?") // everyday at 00:00:00
- @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = false)
- public void deleteOrphanFiles() {
- jdbcDao.executeUpdate("DELETE FROM files_blob WHERE NOT EXISTS (SELECT 1 FROM files_ref WHERE deleted = 0 AND fileId = files_blob.fileId)");
- jdbcDao.executeUpdate("DELETE FROM files WHERE NOT EXISTS (SELECT 1 FROM files_ref WHERE deleted = 0 AND fileId = files.id)");
- }
-
- @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = true)
- public List<Map<String, Object>> getCustImageList() {
- return jdbcDao.queryForList(" Select cp.* From cust_photo cp ", null);
- }
-
- @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class, readOnly = true)
- public List<Map<String, Object>> getOrderImageList() {
- return jdbcDao.queryForList(" Select op.* From order_photo cp ", null);
- }
-
-
-
- }
|