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