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