001
014
015 package com.liferay.portlet.documentlibrary.store;
016
017 import com.liferay.portal.kernel.bean.BeanReference;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.io.ByteArrayFileInputStream;
021 import com.liferay.portal.kernel.search.BooleanClauseOccur;
022 import com.liferay.portal.kernel.search.BooleanQuery;
023 import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
024 import com.liferay.portal.kernel.search.Field;
025 import com.liferay.portal.kernel.search.Hits;
026 import com.liferay.portal.kernel.search.Indexer;
027 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
028 import com.liferay.portal.kernel.search.SearchContext;
029 import com.liferay.portal.kernel.search.SearchEngineUtil;
030 import com.liferay.portal.kernel.search.TermQuery;
031 import com.liferay.portal.kernel.search.TermQueryFactoryUtil;
032 import com.liferay.portal.kernel.util.FileUtil;
033 import com.liferay.portal.kernel.util.PropsKeys;
034 import com.liferay.portal.kernel.util.StringPool;
035 import com.liferay.portal.kernel.util.StringUtil;
036 import com.liferay.portal.kernel.util.Validator;
037 import com.liferay.portal.model.Group;
038 import com.liferay.portal.security.permission.ActionKeys;
039 import com.liferay.portal.security.permission.PermissionChecker;
040 import com.liferay.portal.security.permission.PermissionThreadLocal;
041 import com.liferay.portal.service.GroupLocalService;
042 import com.liferay.portal.util.PrefsPropsUtil;
043 import com.liferay.portal.util.PropsValues;
044 import com.liferay.portlet.documentlibrary.DirectoryNameException;
045 import com.liferay.portlet.documentlibrary.FileExtensionException;
046 import com.liferay.portlet.documentlibrary.FileNameException;
047 import com.liferay.portlet.documentlibrary.FileSizeException;
048 import com.liferay.portlet.documentlibrary.SourceFileNameException;
049 import com.liferay.portlet.documentlibrary.antivirus.AntivirusScannerUtil;
050 import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
051 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
052 import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
053
054 import java.io.File;
055 import java.io.IOException;
056 import java.io.InputStream;
057
058
063 public class DLStoreImpl implements DLStore {
064
065 public void addDirectory(long companyId, long repositoryId, String dirName)
066 throws PortalException, SystemException {
067
068 if (!isValidName(dirName) || dirName.equals("/")) {
069 throw new DirectoryNameException(dirName);
070 }
071
072 store.addDirectory(companyId, repositoryId, dirName);
073 }
074
075 public void addFile(
076 long companyId, long repositoryId, String fileName,
077 boolean validateFileExtension, byte[] bytes)
078 throws PortalException, SystemException {
079
080 validate(fileName, validateFileExtension, bytes);
081
082 if (!PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
083 AntivirusScannerUtil.scan(bytes);
084 }
085
086 store.addFile(companyId, repositoryId, fileName, bytes);
087 }
088
089 public void addFile(
090 long companyId, long repositoryId, String fileName,
091 boolean validateFileExtension, File file)
092 throws PortalException, SystemException {
093
094 validate(fileName, validateFileExtension, file);
095
096 if (PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
097 AntivirusScannerUtil.scan(file);
098 }
099
100 store.addFile(companyId, repositoryId, fileName, file);
101 }
102
103 public void addFile(
104 long companyId, long repositoryId, String fileName,
105 boolean validateFileExtension, InputStream is)
106 throws PortalException, SystemException {
107
108 if (is instanceof ByteArrayFileInputStream) {
109 ByteArrayFileInputStream byteArrayFileInputStream =
110 (ByteArrayFileInputStream)is;
111
112 File file = byteArrayFileInputStream.getFile();
113
114 addFile(
115 companyId, repositoryId, fileName, validateFileExtension, file);
116
117 return;
118 }
119
120 validate(fileName, validateFileExtension, is);
121
122 if (!PropsValues.DL_STORE_ANTIVIRUS_ENABLED ||
123 !AntivirusScannerUtil.isActive()) {
124
125 store.addFile(companyId, repositoryId, fileName, is);
126 }
127 else {
128 File tempFile = null;
129
130 try {
131 if (is.markSupported()) {
132 is.mark(is.available() + 1);
133
134 AntivirusScannerUtil.scan(is);
135
136 is.reset();
137
138 store.addFile(companyId, repositoryId, fileName, is);
139 }
140 else {
141 tempFile = FileUtil.createTempFile();
142
143 FileUtil.write(tempFile, is);
144
145 AntivirusScannerUtil.scan(tempFile);
146
147 store.addFile(companyId, repositoryId, fileName, tempFile);
148 }
149 }
150 catch (IOException ioe) {
151 throw new SystemException(
152 "Unable to scan file " + fileName, ioe);
153 }
154 finally {
155 if (tempFile != null) {
156 tempFile.delete();
157 }
158 }
159 }
160 }
161
162 public void addFile(
163 long companyId, long repositoryId, String fileName, byte[] bytes)
164 throws PortalException, SystemException {
165
166 addFile(companyId, repositoryId, fileName, true, bytes);
167 }
168
169 public void addFile(
170 long companyId, long repositoryId, String fileName, File file)
171 throws PortalException, SystemException {
172
173 addFile(companyId, repositoryId, fileName, true, file);
174 }
175
176 public void addFile(
177 long companyId, long repositoryId, String fileName, InputStream is)
178 throws PortalException, SystemException {
179
180 addFile(companyId, repositoryId, fileName, true, is);
181 }
182
183 public void checkRoot(long companyId) throws SystemException {
184 store.checkRoot(companyId);
185 }
186
187 public void copyFileVersion(
188 long companyId, long repositoryId, String fileName,
189 String fromVersionLabel, String toVersionLabel)
190 throws PortalException, SystemException {
191
192 store.copyFileVersion(
193 companyId, repositoryId, fileName, fromVersionLabel,
194 toVersionLabel);
195 }
196
197 public void deleteDirectory(
198 long companyId, long repositoryId, String dirName)
199 throws PortalException, SystemException {
200
201 store.deleteDirectory(companyId, repositoryId, dirName);
202 }
203
204 public void deleteFile(long companyId, long repositoryId, String fileName)
205 throws PortalException, SystemException {
206
207 store.deleteFile(companyId, repositoryId, fileName);
208 }
209
210 public void deleteFile(
211 long companyId, long repositoryId, String fileName,
212 String versionLabel)
213 throws PortalException, SystemException {
214
215 store.deleteFile(companyId, repositoryId, fileName, versionLabel);
216 }
217
218 public File getFile(long companyId, long repositoryId, String fileName)
219 throws PortalException, SystemException {
220
221 validate(fileName, false);
222
223 return store.getFile(companyId, repositoryId, fileName);
224 }
225
226 public File getFile(
227 long companyId, long repositoryId, String fileName,
228 String versionLabel)
229 throws PortalException, SystemException {
230
231 validate(fileName, false);
232
233 return store.getFile(companyId, repositoryId, fileName, versionLabel);
234 }
235
236 public byte[] getFileAsBytes(
237 long companyId, long repositoryId, String fileName)
238 throws PortalException, SystemException {
239
240 validate(fileName, false);
241
242 return store.getFileAsBytes(companyId, repositoryId, fileName);
243 }
244
245 public byte[] getFileAsBytes(
246 long companyId, long repositoryId, String fileName,
247 String versionLabel)
248 throws PortalException, SystemException {
249
250 validate(fileName, false);
251
252 return store.getFileAsBytes(
253 companyId, repositoryId, fileName, versionLabel);
254 }
255
256 public InputStream getFileAsStream(
257 long companyId, long repositoryId, String fileName)
258 throws PortalException, SystemException {
259
260 validate(fileName, false);
261
262 return store.getFileAsStream(companyId, repositoryId, fileName);
263 }
264
265 public InputStream getFileAsStream(
266 long companyId, long repositoryId, String fileName,
267 String versionLabel)
268 throws PortalException, SystemException {
269
270 validate(fileName, false);
271
272 return store.getFileAsStream(
273 companyId, repositoryId, fileName, versionLabel);
274 }
275
276 public String[] getFileNames(
277 long companyId, long repositoryId, String dirName)
278 throws PortalException, SystemException {
279
280 if (!isValidName(dirName)) {
281 throw new DirectoryNameException(dirName);
282 }
283
284 return store.getFileNames(companyId, repositoryId, dirName);
285 }
286
287 public long getFileSize(long companyId, long repositoryId, String fileName)
288 throws PortalException, SystemException {
289
290 validate(fileName, false);
291
292 return store.getFileSize(companyId, repositoryId, fileName);
293 }
294
295 public boolean hasDirectory(
296 long companyId, long repositoryId, String dirName)
297 throws PortalException, SystemException {
298
299 if (!isValidName(dirName)) {
300 throw new DirectoryNameException(dirName);
301 }
302
303 return store.hasDirectory(companyId, repositoryId, dirName);
304 }
305
306 public boolean hasFile(long companyId, long repositoryId, String fileName)
307 throws PortalException, SystemException {
308
309 validate(fileName, false);
310
311 return store.hasFile(companyId, repositoryId, fileName);
312 }
313
314 public boolean hasFile(
315 long companyId, long repositoryId, String fileName,
316 String versionLabel)
317 throws PortalException, SystemException {
318
319 validate(fileName, false);
320
321 return store.hasFile(companyId, repositoryId, fileName, versionLabel);
322 }
323
324 public void move(String srcDir, String destDir) throws SystemException {
325 store.move(srcDir, destDir);
326 }
327
328 public Hits search(
329 long companyId, long userId, String portletId, long groupId,
330 long[] repositoryIds, String keywords, int start, int end)
331 throws SystemException {
332
333 try {
334 SearchContext searchContext = new SearchContext();
335
336 searchContext.setCompanyId(companyId);
337 searchContext.setEnd(end);
338 searchContext.setEntryClassNames(
339 new String[] {DLFileEntryConstants.getClassName()});
340 searchContext.setGroupIds(new long[] {groupId});
341
342 Indexer indexer = IndexerRegistryUtil.getIndexer(
343 DLFileEntryConstants.getClassName());
344
345 searchContext.setSearchEngineId(indexer.getSearchEngineId());
346
347 searchContext.setStart(start);
348 searchContext.setUserId(userId);
349
350 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(
351 searchContext);
352
353 contextQuery.addRequiredTerm(Field.PORTLET_ID, portletId);
354
355 if (groupId > 0) {
356 Group group = groupLocalService.getGroup(groupId);
357
358 if (group.isLayout()) {
359 contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
360
361 groupId = group.getParentGroupId();
362 }
363
364 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
365 }
366
367 if ((repositoryIds != null) && (repositoryIds.length > 0)) {
368 BooleanQuery repositoryIdsQuery =
369 BooleanQueryFactoryUtil.create(searchContext);
370
371 for (long repositoryId : repositoryIds) {
372 try {
373 if (userId > 0) {
374 PermissionChecker permissionChecker =
375 PermissionThreadLocal.getPermissionChecker();
376
377 DLFolderPermission.check(
378 permissionChecker, groupId, repositoryId,
379 ActionKeys.VIEW);
380 }
381
382 if (repositoryId ==
383 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
384
385 repositoryId = groupId;
386 }
387
388 TermQuery termQuery = TermQueryFactoryUtil.create(
389 searchContext, "repositoryId", repositoryId);
390
391 repositoryIdsQuery.add(
392 termQuery, BooleanClauseOccur.SHOULD);
393 }
394 catch (Exception e) {
395 }
396 }
397
398 contextQuery.add(repositoryIdsQuery, BooleanClauseOccur.MUST);
399 }
400
401 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(
402 searchContext);
403
404 searchQuery.addTerms(_KEYWORDS_FIELDS, keywords);
405
406 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(
407 searchContext);
408
409 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
410
411 if (searchQuery.clauses().size() > 0) {
412 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
413 }
414
415 return SearchEngineUtil.search(searchContext, fullQuery);
416 }
417 catch (Exception e) {
418 throw new SystemException(e);
419 }
420 }
421
422 public void updateFile(
423 long companyId, long repositoryId, long newRepositoryId,
424 String fileName)
425 throws PortalException, SystemException {
426
427 store.updateFile(companyId, repositoryId, newRepositoryId, fileName);
428 }
429
430 public void updateFile(
431 long companyId, long repositoryId, String fileName,
432 String newFileName)
433 throws PortalException, SystemException {
434
435 store.updateFile(companyId, repositoryId, fileName, newFileName);
436 }
437
438 public void updateFile(
439 long companyId, long repositoryId, String fileName,
440 String fileExtension, boolean validateFileExtension,
441 String versionLabel, String sourceFileName, File file)
442 throws PortalException, SystemException {
443
444 validate(
445 fileName, fileExtension, sourceFileName, validateFileExtension,
446 file);
447
448 if (!PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
449 AntivirusScannerUtil.scan(file);
450 }
451
452 store.updateFile(companyId, repositoryId, fileName, versionLabel, file);
453 }
454
455 public void updateFile(
456 long companyId, long repositoryId, String fileName,
457 String fileExtension, boolean validateFileExtension,
458 String versionLabel, String sourceFileName, InputStream is)
459 throws PortalException, SystemException {
460
461 if (is instanceof ByteArrayFileInputStream) {
462 ByteArrayFileInputStream byteArrayFileInputStream =
463 (ByteArrayFileInputStream)is;
464
465 File file = byteArrayFileInputStream.getFile();
466
467 updateFile(
468 companyId, repositoryId, fileName, fileExtension,
469 validateFileExtension, versionLabel, sourceFileName, file);
470
471 return;
472 }
473
474 validate(
475 fileName, fileExtension, sourceFileName, validateFileExtension, is);
476
477 if (!PropsValues.DL_STORE_ANTIVIRUS_ENABLED ||
478 !AntivirusScannerUtil.isActive()) {
479
480 store.updateFile(
481 companyId, repositoryId, fileName, versionLabel, is);
482 }
483 else {
484 File tempFile = null;
485
486 try {
487 if (is.markSupported()) {
488 is.mark(is.available() + 1);
489
490 AntivirusScannerUtil.scan(is);
491
492 is.reset();
493
494 store.updateFile(
495 companyId, repositoryId, fileName, versionLabel, is);
496 }
497 else {
498 tempFile = FileUtil.createTempFile();
499
500 FileUtil.write(tempFile, is);
501
502 AntivirusScannerUtil.scan(tempFile);
503
504 store.updateFile(
505 companyId, repositoryId, fileName, versionLabel,
506 tempFile);
507 }
508 }
509 catch (IOException ioe) {
510 throw new SystemException(
511 "Unable to scan file " + fileName, ioe);
512 }
513 finally {
514 if (tempFile != null) {
515 tempFile.delete();
516 }
517 }
518 }
519 }
520
521 public void updateFileVersion(
522 long companyId, long repositoryId, String fileName,
523 String fromVersionLabel, String toVersionLabel)
524 throws PortalException, SystemException {
525
526 store.updateFileVersion(
527 companyId, repositoryId, fileName, fromVersionLabel,
528 toVersionLabel);
529 }
530
531 public void validate(String fileName, boolean validateFileExtension)
532 throws PortalException, SystemException {
533
534 if (!isValidName(fileName)) {
535 throw new FileNameException(fileName);
536 }
537
538 if (validateFileExtension) {
539 boolean validFileExtension = false;
540
541 String[] fileExtensions = PrefsPropsUtil.getStringArray(
542 PropsKeys.DL_FILE_EXTENSIONS, StringPool.COMMA);
543
544 for (String fileExtension : fileExtensions) {
545 if (StringPool.STAR.equals(fileExtension) ||
546 StringUtil.endsWith(fileName, fileExtension)) {
547
548 validFileExtension = true;
549
550 break;
551 }
552 }
553
554 if (!validFileExtension) {
555 throw new FileExtensionException(fileName);
556 }
557 }
558 }
559
560 public void validate(
561 String fileName, boolean validateFileExtension, byte[] bytes)
562 throws PortalException, SystemException {
563
564 validate(fileName, validateFileExtension);
565
566 if ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
567 ((bytes == null) ||
568 (bytes.length >
569 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
570
571 throw new FileSizeException(fileName);
572 }
573 }
574
575 public void validate(
576 String fileName, boolean validateFileExtension, File file)
577 throws PortalException, SystemException {
578
579 validate(fileName, validateFileExtension);
580
581 if ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
582 ((file == null) ||
583 (file.length() >
584 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
585
586 throw new FileSizeException(fileName);
587 }
588 }
589
590 public void validate(
591 String fileName, boolean validateFileExtension, InputStream is)
592 throws PortalException, SystemException {
593
594 validate(fileName, validateFileExtension);
595
596
597
598 try {
599 if ((is == null) ||
600 ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
601 (is.available() >
602 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
603
604 throw new FileSizeException(fileName);
605 }
606 }
607 catch (IOException ioe) {
608 throw new FileSizeException(ioe.getMessage());
609 }
610 }
611
612 public void validate(
613 String fileName, String fileExtension, String sourceFileName,
614 boolean validateFileExtension, File file)
615 throws PortalException, SystemException {
616
617 validate(
618 fileName, fileExtension, sourceFileName, validateFileExtension);
619
620 if ((file != null) &&
621 (PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
622 (file.length() >
623 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE))) {
624
625 throw new FileSizeException(fileName);
626 }
627 }
628
629 public void validate(
630 String fileName, String fileExtension, String sourceFileName,
631 boolean validateFileExtension, InputStream is)
632 throws PortalException, SystemException {
633
634 validate(
635 fileName, fileExtension, sourceFileName, validateFileExtension);
636
637 try {
638 if ((is != null) &&
639 (PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
640 (is.available() >
641 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE))) {
642
643 throw new FileSizeException(fileName);
644 }
645 }
646 catch (IOException ioe) {
647 throw new FileSizeException(ioe.getMessage());
648 }
649 }
650
651 protected boolean isValidName(String name) {
652 if ((name == null) ||
653 name.contains("\\") ||
654 name.contains("\\\\") ||
655 name.contains("
656 name.contains(":") ||
657 name.contains("*") ||
658 name.contains("?") ||
659 name.contains("\"") ||
660 name.contains("<") ||
661 name.contains(">") ||
662 name.contains("|") ||
663 name.contains("[") ||
664 name.contains("]") ||
665 name.contains("../") ||
666 name.contains("/..")) {
667
668 return false;
669 }
670
671 return true;
672 }
673
674 protected void validate(
675 String fileName, String fileExtension, String sourceFileName,
676 boolean validateFileExtension)
677 throws PortalException, SystemException {
678
679 String sourceFileExtension = FileUtil.getExtension(sourceFileName);
680
681 if (Validator.isNotNull(sourceFileName) &&
682 PropsValues.DL_FILE_EXTENSIONS_STRICT_CHECK &&
683 !fileExtension.equals(sourceFileExtension)) {
684
685 throw new SourceFileNameException(sourceFileExtension);
686 }
687
688 validate(fileName, validateFileExtension);
689 }
690
691 @BeanReference(type = GroupLocalService.class)
692 protected GroupLocalService groupLocalService;
693
694 @BeanReference(type = Store.class)
695 protected Store store;
696
697 private static final String[] _KEYWORDS_FIELDS = {
698 Field.ASSET_TAG_NAMES, Field.CONTENT, Field.PROPERTIES
699 };
700
701 }