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