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