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, validateFileExtension,
408 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, validateFileExtension, is);
438
439 if (!PropsValues.DL_STORE_ANTIVIRUS_ENABLED ||
440 !AntivirusScannerUtil.isActive()) {
441
442 store.updateFile(
443 companyId, repositoryId, fileName, versionLabel, is);
444 }
445 else {
446 File tempFile = null;
447
448 try {
449 if (is.markSupported()) {
450 is.mark(is.available() + 1);
451
452 AntivirusScannerUtil.scan(is);
453
454 is.reset();
455
456 store.updateFile(
457 companyId, repositoryId, fileName, versionLabel, is);
458 }
459 else {
460 tempFile = FileUtil.createTempFile();
461
462 FileUtil.write(tempFile, is);
463
464 AntivirusScannerUtil.scan(tempFile);
465
466 store.updateFile(
467 companyId, repositoryId, fileName, versionLabel,
468 tempFile);
469 }
470 }
471 catch (IOException ioe) {
472 throw new SystemException(
473 "Unable to scan file " + fileName, ioe);
474 }
475 finally {
476 if (tempFile != null) {
477 tempFile.delete();
478 }
479 }
480 }
481 }
482
483 public void updateFileVersion(
484 long companyId, long repositoryId, String fileName,
485 String fromVersionLabel, String toVersionLabel)
486 throws PortalException, SystemException {
487
488 store.updateFileVersion(
489 companyId, repositoryId, fileName, fromVersionLabel,
490 toVersionLabel);
491 }
492
493 public void validate(String fileName, boolean validateFileExtension)
494 throws PortalException, SystemException {
495
496 if (!isValidName(fileName)) {
497 throw new FileNameException(fileName);
498 }
499
500 if (validateFileExtension) {
501 boolean validFileExtension = false;
502
503 String[] fileExtensions = PrefsPropsUtil.getStringArray(
504 PropsKeys.DL_FILE_EXTENSIONS, StringPool.COMMA);
505
506 for (int i = 0; i < fileExtensions.length; i++) {
507 if (StringPool.STAR.equals(fileExtensions[i]) ||
508 StringUtil.endsWith(fileName, fileExtensions[i])) {
509
510 validFileExtension = true;
511
512 break;
513 }
514 }
515
516 if (!validFileExtension) {
517 throw new FileExtensionException(fileName);
518 }
519 }
520 }
521
522 public void validate(
523 String fileName, boolean validateFileExtension, byte[] bytes)
524 throws PortalException, SystemException {
525
526 validate(fileName, validateFileExtension);
527
528 if ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
529 ((bytes == null) ||
530 (bytes.length >
531 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
532
533 throw new FileSizeException(fileName);
534 }
535 }
536
537 public void validate(
538 String fileName, boolean validateFileExtension, File file)
539 throws PortalException, SystemException {
540
541 validate(fileName, validateFileExtension);
542
543 if ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
544 ((file == null) ||
545 (file.length() >
546 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
547
548 throw new FileSizeException(fileName);
549 }
550 }
551
552 public void validate(
553 String fileName, boolean validateFileExtension, InputStream is)
554 throws PortalException, SystemException {
555
556 validate(fileName, validateFileExtension);
557
558
559
560 try {
561 if ((is == null) ||
562 ((PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
563 (is.available() >
564 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE)))) {
565
566 throw new FileSizeException(fileName);
567 }
568 }
569 catch (IOException ioe) {
570 throw new FileSizeException(ioe.getMessage());
571 }
572 }
573
574 public void validate(
575 String fileName, String fileExtension, String sourceFileName,
576 boolean validateFileExtension, File file)
577 throws PortalException, SystemException {
578
579 validate(
580 fileName, fileExtension, sourceFileName, validateFileExtension);
581
582 if ((file != null) &&
583 (PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
584 (file.length() >
585 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE))) {
586
587 throw new FileSizeException(fileName);
588 }
589 }
590
591 public void validate(
592 String fileName, String fileExtension, String sourceFileName,
593 boolean validateFileExtension, InputStream is)
594 throws PortalException, SystemException {
595
596 validate(
597 fileName, fileExtension, sourceFileName, validateFileExtension);
598
599 try {
600 if ((is != null) &&
601 (PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE) > 0) &&
602 (is.available() >
603 PrefsPropsUtil.getLong(PropsKeys.DL_FILE_MAX_SIZE))) {
604
605 throw new FileSizeException(fileName);
606 }
607 }
608 catch (IOException ioe) {
609 throw new FileSizeException(ioe.getMessage());
610 }
611 }
612
613 protected boolean isValidName(String name) {
614 if ((name == null) ||
615 name.contains("\\") ||
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
630 return false;
631 }
632
633 return true;
634 }
635
636 protected void validate(
637 String fileName, String fileExtension, String sourceFileName,
638 boolean validateFileExtension)
639 throws PortalException, SystemException {
640
641 String sourceFileExtension = FileUtil.getExtension(sourceFileName);
642
643 if (Validator.isNotNull(sourceFileName) &&
644 PropsValues.DL_FILE_EXTENSIONS_STRICT_CHECK &&
645 !fileExtension.equals(sourceFileExtension)) {
646
647 throw new SourceFileNameException(sourceFileExtension);
648 }
649
650 validate(fileName, validateFileExtension);
651 }
652
653 @BeanReference(type = GroupLocalService.class)
654 protected GroupLocalService groupLocalService;
655
656 @BeanReference(type = Store.class)
657 protected Store store;
658
659 private static final String[] _KEYWORDS_FIELDS = {
660 Field.ASSET_TAG_NAMES, Field.CONTENT, Field.PROPERTIES
661 };
662
663 }