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