shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
package com.walker.file;
 
import com.walker.file.support.SimpleFileMeta;
import com.walker.infrastructure.core.NestedRuntimeException;
import com.walker.infrastructure.utils.FileUtils;
import com.walker.infrastructure.utils.JarDeployer;
import com.walker.infrastructure.utils.LongCalendar;
import com.walker.infrastructure.utils.NumberGenerator;
import com.walker.infrastructure.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
 
@Deprecated
public abstract class AbstractFileEngine implements FileEngine {
    
    protected static final transient Logger logger = LoggerFactory.getLogger(AbstractFileEngine.class);
    
    /* 系统文件系统根路径:file:// or file:/// */
    private String fileSystemRoot = FileUtils.getFileSystemRoot();
    private String rootPath = null;
    
    /* 是否默认就存储到webroot目录下面么,通常对于小项目文件少我们建议存储到web下可以直接访问;
     * 对于大项目我们可以存储到其他存储设备目录中,但这样做就不能让系统直接生成链接访问了 */
    private boolean storeInWebRoot = true;
    
    public boolean isStoreInWebRoot() {
        return storeInWebRoot;
    }
 
    /**
     * 设置文件是否存储到web目录中
     * @param storeInWebRoot
     */
    public void setStoreInWebRoot(boolean storeInWebRoot) {
        this.storeInWebRoot = storeInWebRoot;
    }
    
    public String getFileStoreRootPath() {
        return rootPath;
    }
 
    private FileReader fileReader;
    
    @Override
    public List<FileMeta> readFiles(Object request, String fileFormId,
            StoreType st) throws FileOperateException {
        if(fileReader == null){
            throw new IllegalArgumentException("fileReader is required!");
        }
        
        try {
            return fileReader.read(request, fileFormId, st);
        } catch (IOException e) {
            logger.error("reader file from request failed!", e);
            throw new FileOperateException(e.getMessage(), e);
        }
    }
 
    @Override
    public List<String> writeFiles(List<FileMeta> fileMetas)
            throws FileOperateException {
        assert (fileMetas != null);
        logger.debug("...... start write files: " + fileMetas.size());
        
        List<String> ids = new LinkedList<String>();
        doWriteFiles(fileMetas);
        for(FileMeta fm : fileMetas){
            ids.add(fm.getId());
        }
        return ids;
        
//        try{
//            for(FileMeta fm : fileMetas){
//                if(fm.getStoreType() == StoreType.FileSystem){
//                    // 存储到文件系统
//                    if(StringUtils.isEmpty(rootPath)){
//                        throw new FileOperateException("rootPath is required!");
//                    }
//                    // 复制文件到服务器
//                    writeToFileSystem(fm, rootPath);
//                    // 存储记录、包括元数据到数据库
//                    writeToDatabase(fm);
//                    
//                } else if(fm.getStoreType() == StoreType.Database){
//                    // 存储记录、包括元数据到数据库
//                    writeToDatabase(fm);
//                } else
//                    throw new UnsupportedOperationException();
//                ids.add(fm.getId());
//            }
//            return ids;
//        } catch(Exception ex){
//            throw new FileOperateException("write file failed!", ex);
//        }
    }
    
    private void doWriteFiles(List<FileMeta> fileMetas) throws FileOperateException{
        try{
            for(FileMeta fm : fileMetas){
                if(fm.getStoreType() == StoreType.FileSystem){
                    // 存储到文件系统
                    if(StringUtils.isEmpty(rootPath)){
                        throw new FileOperateException("rootPath is required!");
                    }
                    // 复制文件到服务器
                    writeToFileSystem(fm, rootPath);
                    // 存储记录、包括元数据到数据库
                    writeToDatabase(fm);
                    
                } else if(fm.getStoreType() == StoreType.Database){
                    // 存储记录、包括元数据到数据库
                    writeToDatabase(fm);
                } else
                    throw new UnsupportedOperationException();
            }
        } catch(Exception ex){
            throw new FileOperateException(ex.getMessage(), ex);
        }
    }
    
