001
014
015 package com.liferay.portlet.documentlibrary.store;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.util.FileUtil;
020 import com.liferay.portal.kernel.util.StringPool;
021 import com.liferay.portal.kernel.util.Validator;
022 import com.liferay.portal.util.PropsValues;
023 import com.liferay.portlet.documentlibrary.DuplicateDirectoryException;
024 import com.liferay.portlet.documentlibrary.DuplicateFileException;
025 import com.liferay.portlet.documentlibrary.NoSuchDirectoryException;
026 import com.liferay.portlet.documentlibrary.NoSuchFileException;
027 import com.liferay.portlet.documentlibrary.util.DLUtil;
028
029 import java.io.File;
030 import java.io.FileInputStream;
031 import java.io.FileNotFoundException;
032 import java.io.IOException;
033 import java.io.InputStream;
034
035 import java.util.Arrays;
036 import java.util.Map;
037 import java.util.concurrent.ConcurrentHashMap;
038
039
045 public class FileSystemStore extends BaseStore {
046
047 public FileSystemStore() {
048 if (!_rootDir.exists()) {
049 _rootDir.mkdirs();
050 }
051 }
052
053 @Override
054 public void addDirectory(long companyId, long repositoryId, String dirName)
055 throws PortalException {
056
057 File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
058
059 if (dirNameDir.exists()) {
060 throw new DuplicateDirectoryException(dirNameDir.getPath());
061 }
062
063 dirNameDir.mkdirs();
064 }
065
066 @Override
067 public void addFile(
068 long companyId, long repositoryId, String fileName, InputStream is)
069 throws PortalException, SystemException {
070
071 try {
072 File fileNameVersionFile = getFileNameVersionFile(
073 companyId, repositoryId, fileName, VERSION_DEFAULT);
074
075 if (fileNameVersionFile.exists()) {
076 throw new DuplicateFileException(fileNameVersionFile.getPath());
077 }
078
079 FileUtil.write(fileNameVersionFile, is);
080 }
081 catch (IOException ioe) {
082 throw new SystemException(ioe);
083 }
084 }
085
086 @Override
087 public void checkRoot(long companyId) {
088 }
089
090 @Override
091 public void copyFileVersion(
092 long companyId, long repositoryId, String fileName,
093 String fromVersionLabel, String toVersionLabel)
094 throws PortalException, SystemException {
095
096 File fromFileNameVersionFile = getFileNameVersionFile(
097 companyId, repositoryId, fileName, fromVersionLabel);
098
099 File toFileNameVersionFile = getFileNameVersionFile(
100 companyId, repositoryId, fileName, toVersionLabel);
101
102 if (toFileNameVersionFile.exists()) {
103 throw new DuplicateFileException(toFileNameVersionFile.getPath());
104 }
105
106 try {
107 toFileNameVersionFile.createNewFile();
108
109 FileUtil.copyFile(fromFileNameVersionFile, toFileNameVersionFile);
110 }
111 catch (IOException ioe) {
112 throw new SystemException(ioe);
113 }
114 }
115
116 @Override
117 public void deleteDirectory(
118 long companyId, long repositoryId, String dirName)
119 throws PortalException {
120
121 File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
122
123 if (!dirNameDir.exists()) {
124 throw new NoSuchDirectoryException(dirNameDir.getPath());
125 }
126
127 File parentFile = dirNameDir.getParentFile();
128
129 FileUtil.deltree(dirNameDir);
130
131 RepositoryDirKey repositoryDirKey = new RepositoryDirKey(
132 companyId, repositoryId);
133
134 _repositoryDirs.remove(repositoryDirKey);
135
136 deleteEmptyAncestors(parentFile);
137 }
138
139 @Override
140 public void deleteFile(long companyId, long repositoryId, String fileName)
141 throws PortalException {
142
143 File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
144
145 if (!fileNameDir.exists()) {
146 throw new NoSuchFileException(fileNameDir.getPath());
147 }
148
149 File parentFile = fileNameDir.getParentFile();
150
151 FileUtil.deltree(fileNameDir);
152
153 deleteEmptyAncestors(companyId, repositoryId, parentFile);
154 }
155
156 @Override
157 public void deleteFile(
158 long companyId, long repositoryId, String fileName,
159 String versionLabel)
160 throws PortalException {
161
162 File fileNameVersionFile = getFileNameVersionFile(
163 companyId, repositoryId, fileName, versionLabel);
164
165 if (!fileNameVersionFile.exists()) {
166 throw new NoSuchFileException(fileNameVersionFile.getPath());
167 }
168
169 File parentFile = fileNameVersionFile.getParentFile();
170
171 fileNameVersionFile.delete();
172
173 deleteEmptyAncestors(companyId, repositoryId, parentFile);
174 }
175
176 @Override
177 public File getFile(
178 long companyId, long repositoryId, String fileName,
179 String versionLabel)
180 throws PortalException {
181
182 if (Validator.isNull(versionLabel)) {
183 versionLabel = getHeadVersionLabel(
184 companyId, repositoryId, fileName);
185 }
186
187 File fileNameVersionFile = getFileNameVersionFile(
188 companyId, repositoryId, fileName, versionLabel);
189
190 if (!fileNameVersionFile.exists()) {
191 throw new NoSuchFileException(fileNameVersionFile.getPath());
192 }
193
194 return fileNameVersionFile;
195 }
196
197 @Override
198 public InputStream getFileAsStream(
199 long companyId, long repositoryId, String fileName,
200 String versionLabel)
201 throws PortalException {
202
203 if (Validator.isNull(versionLabel)) {
204 versionLabel = getHeadVersionLabel(
205 companyId, repositoryId, fileName);
206 }
207
208 File fileNameVersionFile = getFileNameVersionFile(
209 companyId, repositoryId, fileName, versionLabel);
210
211 try {
212 return new FileInputStream(fileNameVersionFile);
213 }
214 catch (FileNotFoundException fnfe) {
215 throw new NoSuchFileException(fileNameVersionFile.getPath(), fnfe);
216 }
217 }
218
219 public String[] getFileNames(long companyId, long repositoryId) {
220 File repositoryDir = getRepositoryDir(companyId, repositoryId);
221
222 return FileUtil.listDirs(repositoryDir);
223 }
224
225 @Override
226 public String[] getFileNames(
227 long companyId, long repositoryId, String dirName)
228 throws PortalException {
229
230 File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
231
232 if (!dirNameDir.exists()) {
233 throw new NoSuchDirectoryException(dirNameDir.getPath());
234 }
235
236 String[] fileNames = FileUtil.listDirs(dirNameDir);
237
238 Arrays.sort(fileNames);
239
240
241
242 for (int i = 0; i < fileNames.length; i++) {
243 fileNames[i] =
244 StringPool.SLASH + dirName + StringPool.SLASH + fileNames[i];
245 }
246
247 return fileNames;
248 }
249
250 @Override
251 public long getFileSize(long companyId, long repositoryId, String fileName)
252 throws PortalException {
253
254 String versionLabel = getHeadVersionLabel(
255 companyId, repositoryId, fileName);
256
257 File fileNameVersionFile = getFileNameVersionFile(
258 companyId, repositoryId, fileName, versionLabel);
259
260 if (!fileNameVersionFile.exists()) {
261 throw new NoSuchFileException(fileNameVersionFile.getPath());
262 }
263
264 return fileNameVersionFile.length();
265 }
266
267 @Override
268 public boolean hasDirectory(
269 long companyId, long repositoryId, String dirName) {
270
271 File dirNameDir = getDirNameDir(companyId, repositoryId, dirName);
272
273 return dirNameDir.exists();
274 }
275
276 @Override
277 public boolean hasFile(
278 long companyId, long repositoryId, String fileName,
279 String versionLabel) {
280
281 File fileNameVersionFile = getFileNameVersionFile(
282 companyId, repositoryId, fileName, versionLabel);
283
284 if (fileNameVersionFile.exists()) {
285 return true;
286 }
287 else {
288 return false;
289 }
290 }
291
292 @Override
293 public void move(String srcDir, String destDir) {
294 }
295
296 @Override
297 public void updateFile(
298 long companyId, long repositoryId, long newRepositoryId,
299 String fileName)
300 throws PortalException, SystemException {
301
302 File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
303 File newFileNameDir = getFileNameDir(
304 companyId, newRepositoryId, fileName);
305
306 if (newFileNameDir.exists()) {
307 throw new DuplicateFileException(fileName);
308 }
309
310 File parentFile = fileNameDir.getParentFile();
311
312 boolean renamed = FileUtil.move(fileNameDir, newFileNameDir);
313
314 if (!renamed) {
315 throw new SystemException(
316 "File name directory was not renamed from " +
317 fileNameDir.getPath() + " to " + newFileNameDir.getPath());
318 }
319
320 deleteEmptyAncestors(companyId, repositoryId, parentFile);
321 }
322
323 public void updateFile(
324 long companyId, long repositoryId, String fileName,
325 String newFileName)
326 throws PortalException, SystemException {
327
328 File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
329 File newFileNameDir = getFileNameDir(
330 companyId, repositoryId, newFileName);
331
332 if (newFileNameDir.exists()) {
333 throw new DuplicateFileException(newFileName);
334 }
335
336 File parentFile = fileNameDir.getParentFile();
337
338 boolean renamed = FileUtil.move(fileNameDir, newFileNameDir);
339
340 if (!renamed) {
341 throw new SystemException(
342 "File name directory was not renamed from " +
343 fileNameDir.getPath() + " to " + newFileNameDir.getPath());
344 }
345
346 deleteEmptyAncestors(companyId, repositoryId, parentFile);
347 }
348
349 @Override
350 public void updateFile(
351 long companyId, long repositoryId, String fileName,
352 String versionLabel, InputStream is)
353 throws PortalException, SystemException {
354
355 try {
356 File fileNameVersionFile = getFileNameVersionFile(
357 companyId, repositoryId, fileName, versionLabel);
358
359 if (fileNameVersionFile.exists()) {
360 throw new DuplicateFileException(fileNameVersionFile.getPath());
361 }
362
363 FileUtil.write(fileNameVersionFile, is);
364 }
365 catch (IOException ioe) {
366 throw new SystemException(ioe);
367 }
368 }
369
370 @Override
371 public void updateFileVersion(
372 long companyId, long repositoryId, String fileName,
373 String fromVersionLabel, String toVersionLabel)
374 throws PortalException, SystemException {
375
376 File fromFileNameVersionFile = getFileNameVersionFile(
377 companyId, repositoryId, fileName, fromVersionLabel);
378
379 File toFileNameVersionFile = getFileNameVersionFile(
380 companyId, repositoryId, fileName, toVersionLabel);
381
382 if (toFileNameVersionFile.exists()) {
383 throw new DuplicateFileException(toFileNameVersionFile.getPath());
384 }
385
386 boolean renamed = FileUtil.move(
387 fromFileNameVersionFile, toFileNameVersionFile);
388
389 if (!renamed) {
390 throw new SystemException(
391 "File name version file was not renamed from " +
392 fromFileNameVersionFile.getPath() + " to " +
393 toFileNameVersionFile.getPath());
394 }
395 }
396
397 protected void deleteEmptyAncestors(File file) {
398 deleteEmptyAncestors(-1, -1, file);
399 }
400
401 protected void deleteEmptyAncestors(
402 long companyId, long repositoryId, File file) {
403
404 String[] fileNames = file.list();
405
406 if ((fileNames == null) || (fileNames.length > 0)) {
407 return;
408 }
409
410 String fileName = file.getName();
411
412 if ((repositoryId > 0) &&
413 fileName.equals(String.valueOf(repositoryId))) {
414
415 RepositoryDirKey repositoryDirKey = new RepositoryDirKey(
416 companyId, repositoryId);
417
418 _repositoryDirs.remove(repositoryDirKey);
419 }
420
421 File parentFile = file.getParentFile();
422
423 if (file.delete() && (parentFile != null)) {
424 deleteEmptyAncestors(companyId, repositoryId, parentFile);
425 }
426 }
427
428 protected File getCompanyDir(long companyId) {
429 File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
430
431 if (!companyDir.exists()) {
432 companyDir.mkdirs();
433 }
434
435 return companyDir;
436 }
437
438 protected File getDirNameDir(
439 long companyId, long repositoryId, String dirName) {
440
441 return getFileNameDir(companyId, repositoryId, dirName);
442 }
443
444 protected File getFileNameDir(
445 long companyId, long repositoryId, String fileName) {
446
447 File repositoryDir = getRepositoryDir(companyId, repositoryId);
448
449 File fileNameDir = new File(
450 repositoryDir + StringPool.SLASH + fileName);
451
452 return fileNameDir;
453 }
454
455 protected File getFileNameVersionFile(
456 long companyId, long repositoryId, String fileName, String version) {
457
458 File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
459
460 File fileNameVersionFile = new File(
461 fileNameDir + StringPool.SLASH + version);
462
463 return fileNameVersionFile;
464 }
465
466 protected String getHeadVersionLabel(
467 long companyId, long repositoryId, String fileName) {
468
469 File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
470
471 if (!fileNameDir.exists()) {
472 return VERSION_DEFAULT;
473 }
474
475 String[] versionLabels = FileUtil.listFiles(fileNameDir);
476
477 String headVersionLabel = VERSION_DEFAULT;
478
479 for (String versionLabel : versionLabels) {
480 if (DLUtil.compareVersions(versionLabel, headVersionLabel) > 0) {
481 headVersionLabel = versionLabel;
482 }
483 }
484
485 return headVersionLabel;
486 }
487
488 protected File getRepositoryDir(long companyId, long repositoryId) {
489 RepositoryDirKey repositoryDirKey = new RepositoryDirKey(
490 companyId, repositoryId);
491
492 File repositoryDir = _repositoryDirs.get(repositoryDirKey);
493
494 if (repositoryDir == null) {
495 File companyDir = getCompanyDir(companyId);
496
497 repositoryDir = new File(
498 companyDir + StringPool.SLASH + repositoryId);
499
500 if (!repositoryDir.exists()) {
501 repositoryDir.mkdirs();
502 }
503
504 _repositoryDirs.put(repositoryDirKey, repositoryDir);
505 }
506
507 return repositoryDir;
508 }
509
510 private Map<RepositoryDirKey, File> _repositoryDirs =
511 new ConcurrentHashMap<RepositoryDirKey, File>();
512 private File _rootDir = new File(PropsValues.DL_STORE_FILE_SYSTEM_ROOT_DIR);
513
514 private class RepositoryDirKey {
515
516 public RepositoryDirKey(long companyId, long repositoryId) {
517 _companyId = companyId;
518 _repositoryId = repositoryId;
519 }
520
521 @Override
522 public boolean equals(Object obj) {
523 RepositoryDirKey repositoryDirKey = (RepositoryDirKey)obj;
524
525 if ((_companyId == repositoryDirKey._companyId) &&
526 (_repositoryId == repositoryDirKey._repositoryId)) {
527
528 return true;
529 }
530 else {
531 return false;
532 }
533 }
534
535 @Override
536 public int hashCode() {
537 return (int)(_companyId * 11 + _repositoryId);
538 }
539
540 private long _companyId;
541 private long _repositoryId;
542
543 }
544
545 }