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.portal.kernel.search;
016    
017    import com.liferay.portal.kernel.util.ArrayUtil;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.Time;
020    import com.liferay.portal.kernel.workflow.WorkflowConstants;
021    import com.liferay.portal.security.permission.ActionKeys;
022    import com.liferay.portal.security.permission.PermissionChecker;
023    
024    import java.util.ArrayList;
025    import java.util.List;
026    
027    /**
028     * @author Tina Tian
029     */
030    public class DefaultSearchResultPermissionFilter
031            extends BaseSearchResultPermissionFilter {
032    
033            public DefaultSearchResultPermissionFilter(
034                    BaseIndexer baseIndexer, PermissionChecker permissionChecker) {
035    
036                    _baseIndexer = baseIndexer;
037                    _permissionChecker = permissionChecker;
038            }
039    
040            @Override
041            protected void filterHits(Hits hits, SearchContext searchContext) {
042                    List<Document> docs = new ArrayList<>();
043                    List<Float> scores = new ArrayList<>();
044    
045                    Document[] documents = hits.getDocs();
046    
047                    int excludeDocsSize = 0;
048    
049                    int status = GetterUtil.getInteger(
050                            searchContext.getAttribute(Field.STATUS),
051                            WorkflowConstants.STATUS_APPROVED);
052    
053                    for (int i = 0; i < documents.length; i++) {
054                            Document document = documents[i];
055    
056                            String entryClassName = document.get(Field.ENTRY_CLASS_NAME);
057    
058                            Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
059    
060                            long entryClassPK = GetterUtil.getLong(
061                                    document.get(Field.ENTRY_CLASS_PK));
062    
063                            try {
064                                    if ((indexer == null) ||
065                                            (indexer.isFilterSearch() &&
066                                             indexer.hasPermission(
067                                                     _permissionChecker, entryClassName, entryClassPK,
068                                                     ActionKeys.VIEW) &&
069                                             indexer.isVisibleRelatedEntry(entryClassPK, status)) ||
070                                            !indexer.isFilterSearch() || !indexer.isPermissionAware()) {
071    
072                                            docs.add(document);
073                                            scores.add(hits.score(i));
074                                    }
075                                    else {
076                                            excludeDocsSize++;
077                                    }
078                            }
079                            catch (Exception e) {
080                                    excludeDocsSize++;
081                            }
082                    }
083    
084                    hits.setDocs(docs.toArray(new Document[docs.size()]));
085                    hits.setScores(ArrayUtil.toFloatArray(scores));
086                    hits.setSearchTime(
087                            (float)(System.currentTimeMillis() - hits.getStart()) /
088                                    Time.SECOND);
089                    hits.setLength(hits.getLength() - excludeDocsSize);
090            }
091    
092            @Override
093            protected Hits getHits(SearchContext searchContext) throws SearchException {
094                    return _baseIndexer.doSearch(searchContext);
095            }
096    
097            private final BaseIndexer _baseIndexer;
098            private final PermissionChecker _permissionChecker;
099    
100    }