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