    @Override
    public FileMeta createEmptyFile(String filename, String mimeType){
        assert (StringUtils.isNotEmpty(filename));
        if(filename.indexOf(StringUtils.EXTENSION_SEPARATOR) <= 0){
            throw new IllegalArgumentException("file not include extention name.");
        }
        int extIndex = filename.lastIndexOf(".");
        FileMeta fm = new SimpleFileMeta();
        fm.setFilename(filename);
        fm.setFileExt(filename.substring(extIndex+1));
        fm.setContentType(mimeType);
        
        // 要保存到数据库的路径,如:2014/3/
        String savedPath = LongCalendar.getCurrentMonth();
        String filePath = getSavedAbsolutePath(savedPath);
        String newFilename = getSavedFilename(filename, fm.getFileExt());
        fm.setPath(savedPath + newFilename);
        fm.setAbsoluteFileName(filePath + newFilename);
        
        // 创建空文件
        try {
            FileUtils.createEmptyFile(filePath + newFilename);
        } catch (IOException e) {
            throw new NestedRuntimeException("create emptyFile failed: " + e.getMessage(), e);
        }
        try {
            writeToDatabase(fm);
        } catch (Exception e) {
            throw new NestedRuntimeException("save file meta into db failed", e);
        }
        return fm;
    }
    
    /**
     * 写入文件到操作系统的文件系统中
     * @param fm
     * @param rootPath
     * @return 返回写入文件的绝对路径
     * @throws IOException
     */
    protected abstract String writeToFileSystem(FileMeta fm, String rootPath) throws IOException;
    
    /**
     * 把文件信息写入到数据库,包括元数据,如果文件是二进制也保存。
     * @param fm
     * @return
     * @throws Exception
     */
    protected abstract String writeToDatabase(FileMeta fm) throws Exception;
    
    /**
     * 返回保存文件的绝对路径,如:d:/file_store/2014/3/
     * @param savedPath 生成的月份路径,如:2014/3/
     * @return
     */
    protected String getSavedAbsolutePath(String savedPath){
        // 组织新的目录:定义根目录 + 年月。如:d:/logs/2014/3/
        String filePath = new StringBuilder()
                .append(rootPath)
                .append(savedPath).toString();
        
        // 检查目录是否存在,不存在自动创建
        FileUtils.checkDir(filePath);
        return filePath;
    }
    
    /**
     * 组织新的文件名
     * @param resFilename 原始文件名
     * @return
     */
    protected String getSavedFilename(String resFilename, String ext){
        String newFilename = new StringBuilder()
        .append(NumberGenerator.getLongSequenceNumber())
//        .append(StringUtils.UNDERLINE)
//        .append(resFilename).toString();
        .append(StringUtils.EXTENSION_SEPARATOR).append(ext).toString();
        return newFilename;
    }
    
    @Override
    public List<FileMeta> listFiles(List<String> ids)
            throws FileOperateException {
        return null;
    }
 
    @Override
    public FileMeta getFile(String id) {
        return null;
    }
    
    @Override
    public File getFileObject(String id){
        return null;
    }
 
    @Override
    public void removeFile(String id) throws FileOperateException {
        
    }
 
    @Override
    public void setFileStoreRootPath(String rootPath) {
        assert (StringUtils.isNotEmpty(rootPath));
        if(storeInWebRoot){
            logger.warn("已经设置文件存放到web目录中,就不需要再配置存储根路径了:请查阅参数'storeInWebRoot'");
//            throw new IllegalStateException("已经设置文件存放到web目录中,就不需要再配置存储根路径了:请查阅参数'storeInWebRoot'");
            this.rootPath = fileSystemRoot + JarDeployer.webappRootAbsolute + "upload/files/";
        } else {
            this.rootPath = fileSystemRoot + rootPath;
        }
        logger.info("系统设置了文件存储目录:" + this.rootPath);
    }
 
    @Override
    public void setFileReader(FileReader reader) {
        assert (reader != null);
        this.fileReader = reader;
    }
 
}