package com.iplatform.file;
import com.iplatform.base.PlatformRuntimeException;
import com.iplatform.file.util.FileStoreUtils;
import com.walker.file.FileInfo;
import com.walker.file.FileOperateEngine;
import com.walker.file.FileOperateException;
import com.walker.file.FileStoreType;
import com.walker.infrastructure.arguments.ArgumentsManager;
import com.walker.infrastructure.arguments.Variable;
import com.walker.infrastructure.core.ApplicationBeanInitialized;
import com.walker.infrastructure.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 文件管理引擎工厂,提供不同实现上传调用。
* @author 时克英
* @date 2023-02-14
*/
public class FileEngineFactory implements ApplicationBeanInitialized {
protected final transient Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 下载oss文件
* @param fileStoreType
* @param id 文件唯一编号
* @return
* @date 2023-12-13
*/
public byte[] downloadOssFile(FileStoreType fileStoreType, String id){
try {
return this.fileOperateEngineMap.get(fileStoreType).downloadFile(id);
} catch (FileOperateException e) {
throw new PlatformRuntimeException("下载oss文件错误:" + e.getMessage() + ", id=" + id, e);
}
}
/**
* 根据文件ID,返回文件对象。
* @param id
* @return
* @date 2023-02-15
*/
public FileInfo getFileInfo(String id) {
return this.fileOperateEngineMap.get(FileStoreType.FileSystem).getFileInfo(id);
}
/**
* 根据文件ID集合,返回文件对象集合。
*
注意:其实哪个引擎都可以根据 id 返回文件信息,这里随便选一个就行。
* @param ids
* @return
* @date 2023-02-15
* @date 2023-08-01 更新注释
*/
public List getFileInfoList(List ids) {
return this.fileOperateEngineMap.get(FileStoreType.FileSystem).getFileInfoList(ids);
}
/**
* 上传一个文件到系统磁盘。
* @param inputStream 文件输入流
* @param fileName 文件名字,不包含路径,如: demo.txt
* @param groupId 分组ID,即: 业务id,可选
* @return
* @throws FileOperateException
*/
@Deprecated
public FileInfo uploadFileToSystem(InputStream inputStream, String fileName, String groupId, long fileSize) throws FileOperateException{
return this.uploadFile(FileStoreType.FileSystem, inputStream, fileName, groupId, fileSize);
}
/**
* 上传文件到系统本地。
* @param inputStream
* @param fileName
* @param groupId
* @param fileSize
* @param businessType
* @param owner
* @return
* @throws FileOperateException
* @date 2023-06-09
*/
public FileInfo uploadFileToLocal(InputStream inputStream, String fileName, String groupId
, long fileSize, Integer businessType, String owner) throws FileOperateException{
return this.uploadFile(FileStoreType.FileSystem, inputStream, fileName, groupId, fileSize, businessType, owner);
}
public FileInfo[] uploadFileToLocal(InputStream[] inputStream, String[] fileName, String groupId
, long[] fileSize, Integer businessType, String owner) throws FileOperateException{
return this.uploadFile(FileStoreType.FileSystem, inputStream, fileName, groupId, fileSize, businessType, owner);
}
/**
* 上传一个文件到FTP。
* @param inputStream 文件输入流
* @param fileName 文件名字,不包含路径,如: demo.txt
* @param groupId 分组ID,即: 业务id,可选
* @return
* @throws FileOperateException
*/
@Deprecated
public FileInfo uploadFileToFtp(InputStream inputStream, String fileName, String groupId, long fileSize) throws FileOperateException{
return this.uploadFile(FileStoreType.Ftp, inputStream, fileName, groupId, fileSize);
}
/**
* 上传一个文件到FTP,这是新方法。
* @param inputStream
* @param fileName
* @param groupId
* @param fileSize
* @param businessType
* @param owner
* @return
* @throws FileOperateException
* @date 2023-06-09
*/
public FileInfo uploadFileToFtp(InputStream inputStream, String fileName, String groupId
, long fileSize, Integer businessType, String owner) throws FileOperateException{
if(this.remoteAsLocal){
// 2023-07-03
return this.uploadFile(FileStoreType.FileSystem, inputStream, fileName, groupId, fileSize, businessType, owner);
} else {
return this.uploadFile(FileStoreType.Ftp, inputStream, fileName, groupId, fileSize, businessType, owner);
}
}
public FileInfo[] uploadFileToFtp(InputStream[] inputStream, String[] fileName, String groupId
, long[] fileSize, Integer businessType, String owner) throws FileOperateException{
if(this.remoteAsLocal){
// 2023-07-03
return this.uploadFile(FileStoreType.FileSystem, inputStream, fileName, groupId, fileSize, businessType, owner);
} else {
return this.uploadFile(FileStoreType.Ftp, inputStream, fileName, groupId, fileSize, businessType, owner);
}
}
/**
* 上传文件到第三方 OSS 系统。
* @param inputStream
* @param fileName 文件名字,不包含路径,如: demo.txt
* @param groupId
* @param fileSize
* @param businessType 业务类型(PID)
* @param owner 数据归属(商户ID),如果平台则为:-1
* @param fileStoreType
* @return
* @throws FileOperateException
* @date 2023-06-09
*/
public FileInfo uploadFileToOss(InputStream inputStream, String fileName, String groupId
, long fileSize, Integer businessType, String owner, FileStoreType fileStoreType) throws FileOperateException{
if(fileStoreType != FileStoreType.OssQiNiu
&& fileStoreType != FileStoreType.OssTx && fileStoreType != FileStoreType.OssAli
&& fileStoreType != FileStoreType.OssAws){
throw new UnsupportedOperationException("不支持的OSS类型:" + fileStoreType);
}
if(this.remoteAsLocal){
// 2023-07-03
return this.uploadFile(FileStoreType.FileSystem, inputStream, fileName, groupId, fileSize, businessType, owner);
} else {
return this.uploadFile(fileStoreType, inputStream, fileName, groupId, fileSize, businessType, owner);
}
}
public FileInfo[] uploadFileToOss(InputStream[] inputStream, String[] fileName, String groupId
, long[] fileSize, Integer businessType, String owner, FileStoreType fileStoreType) throws FileOperateException{
if(fileStoreType != FileStoreType.OssQiNiu
&& fileStoreType != FileStoreType.OssTx && fileStoreType != FileStoreType.OssAli
&& fileStoreType != FileStoreType.OssAws){
throw new UnsupportedOperationException("不支持的OSS类型:" + fileStoreType);
}
if(this.remoteAsLocal){
// 2023-07-03
return this.uploadFile(FileStoreType.FileSystem, inputStream, fileName, groupId, fileSize, businessType, owner);
} else {
return this.uploadFile(fileStoreType, inputStream, fileName, groupId, fileSize, businessType, owner);
}
}
/**
* 上传一个文件。
* @param fileStoreType 文件存储类型,见: FileStoreType
* @param inputStream 文件输入流
* @param fileName 文件名字,不包含路径,如: demo.txt
* @param groupId 分组ID,即: 业务id,可选
* @return
* @throws FileOperateException
*/
@Deprecated
public FileInfo uploadFile(FileStoreType fileStoreType
, InputStream inputStream, String fileName, String groupId, long fileSize) throws FileOperateException{
FileOperateEngine fileOperateEngine = this.fileOperateEngineMap.get(fileStoreType);
if(fileOperateEngine == null){
throw new IllegalArgumentException("未找到对应的文件引擎,fileStoreType=" + fileStoreType);
}
// return fileOperateEngine.uploadFile(inputStream, fileName, groupId, fileSize);
return fileOperateEngine.uploadFile(inputStream, fileName, groupId, fileSize);
}
public FileInfo uploadFile(FileStoreType fileStoreType
, InputStream inputStream, String fileName, String groupId, long fileSize
, Integer businessType, String owner) throws FileOperateException{
FileOperateEngine fileOperateEngine = this.fileOperateEngineMap.get(fileStoreType);
if(fileOperateEngine == null){
throw new IllegalArgumentException("未找到对应的文件引擎,fileStoreType=" + fileStoreType);
}
// return fileOperateEngine.uploadFile(inputStream, fileName, groupId, fileSize);
return fileOperateEngine.uploadFile(inputStream, fileName, groupId, fileSize, businessType, owner);
}
public FileInfo[] uploadFile(FileStoreType fileStoreType
, InputStream[] inputStream, String[] fileName, String groupId, long[] fileSize
, Integer businessType, String owner) throws FileOperateException{
FileOperateEngine fileOperateEngine = this.fileOperateEngineMap.get(fileStoreType);
if(fileOperateEngine == null){
throw new IllegalArgumentException("未找到对应的文件引擎,fileStoreType=" + fileStoreType);
}
return fileOperateEngine.uploadFile(inputStream, fileName, groupId, fileSize, businessType, owner);
}
public void register(FileStoreType fileStoreType, FileOperateEngine fileOperateEngine){
if(fileStoreType == null || fileOperateEngine == null){
throw new IllegalArgumentException("错误:注册 '文件管理引擎' 为空。");
}
this.fileOperateEngineMap.put(fileStoreType, fileOperateEngine);
}
private Map fileOperateEngineMap = new HashMap<>(4);
@Override
public void startup() {
String fileUrlPrefixConfig = this.getFileUrlPrefix(FileStoreType.FileSystem.getIndex());
if(StringUtils.isNotEmpty(fileUrlPrefixConfig)){
FileStoreUtils.fileStoreTypeUrlPrefix.put(FileStoreType.FileSystem.getIndex(), fileUrlPrefixConfig);
}
fileUrlPrefixConfig = this.getFileUrlPrefix(FileStoreType.Ftp.getIndex());
if(StringUtils.isNotEmpty(fileUrlPrefixConfig)){
FileStoreUtils.fileStoreTypeUrlPrefix.put(FileStoreType.Ftp.getIndex(), fileUrlPrefixConfig);
}
fileUrlPrefixConfig = this.getFileUrlPrefix(FileStoreType.OssQiNiu.getIndex());
if(StringUtils.isNotEmpty(fileUrlPrefixConfig)){
FileStoreUtils.fileStoreTypeUrlPrefix.put(FileStoreType.OssQiNiu.getIndex(), fileUrlPrefixConfig);
}
fileUrlPrefixConfig = this.getFileUrlPrefix(FileStoreType.OssTx.getIndex());
if(StringUtils.isNotEmpty(fileUrlPrefixConfig)){
FileStoreUtils.fileStoreTypeUrlPrefix.put(FileStoreType.OssTx.getIndex(), fileUrlPrefixConfig);
}
fileUrlPrefixConfig = this.getFileUrlPrefix(FileStoreType.OssAli.getIndex());
if(StringUtils.isNotEmpty(fileUrlPrefixConfig)){
FileStoreUtils.fileStoreTypeUrlPrefix.put(FileStoreType.OssAli.getIndex(), fileUrlPrefixConfig);
}
}
/**
* 返回文件存储不同方式,对应的文件URL前缀。
* @param fileStoreType
* @return
*/
private String getFileUrlPrefix(String fileStoreType){
logger.info("setup fileStoreType = {}", fileStoreType);
String fileUrlKey = FileStoreUtils.getFileUrlPrefixKey(fileStoreType);
if(StringUtils.isEmpty(fileUrlKey)){
logger.error("fileUrlKey为空,该文件存储类型无法获取配置,fileStoreType = " + fileStoreType);
return null;
}
Variable var = this.argumentsManager.getVariable(fileUrlKey);
if(var == null){
// throw new IllegalStateException("variable未找到,key = " + fileUrlKey);
logger.error("argumentsManager获取参数为空! fileUrlKey=" + fileUrlKey);
return null;
}
return var.getStringValue();
}
public void setArgumentsManager(ArgumentsManager argumentsManager) {
this.argumentsManager = argumentsManager;
}
/**
* 是否在调用远程存储方法时,按照本地方式存储,如果设置:true 则存储到本地(一般测试没有FTP、OSS环境时这样使用)
* @param remoteAsLocal
* @date 2023-07-03
*/
public void setRemoteAsLocal(boolean remoteAsLocal) {
this.remoteAsLocal = remoteAsLocal;
}
private boolean remoteAsLocal = true;
private ArgumentsManager argumentsManager;
}