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 validate(fileName, false);
208
209 store.deleteFile(companyId, repositoryId, fileName);
210 }
211
212 public void deleteFile(
213 long companyId, long repositoryId, String fileName,
214 String versionLabel)
215 throws PortalException, SystemException {
216
217 validate(fileName, false);
218
219 store.deleteFile(companyId, repositoryId, fileName, versionLabel);
220 }
221
222 public File getFile(long companyId, long repositoryId, String fileName)
223 throws PortalException, SystemException {
224
225 validate(fileName, false);
226
227 return store.getFile(companyId, repositoryId, fileName);
228 }
229
230 public File getFile(
231 long companyId, long repositoryId, String fileName,
232 String versionLabel)
233 throws PortalException, SystemException {
234
235 validate(fileName, false);
236
237 return store.getFile(companyId, repositoryId, fileName, versionLabel);
238 }
239
240 public byte[] getFileAsBytes(
241 long companyId, long repositoryId, String fileName)
242 throws PortalException, SystemException {
243
244 validate(fileName, false);
245
246 return store.getFileAsBytes(companyId, repositoryId, fileName);
247 }
248
249 public byte[] getFileAsBytes(
250 long companyId, long repositoryId, String fileName,
251 String versionLabel)
252 throws PortalException, SystemException {
253
254 validate(fileName, false);
255
256 return store.getFileAsBytes(
257 companyId, repositoryId, fileName, versionLabel);
258 }
259
260 public InputStream getFileAsStream(
261 long companyId, long repositoryId, String fileName)
262 throws PortalException, SystemException {
263
264 validate(fileName, false);
265
266 return store.getFileAsStream(companyId, repositoryId, fileName);
267 }
268
269 public InputStream getFileAsStream(
270 long companyId, long repositoryId, String fileName,
271 String versionLabel)
272 throws PortalException, SystemException {
273
274 validate(fileName, false);
275
276 return store.getFileAsStream(
277 companyId, repositoryId, fileName, versionLabel);
278 }
279
280 public String[] getFileNames(
281 long companyId, long repositoryId, String dirName)
282 throws PortalException, SystemException {
283
284 if (!isValidName(dirName)) {
285 throw new DirectoryNameException(dirName);
286 }
287
288 return store.getFileNames(companyId, repositoryId, dirName);
289 }
290
291 public long getFileSize(long companyId, long repositoryId, String fileName)
292 throws PortalException, SystemException {
293
294 validate(fileName, false);
295
296 return store.getFileSize(companyId, repositoryId, fileName);
297 }
298
299 public boolean hasDirectory(
300 long companyId, long repositoryId, String dirName)
301 throws PortalException, SystemException {
302
303 if (!isValidName(dirName)) {
304 throw new DirectoryNameException(dirName);
305 }
306
307 return store.hasDirectory(companyId, repositoryId, dirName);
308 }
309
310 public boolean hasFile(long companyId, long repositoryId, String fileName)
311 throws PortalException, SystemException {
312
313 validate(fileName, false);
314
315 return store.hasFile(companyId, repositoryId, fileName);
316 }
317
318 public boolean hasFile(
319 long companyId, long repositoryId, String fileName,
320 String versionLabel)
321 throws PortalException, SystemException {
322
323 validate(fileName, false);
324
325 return store.hasFile(companyId, repositoryId, fileName, versionLabel);
326 }
327
328 public void move(String srcDir, String destDir) throws SystemException {
329 store.move(srcDir, destDir);
330 }
331
332 public Hits search(
333 long companyId, long userId, String portletId, long groupId,
334 long[] repositoryIds, String keywords, int start, int end)
335 throws SystemException {
336
337 try {
338 SearchContext searchContext = new SearchContext();
339
340 searchContext.setCompanyId(companyId);
341 searchContext.setEnd(end);
342 searchContext.setEntryClassNames(
343 new String[] {DLFileEntryConstants.getClassName()});
344 searchContext.setGroupIds(new long[] {groupId});
345
346 Indexer indexer = IndexerRegistryUtil.getIndexer(
347 DLFileEntryConstants.getClassName());
348
349 searchContext.setSearchEngineId(indexer.getSearchEngineId());
350
351 searchContext.setStart(start);
352 searchContext.setUserId(userId);
353
354 BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(
355 searchContext);
356
357 contextQuery.addRequiredTerm(Field.PORTLET_ID, portletId);
358
359 if (groupId > 0) {
360 Group group = groupLocalService.getGroup(groupId);
361
362 if (group.isLayout()) {
363 contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
364
365 groupId = group.getParentGroupId();
366 }
367
368 contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
369 }
370
371 if ((repositoryIds != null) && (repositoryIds.length > 0)) {
372 BooleanQuery repositoryIdsQuery =
373 BooleanQueryFactoryUtil.create(searchContext);
374
375 for (long repositoryId : repositoryIds) {
376 try {
377 if (userId > 0) {
378 PermissionChecker permissionChecker =
379 PermissionThreadLocal.getPermissionChecker();
380
381 DLFolderPermission.check(
382 permissionChecker, groupId, repositoryId,
383 ActionKeys.VIEW);
384 }
385
386 if (repositoryId ==
387 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
388
389 repositoryId = groupId;
390 }
391
392 TermQuery termQuery = TermQueryFactoryUtil.create(
393 searchContext, "repositoryId", repositoryId);
394
395 repositoryIdsQuery.add(
396 termQuery, BooleanClauseOccur.SHOULD);
397 }
398 catch (Exception e) {
399 }
400 }
401
402 contextQuery.add(repositoryIdsQuery, BooleanClauseOccur.MUST);
403 }
404
405 BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(
406 searchContext);
407
408 searchQuery.addTerms(_KEYWORDS_FIELDS, keywords);
409
410 BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(
411 searchContext);
412
413 fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
414
415 if (searchQuery.clauses().size() > 0) {
416 fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
417 }
418
419 return SearchEngineUtil.search(searchContext, fullQuery);
420 }
421 catch (Exception e) {
422 throw new SystemException(e);
423 }
424 }
425
426 public void updateFile(
427 long companyId, long repositoryId, long newRepositoryId,
428 String fileName)
429 throws PortalException, SystemException {
430
431 store.updateFile(companyId, repositoryId, newRepositoryId, fileName);
432 }
433
434 public void updateFile(
435 long companyId, long repositoryId, String fileName,
436 String newFileName)
437 throws PortalException, SystemException {
438
439 store.updateFile(companyId, repositoryId, fileName, newFileName);
440 }
441
442 public void updateFile(
443 long companyId, long repositoryId, String fileName,
444 String fileExtension, boolean validateFileExtension,
445 String versionLabel, String sourceFileName, File file)
446 throws PortalException, SystemException {
447
448 validate(
449 fileName, fileExtension, sourceFileName, validateFileExtension,
450 file);
451
452 if (PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
453 AntivirusScannerUtil.scan(file);
454 }
455
456 store.updateFile(companyId, repositoryId, fileName, versionLabel, file);
457 }
458
459 public void updateFile(
460 long companyId, long repositoryId, String fileName,
461 String fileExtension, boolean validateFileExtension,
462 String versionLabel, String sourceFileName, InputStream is)
463 throws PortalException, SystemException {
464
465 if (is instanceof ByteArrayFileInputStream) {
466 ByteArrayFileInputStream byteArrayFileInputStream =
467 (ByteArrayFileInputStream)is;
468
469 File file = byteArrayFileInputStream.getFile();
470
471 updateFile(
472 companyId, repositoryId, fileName, fileExtension,
473 validateFileExtension, versionLabel, sourceFileName, file);
474
475 return;
476 }
477
478 validate(
479 fileName, fileExtension, sourceFileName, validateFileExtension, is);
480
481 if (!PropsValues.DL_STORE_ANTIVIRUS_ENABLED ||
482 !AntivirusScannerUtil.isActive()) {
483
484 store.updateFile(
485 companyId, repositoryId, fileName, versionLabel, is);
486 }
487 else {
488 File tempFile = null;
489
490 try {
491 if (is.markSupported()) {
492 is.mark(is.available() + 1);
493
494 AntivirusScannerUtil.scan(is);
495
496 is.reset();
497
498 store.updateFile(
499 companyId, repositoryId, fileName, versionLabel, is);
500 }
501 else {
502 tempFile = FileUtil.createTempFile();
503
504 FileUtil.write(tempFile, is);
505
506 AntivirusScannerUtil.scan(tempFile);
507
508 store.updateFile(
509 companyId, repositoryId, fileName, versionLabel,
510 tempFile);
511 }
512 }
513 catch (IOException ioe) {
514 throw new SystemException(
515 "Unable to scan file " + fileName, ioe);
516 }
517 finally {
518 if (tempFile != null) {
519 tempFile.delete();
520 }
521 }
522 }
523 }
524
525 public void updateFileVersion(
526 long companyId, long repositoryId, String fileName,
527 String fromVersionLabel, String toVersionLabel)
528 throws PortalException, SystemException {
529
530 store.updateFileVersion(
531 companyId, repositoryId, fileName, fromVersionLabel,
532 toVersionLabel);
533 }
534
535 public void validate(String fileName, boolean validateFileExtension)
536 throws PortalException, SystemException {
537
538 if (!isValidName(fileName)) {
539 throw new FileNameException(fileName);
540 }
541
542 if (validateFileExtension) {
543 boolean validFileExtension = false;
544
545 String[] fileExtensions = PrefsPropsUtil.getStringArray(
546 PropsKeys.DL_FILE_EXTENSIONS, StringPool.COMMA);
547
548 for (String fileExtension : fileExtensions) {
549 if (StringPool.STAR.equals(fileExtension) ||
550 StringUtil.endsWith(fileName, fileExtension)) {
551
552 validFileExtension = true;
553
554 break;
555 }
556 }
557
558 if (!validFileExtension) {
559 throw new FileExtensionException(fileName);
560 }
561 }
562 }
563
564 public void validate(
565 String fileName, boolean validateFileExtension, byte[] bytes)
566 throws PortalException, SystemException {
567
568 validate(fileName, validateFileExtension);
569
570 if ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
571 ((bytes == null) ||
572 (bytes.length >
573 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
574
575 throw new FileSizeException(fileName);
576 }
577 }
578
579 public void validate(
580 String fileName, boolean validateFileExtension, File file)
581 throws PortalException, SystemException {
582
583 validate(fileName, validateFileExtension);
584
585 if ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
586 ((file == null) ||
587 (file.length() >
588 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
589
590 throw new FileSizeException(fileName);
591 }
592 }
593
594 public void validate(
595 String fileName, boolean validateFileExtension, InputStream is)
596 throws PortalException, SystemException {
597
598 validate(fileName, validateFileExtension);
599
600
601
602 try {
603 if ((is == null) ||
604 ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
605 (is.available() >
606 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
607
608 throw new FileSizeException(fileName);
609 }
610 }
611 catch (IOException ioe) {
612 throw new FileSizeException(ioe.getMessage());
613 }
614 }
615
616 public void validate(
617 String fileName, String fileExtension, String sourceFileName,
618 boolean validateFileExtension, File file)
619 throws PortalException, SystemException {
620
621 validate(
622 fileName, fileExtension, sourceFileName, validateFileExtension);
623
624 if ((file != null) &&
625 (PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
626 (file.length() >
627 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE))) {
628
629 throw new FileSizeException(fileName);
630 }
631 }
632
633 public void validate(
634 String fileName, String fileExtension, String sourceFileName,
635 boolean validateFileExtension, InputStream is)
636 throws PortalException, SystemException {
637
638 validate(
639 fileName, fileExtension, sourceFileName, validateFileExtension);
640
641 try {
642 if ((is != null) &&
643 (PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
644 (is.available() >
645 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE))) {
646
647 throw new FileSizeException(fileName);
648 }
649 }
650 catch (IOException ioe) {
651 throw new FileSizeException(ioe.getMessage());
652 }
653 }
654
655 protected boolean isValidName(String name) {
656 if ((name == null) ||
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 name.contains("[") ||
668 name.contains("]") ||
669 name.contains("../") ||
670 name.contains("/..")) {
671
672 return false;
673 }
674
675 return true;
676 }
677
678 protected void validate(
679 String fileName, String fileExtension, String sourceFileName,
680 boolean validateFileExtension)
681 throws PortalException, SystemException {
682
683 String sourceFileExtension = FileUtil.getExtension(sourceFileName);
684
685 if (Validator.isNotNull(sourceFileName) &&
686 PropsValues.DL_FILE_EXTENSIONS_STRICT_CHECK &&
687 !fileExtension.equals(sourceFileExtension)) {
688
689 throw new SourceFileNameException(sourceFileExtension);
690 }
691
692 validate(fileName, validateFileExtension);
693 }
694
695 @BeanReference(type = GroupLocalService.class)
696 protected GroupLocalService groupLocalService;
697
698 @BeanReference(type = Store.class)
699 protected Store store;
700
701 private static final String[] _KEYWORDS_FIELDS = {
702 Field.ASSET_TAG_NAMES, Field.CONTENT, Field.PROPERTIES
703 };
704
705 }