001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.BooleanClause;
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.Indexer;
028    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
029    import com.liferay.portal.kernel.search.SearchContext;
030    import com.liferay.portal.kernel.search.SearchEngineUtil;
031    import com.liferay.portal.kernel.search.TermQuery;
032    import com.liferay.portal.kernel.search.TermQueryFactoryUtil;
033    import com.liferay.portal.kernel.util.ArrayUtil;
034    import com.liferay.portal.kernel.util.FileUtil;
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.PropsValues;
041    import com.liferay.portlet.documentlibrary.DirectoryNameException;
042    import com.liferay.portlet.documentlibrary.antivirus.AntivirusScannerUtil;
043    import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
044    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
045    import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
046    import com.liferay.portlet.documentlibrary.util.DLValidatorUtil;
047    
048    import java.io.File;
049    import java.io.IOException;
050    import java.io.InputStream;
051    
052    import java.util.List;
053    
054    /**
055     * @author Brian Wing Shun Chan
056     * @author Alexander Chow
057     * @author Edward Han
058     */
059    public class DLStoreImpl implements DLStore {
060    
061            @Override
062            public void addDirectory(long companyId, long repositoryId, String dirName)
063                    throws PortalException {
064    
065                    if (!DLValidatorUtil.isValidName(dirName) || dirName.equals("/")) {
066                            throw new DirectoryNameException(dirName);
067                    }
068    
069                    store.addDirectory(companyId, repositoryId, dirName);
070            }
071    
072            @Override
073            public void addFile(
074                            long companyId, long repositoryId, String fileName,
075                            boolean validateFileExtension, byte[] bytes)
076                    throws PortalException {
077    
078                    validate(fileName, validateFileExtension);
079    
080                    if (PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
081                            AntivirusScannerUtil.scan(bytes);
082                    }
083    
084                    store.addFile(companyId, repositoryId, fileName, bytes);
085            }
086    
087            @Override
088            public void addFile(
089                            long companyId, long repositoryId, String fileName,
090                            boolean validateFileExtension, File file)
091                    throws PortalException {
092    
093                    validate(fileName, validateFileExtension);
094    
095                    if (PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
096                            AntivirusScannerUtil.scan(file);
097                    }
098    
099                    store.addFile(companyId, repositoryId, fileName, file);
100            }
101    
102            @Override
103            public void addFile(
104                            long companyId, long repositoryId, String fileName,
105                            boolean validateFileExtension, InputStream is)
106                    throws PortalException {
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);
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            @Override
163            public void addFile(
164                            long companyId, long repositoryId, String fileName, byte[] bytes)
165                    throws PortalException {
166    
167                    addFile(companyId, repositoryId, fileName, true, bytes);
168            }
169    
170            @Override
171            public void addFile(
172                            long companyId, long repositoryId, String fileName, File file)
173                    throws PortalException {
174    
175                    addFile(companyId, repositoryId, fileName, true, file);
176            }
177    
178            @Override
179            public void addFile(
180                            long companyId, long repositoryId, String fileName, InputStream is)
181                    throws PortalException {
182    
183                    addFile(companyId, repositoryId, fileName, true, is);
184            }
185    
186            @Override
187            public void checkRoot(long companyId) {
188                    store.checkRoot(companyId);
189            }
190    
191            @Override
192            public void copyFileVersion(
193                            long companyId, long repositoryId, String fileName,
194                            String fromVersionLabel, String toVersionLabel)
195                    throws PortalException {
196    
197                    store.copyFileVersion(
198                            companyId, repositoryId, fileName, fromVersionLabel,
199                            toVersionLabel);
200            }
201    
202            @Override
203            public void deleteDirectory(
204                            long companyId, long repositoryId, String dirName)
205                    throws PortalException {
206    
207                    store.deleteDirectory(companyId, repositoryId, dirName);
208            }
209    
210            @Override
211            public void deleteFile(long companyId, long repositoryId, String fileName)
212                    throws PortalException {
213    
214                    validate(fileName, false);
215    
216                    store.deleteFile(companyId, repositoryId, fileName);
217            }
218    
219            @Override
220            public void deleteFile(
221                            long companyId, long repositoryId, String fileName,
222                            String versionLabel)
223                    throws PortalException {
224    
225                    validate(fileName, false, versionLabel);
226    
227                    store.deleteFile(companyId, repositoryId, fileName, versionLabel);
228            }
229    
230            @Override
231            public File getFile(long companyId, long repositoryId, String fileName)
232                    throws PortalException {
233    
234                    validate(fileName, false);
235    
236                    return store.getFile(companyId, repositoryId, fileName);
237            }
238    
239            @Override
240            public File getFile(
241                            long companyId, long repositoryId, String fileName,
242                            String versionLabel)
243                    throws PortalException {
244    
245                    validate(fileName, false, versionLabel);
246    
247                    return store.getFile(companyId, repositoryId, fileName, versionLabel);
248            }
249    
250            @Override
251            public byte[] getFileAsBytes(
252                            long companyId, long repositoryId, String fileName)
253                    throws PortalException {
254    
255                    validate(fileName, false);
256    
257                    return store.getFileAsBytes(companyId, repositoryId, fileName);
258            }
259    
260            @Override
261            public byte[] getFileAsBytes(
262                            long companyId, long repositoryId, String fileName,
263                            String versionLabel)
264                    throws PortalException {
265    
266                    validate(fileName, false, versionLabel);
267    
268                    return store.getFileAsBytes(
269                            companyId, repositoryId, fileName, versionLabel);
270            }
271    
272            @Override
273            public InputStream getFileAsStream(
274                            long companyId, long repositoryId, String fileName)
275                    throws PortalException {
276    
277                    validate(fileName, false);
278    
279                    return store.getFileAsStream(companyId, repositoryId, fileName);
280            }
281    
282            @Override
283            public InputStream getFileAsStream(
284                            long companyId, long repositoryId, String fileName,
285                            String versionLabel)
286                    throws PortalException {
287    
288                    validate(fileName, false, versionLabel);
289    
290                    return store.getFileAsStream(
291                            companyId, repositoryId, fileName, versionLabel);
292            }
293    
294            @Override
295            public String[] getFileNames(
296                            long companyId, long repositoryId, String dirName)
297                    throws PortalException {
298    
299                    if (!DLValidatorUtil.isValidName(dirName)) {
300                            throw new DirectoryNameException(dirName);
301                    }
302    
303                    return store.getFileNames(companyId, repositoryId, dirName);
304            }
305    
306            @Override
307            public long getFileSize(long companyId, long repositoryId, String fileName)
308                    throws PortalException {
309    
310                    validate(fileName, false);
311    
312                    return store.getFileSize(companyId, repositoryId, fileName);
313            }
314    
315            @Override
316            public boolean hasDirectory(
317                            long companyId, long repositoryId, String dirName)
318                    throws PortalException {
319    
320                    if (!DLValidatorUtil.isValidName(dirName)) {
321                            throw new DirectoryNameException(dirName);
322                    }
323    
324                    return store.hasDirectory(companyId, repositoryId, dirName);
325            }
326    
327            @Override
328            public boolean hasFile(long companyId, long repositoryId, String fileName)
329                    throws PortalException {
330    
331                    validate(fileName, false);
332    
333                    return store.hasFile(companyId, repositoryId, fileName);
334            }
335    
336            @Override
337            public boolean hasFile(
338                            long companyId, long repositoryId, String fileName,
339                            String versionLabel)
340                    throws PortalException {
341    
342                    validate(fileName, false, versionLabel);
343    
344                    return store.hasFile(companyId, repositoryId, fileName, versionLabel);
345            }
346    
347            /**
348             * @deprecated As of 7.0.0, replaced by {@link
349             *             DLValidatorUtil#isValidName(String)}
350             */
351            @Deprecated
352            @Override
353            public boolean isValidName(String name) {
354                    return DLValidatorUtil.isValidName(name);
355            }
356    
357            @Override
358            public void move(String srcDir, String destDir) {
359                    store.move(srcDir, destDir);
360            }
361    
362            public Hits search(
363                    long companyId, long userId, String portletId, long groupId,
364                    long[] repositoryIds, String keywords, int start, int end) {
365    
366                    try {
367                            SearchContext searchContext = new SearchContext();
368    
369                            searchContext.setCompanyId(companyId);
370                            searchContext.setEnd(end);
371                            searchContext.setEntryClassNames(
372                                    new String[] {DLFileEntryConstants.getClassName()});
373                            searchContext.setGroupIds(new long[] {groupId});
374    
375                            Indexer indexer = IndexerRegistryUtil.getIndexer(
376                                    DLFileEntryConstants.getClassName());
377    
378                            searchContext.setSearchEngineId(indexer.getSearchEngineId());
379    
380                            searchContext.setStart(start);
381                            searchContext.setUserId(userId);
382    
383                            BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(
384                                    searchContext);
385    
386                            contextQuery.addRequiredTerm(Field.PORTLET_ID, portletId);
387    
388                            if (groupId > 0) {
389                                    Group group = groupLocalService.getGroup(groupId);
390    
391                                    if (group.isLayout()) {
392                                            contextQuery.addRequiredTerm(Field.SCOPE_GROUP_ID, groupId);
393    
394                                            groupId = group.getParentGroupId();
395                                    }
396    
397                                    contextQuery.addRequiredTerm(Field.GROUP_ID, groupId);
398                            }
399    
400                            if (ArrayUtil.isNotEmpty(repositoryIds)) {
401                                    BooleanQuery repositoryIdsQuery =
402                                            BooleanQueryFactoryUtil.create(searchContext);
403    
404                                    for (long repositoryId : repositoryIds) {
405                                            try {
406                                                    if (userId > 0) {
407                                                            PermissionChecker permissionChecker =
408                                                                    PermissionThreadLocal.getPermissionChecker();
409    
410                                                            DLFolderPermission.check(
411                                                                    permissionChecker, groupId, repositoryId,
412                                                                    ActionKeys.VIEW);
413                                                    }
414    
415                                                    if (repositoryId ==
416                                                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
417    
418                                                            repositoryId = groupId;
419                                                    }
420    
421                                                    TermQuery termQuery = TermQueryFactoryUtil.create(
422                                                            searchContext, "repositoryId", repositoryId);
423    
424                                                    repositoryIdsQuery.add(
425                                                            termQuery, BooleanClauseOccur.SHOULD);
426                                            }
427                                            catch (Exception e) {
428                                            }
429                                    }
430    
431                                    contextQuery.add(repositoryIdsQuery, BooleanClauseOccur.MUST);
432                            }
433    
434                            BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(
435                                    searchContext);
436    
437                            searchQuery.addTerms(_KEYWORDS_FIELDS, keywords);
438    
439                            BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(
440                                    searchContext);
441    
442                            fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
443    
444                            List<BooleanClause> clauses = searchQuery.clauses();
445    
446                            if (!clauses.isEmpty()) {
447                                    fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
448                            }
449    
450                            return SearchEngineUtil.search(searchContext, fullQuery);
451                    }
452                    catch (Exception e) {
453                            throw new SystemException(e);
454                    }
455            }
456    
457            @Override
458            public void updateFile(
459                            long companyId, long repositoryId, long newRepositoryId,
460                            String fileName)
461                    throws PortalException {
462    
463                    store.updateFile(companyId, repositoryId, newRepositoryId, fileName);
464            }
465    
466            @Override
467            public void updateFile(
468                            long companyId, long repositoryId, String fileName,
469                            String newFileName)
470                    throws PortalException {
471    
472                    store.updateFile(companyId, repositoryId, fileName, newFileName);
473            }
474    
475            @Override
476            public void updateFile(
477                            long companyId, long repositoryId, String fileName,
478                            String fileExtension, boolean validateFileExtension,
479                            String versionLabel, String sourceFileName, File file)
480                    throws PortalException {
481    
482                    validate(
483                            fileName, fileExtension, sourceFileName, validateFileExtension);
484    
485                    DLValidatorUtil.validateVersionLabel(versionLabel);
486    
487                    if (PropsValues.DL_STORE_ANTIVIRUS_ENABLED) {
488                            AntivirusScannerUtil.scan(file);
489                    }
490    
491                    store.updateFile(companyId, repositoryId, fileName, versionLabel, file);
492            }
493    
494            @Override
495            public void updateFile(
496                            long companyId, long repositoryId, String fileName,
497                            String fileExtension, boolean validateFileExtension,
498                            String versionLabel, String sourceFileName, InputStream is)
499                    throws PortalException {
500    
501                    if (is instanceof ByteArrayFileInputStream) {
502                            ByteArrayFileInputStream byteArrayFileInputStream =
503                                    (ByteArrayFileInputStream)is;
504    
505                            File file = byteArrayFileInputStream.getFile();
506    
507                            updateFile(
508                                    companyId, repositoryId, fileName, fileExtension,
509                                    validateFileExtension, versionLabel, sourceFileName, file);
510    
511                            return;
512                    }
513    
514                    validate(
515                            fileName, fileExtension, sourceFileName, validateFileExtension);
516    
517                    DLValidatorUtil.validateVersionLabel(versionLabel);
518    
519                    if (!PropsValues.DL_STORE_ANTIVIRUS_ENABLED ||
520                            !AntivirusScannerUtil.isActive()) {
521    
522                            store.updateFile(
523                                    companyId, repositoryId, fileName, versionLabel, is);
524                    }
525                    else {
526                            File tempFile = null;
527    
528                            try {
529                                    if (is.markSupported()) {
530                                            is.mark(is.available() + 1);
531    
532                                            AntivirusScannerUtil.scan(is);
533    
534                                            is.reset();
535    
536                                            store.updateFile(
537                                                    companyId, repositoryId, fileName, versionLabel, is);
538                                    }
539                                    else {
540                                            tempFile = FileUtil.createTempFile();
541    
542                                            FileUtil.write(tempFile, is);
543    
544                                            AntivirusScannerUtil.scan(tempFile);
545    
546                                            store.updateFile(
547                                                    companyId, repositoryId, fileName, versionLabel,
548                                                    tempFile);
549                                    }
550                            }
551                            catch (IOException ioe) {
552                                    throw new SystemException(
553                                            "Unable to scan file " + fileName, ioe);
554                            }
555                            finally {
556                                    if (tempFile != null) {
557                                            tempFile.delete();
558                                    }
559                            }
560                    }
561            }
562    
563            @Override
564            public void updateFileVersion(
565                            long companyId, long repositoryId, String fileName,
566                            String fromVersionLabel, String toVersionLabel)
567                    throws PortalException {
568    
569                    store.updateFileVersion(
570                            companyId, repositoryId, fileName, fromVersionLabel,
571                            toVersionLabel);
572            }
573    
574            @Override
575            public void validate(String fileName, boolean validateFileExtension)
576                    throws PortalException {
577    
578                    DLValidatorUtil.validateFileName(fileName);
579    
580                    if (validateFileExtension) {
581                            DLValidatorUtil.validateFileExtension(fileName);
582                    }
583            }
584    
585            @Override
586            public void validate(
587                            String fileName, boolean validateFileExtension, byte[] bytes)
588                    throws PortalException {
589    
590                    validate(fileName, validateFileExtension);
591    
592                    DLValidatorUtil.validateFileSize(fileName, bytes);
593            }
594    
595            @Override
596            public void validate(
597                            String fileName, boolean validateFileExtension, File file)
598                    throws PortalException {
599    
600                    validate(fileName, validateFileExtension);
601    
602                    DLValidatorUtil.validateFileSize(fileName, file);
603            }
604    
605            @Override
606            public void validate(
607                            String fileName, boolean validateFileExtension, InputStream is)
608                    throws PortalException {
609    
610                    validate(fileName, validateFileExtension);
611    
612                    DLValidatorUtil.validateFileSize(fileName, is);
613            }
614    
615            @Override
616            public void validate(
617                            String fileName, String fileExtension, String sourceFileName,
618                            boolean validateFileExtension)
619                    throws PortalException {
620    
621                    validate(fileName, validateFileExtension);
622    
623                    DLValidatorUtil.validateSourceFileExtension(
624                            fileExtension, sourceFileName);
625            }
626    
627            @Override
628            public void validate(
629                            String fileName, String fileExtension, String sourceFileName,
630                            boolean validateFileExtension, File file)
631                    throws PortalException {
632    
633                    validate(
634                            fileName, fileExtension, sourceFileName, validateFileExtension);
635    
636                    DLValidatorUtil.validateFileSize(fileName, file);
637            }
638    
639            @Override
640            public void validate(
641                            String fileName, String fileExtension, String sourceFileName,
642                            boolean validateFileExtension, InputStream is)
643                    throws PortalException {
644    
645                    validate(
646                            fileName, fileExtension, sourceFileName, validateFileExtension);
647    
648                    DLValidatorUtil.validateFileSize(fileName, is);
649            }
650    
651            /**
652             * @deprecated As of 7.0.0, replaced by {@link
653             *             DLValidatorUtil#validateDirectoryName(String)}
654             */
655            @Deprecated
656            @Override
657            public void validateDirectoryName(String directoryName)
658                    throws PortalException {
659    
660                    DLValidatorUtil.validateDirectoryName(directoryName);
661            }
662    
663            protected void validate(
664                            String fileName, boolean validateFileExtension, String versionLabel)
665                    throws PortalException {
666    
667                    validate(fileName, validateFileExtension);
668    
669                    DLValidatorUtil.validateVersionLabel(versionLabel);
670            }
671    
672            protected void validate(
673                            String fileName, String fileExtension, String sourceFileName,
674                            boolean validateFileExtension, File file, String versionLabel)
675                    throws PortalException {
676    
677                    validate(
678                            fileName, fileExtension, sourceFileName, validateFileExtension,
679                            file);
680    
681                    DLValidatorUtil.validateVersionLabel(versionLabel);
682            }
683    
684            protected void validate(
685                            String fileName, String fileExtension, String sourceFileName,
686                            boolean validateFileExtension, InputStream is, String versionLabel)
687                    throws PortalException {
688    
689                    validate(
690                            fileName, fileExtension, sourceFileName, validateFileExtension, is);
691    
692                    DLValidatorUtil.validateVersionLabel(versionLabel);
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    }