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 File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
313 File newFileNameDir = getFileNameDir(
314 companyId, newRepositoryId, fileName);
315
316 if (newFileNameDir.exists()) {
317 throw new DuplicateFileException(fileName);
318 }
319
320 File parentFile = fileNameDir.getParentFile();
321
322 boolean renamed = FileUtil.move(fileNameDir, newFileNameDir);
323
324 if (!renamed) {
325 throw new SystemException(
326 "File name directory was not renamed from " +
327 fileNameDir.getPath() + " to " + newFileNameDir.getPath());
328 }
329
330 deleteEmptyAncestors(companyId, repositoryId, parentFile);
331 }
332
333 @Override
334 public void updateFile(
335 long companyId, long repositoryId, String fileName,
336 String newFileName)
337 throws PortalException, SystemException {
338
339 File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
340 File newFileNameDir = getFileNameDir(
341 companyId, repositoryId, newFileName);
342
343 if (newFileNameDir.exists()) {
344 throw new DuplicateFileException(newFileName);
345 }
346
347 File parentFile = fileNameDir.getParentFile();
348
349 boolean renamed = FileUtil.move(fileNameDir, newFileNameDir);
350
351 if (!renamed) {
352 throw new SystemException(
353 "File name directory was not renamed from " +
354 fileNameDir.getPath() + " to " + newFileNameDir.getPath());
355 }
356
357 deleteEmptyAncestors(companyId, repositoryId, parentFile);
358 }
359
360 @Override
361 public void updateFile(
362 long companyId, long repositoryId, String fileName,
363 String versionLabel, InputStream is)
364 throws PortalException, SystemException {
365
366 try {
367 File fileNameVersionFile = getFileNameVersionFile(
368 companyId, repositoryId, fileName, versionLabel);
369
370 if (fileNameVersionFile.exists()) {
371 throw new DuplicateFileException(fileNameVersionFile.getPath());
372 }
373
374 FileUtil.write(fileNameVersionFile, is);
375 }
376 catch (IOException ioe) {
377 throw new SystemException(ioe);
378 }
379 }
380
381 @Override
382 public void updateFileVersion(
383 long companyId, long repositoryId, String fileName,
384 String fromVersionLabel, String toVersionLabel)
385 throws PortalException, SystemException {
386
387 File fromFileNameVersionFile = getFileNameVersionFile(
388 companyId, repositoryId, fileName, fromVersionLabel);
389
390 File toFileNameVersionFile = getFileNameVersionFile(
391 companyId, repositoryId, fileName, toVersionLabel);
392
393 if (toFileNameVersionFile.exists()) {
394 throw new DuplicateFileException(toFileNameVersionFile.getPath());
395 }
396
397 boolean renamed = FileUtil.move(
398 fromFileNameVersionFile, toFileNameVersionFile);
399
400 if (!renamed) {
401 throw new SystemException(
402 "File name version file was not renamed from " +
403 fromFileNameVersionFile.getPath() + " to " +
404 toFileNameVersionFile.getPath());
405 }
406 }
407
408 protected void deleteEmptyAncestors(File file) {
409 deleteEmptyAncestors(-1, -1, file);
410 }
411
412 protected void deleteEmptyAncestors(
413 long companyId, long repositoryId, File file) {
414
415 String[] fileNames = file.list();
416
417 if ((fileNames == null) || (fileNames.length > 0)) {
418 return;
419 }
420
421 String fileName = file.getName();
422
423 if ((repositoryId > 0) &&
424 fileName.equals(String.valueOf(repositoryId))) {
425
426 RepositoryDirKey repositoryDirKey = new RepositoryDirKey(
427 companyId, repositoryId);
428
429 _repositoryDirs.remove(repositoryDirKey);
430 }
431
432 File parentFile = file.getParentFile();
433
434 if (file.delete() && (parentFile != null)) {
435 deleteEmptyAncestors(companyId, repositoryId, parentFile);
436 }
437 }
438
439 protected File getCompanyDir(long companyId) {
440 File companyDir = new File(_rootDir + StringPool.SLASH + companyId);
441
442 try {
443 FileUtil.mkdirs(companyDir);
444 }
445 catch (IOException ioe) {
446 ReflectionUtil.throwException(ioe);
447 }
448
449 return companyDir;
450 }
451
452 protected File getDirNameDir(
453 long companyId, long repositoryId, String dirName) {
454
455 return getFileNameDir(companyId, repositoryId, dirName);
456 }
457
458 protected File getFileNameDir(
459 long companyId, long repositoryId, String fileName) {
460
461 File repositoryDir = getRepositoryDir(companyId, repositoryId);
462
463 File fileNameDir = new File(
464 repositoryDir + StringPool.SLASH + fileName);
465
466 return fileNameDir;
467 }
468
469 protected File getFileNameVersionFile(
470 long companyId, long repositoryId, String fileName, String version) {
471
472 File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
473
474 File fileNameVersionFile = new File(
475 fileNameDir + StringPool.SLASH + version);
476
477 return fileNameVersionFile;
478 }
479
480 protected String getHeadVersionLabel(
481 long companyId, long repositoryId, String fileName) {
482
483 File fileNameDir = getFileNameDir(companyId, repositoryId, fileName);
484
485 if (!fileNameDir.exists()) {
486 return VERSION_DEFAULT;
487 }
488
489 String[] versionLabels = FileUtil.listFiles(fileNameDir);
490
491 String headVersionLabel = VERSION_DEFAULT;
492
493 for (String versionLabel : versionLabels) {
494 if (DLUtil.compareVersions(versionLabel, headVersionLabel) > 0) {
495 headVersionLabel = versionLabel;
496 }
497 }
498
499 return headVersionLabel;
500 }
501
502 protected File getRepositoryDir(long companyId, long repositoryId) {
503 RepositoryDirKey repositoryDirKey = new RepositoryDirKey(
504 companyId, repositoryId);
505
506 File repositoryDir = _repositoryDirs.get(repositoryDirKey);
507
508 if (repositoryDir == null) {
509 File companyDir = getCompanyDir(companyId);
510
511 repositoryDir = new File(
512 companyDir + StringPool.SLASH + repositoryId);
513
514 try {
515 FileUtil.mkdirs(repositoryDir);
516 }
517 catch (IOException ioe) {
518 ReflectionUtil.throwException(ioe);
519 }
520
521 _repositoryDirs.put(repositoryDirKey, repositoryDir);
522 }
523
524 return repositoryDir;
525 }
526
527 private Map<RepositoryDirKey, File> _repositoryDirs =
528 new ConcurrentHashMap<RepositoryDirKey, File>();
529 private File _rootDir = new File(PropsValues.DL_STORE_FILE_SYSTEM_ROOT_DIR);
530
531 private class RepositoryDirKey {
532
533 public RepositoryDirKey(long companyId, long repositoryId) {
534 _companyId = companyId;
535 _repositoryId = repositoryId;
536 }
537
538 @Override
539 public boolean equals(Object obj) {
540 RepositoryDirKey repositoryDirKey = (RepositoryDirKey)obj;
541
542 if ((_companyId == repositoryDirKey._companyId) &&
543 (_repositoryId == repositoryDirKey._repositoryId)) {
544
545 return true;
546 }
547 else {
548 return false;
549 }
550 }
551
552 @Override
553 public int hashCode() {
554 return (int)(_companyId * 11 + _repositoryId);
555 }
556
557 private long _companyId;
558 private long _repositoryId;
559
560 }
561
562 }