/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.search.web.internal.display.context; import com.liferay.portal.kernel.dao.search.SearchContainer; import com.liferay.portal.kernel.language.Language; import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.search.BooleanClauseOccur; import com.liferay.portal.kernel.search.Document; import com.liferay.portal.kernel.search.Field; import com.liferay.portal.kernel.search.Hits; import com.liferay.portal.kernel.search.QueryConfig; import com.liferay.portal.kernel.search.SearchContext; import com.liferay.portal.kernel.search.SearchContextFactory; import com.liferay.portal.kernel.search.facet.Facet; import com.liferay.portal.kernel.search.facet.faceted.searcher.FacetedSearcherManager; import com.liferay.portal.kernel.search.generic.BooleanClauseImpl; import com.liferay.portal.kernel.search.generic.TermQueryImpl; import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.Html; import com.liferay.portal.kernel.util.ListUtil; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.portal.kernel.util.Portal; import com.liferay.portal.kernel.util.PredicateFilter; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.search.web.constants.SearchPortletParameterNames; import com.liferay.portal.search.web.facet.SearchFacet; import com.liferay.portal.search.web.facet.util.SearchFacetTracker; import com.liferay.portal.search.web.internal.portlet.SearchPortletSearchResultPreferences; import com.liferay.portal.search.web.internal.search.request.SearchRequestImpl; import com.liferay.portal.search.web.internal.search.request.SearchResponseImpl; import com.liferay.portal.search.web.search.request.SearchSettings; import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import javax.portlet.PortletException; import javax.portlet.PortletPreferences; import javax.portlet.PortletURL; import javax.portlet.RenderRequest; import javax.servlet.http.HttpServletRequest; /** * @author Eudaldo Alonso */ public class SearchDisplayContext { public SearchDisplayContext( RenderRequest renderRequest, PortletPreferences portletPreferences, Portal portal, Html html, Language language, FacetedSearcherManager facetedSearcherManager, IndexSearchPropsValues indexSearchPropsValues, PortletURLFactory portletURLFactory) throws PortletException { _renderRequest = renderRequest; _portletPreferences = portletPreferences; _indexSearchPropsValues = indexSearchPropsValues; _portletURLFactory = portletURLFactory; ThemeDisplaySupplier themeDisplaySupplier = new PortletRequestThemeDisplaySupplier(renderRequest); SearchResultPreferences searchResultPreferences = new SearchPortletSearchResultPreferences( portletPreferences, themeDisplaySupplier); _searchResultPreferences = searchResultPreferences; _themeDisplaySupplier = themeDisplaySupplier; String keywords = getKeywords(); if (keywords == null) { _hits = null; _searchContainer = null; _searchContext = null; return; } HttpServletRequest request = portal.getHttpServletRequest( _renderRequest); String emptyResultMessage = language.format( request, "no-results-were-found-that-matched-the-keywords-x", "<strong>" + html.escape(keywords) + "</strong>", false); SearchContainer<Document> searchContainer = new SearchContainer<>( _renderRequest, getPortletURL(), null, emptyResultMessage); SearchContext searchContext = SearchContextFactory.getInstance(request); SearchRequestImpl searchRequestImpl = new SearchRequestImpl( () -> searchContext, searchContainerOptions -> searchContainer, facetedSearcherManager); searchRequestImpl.addSearchSettingsContributor( this::contributeSearchSettings); SearchResponseImpl searchResponseImpl = searchRequestImpl.search(); _hits = searchResponseImpl.getHits(); _searchContainer = searchResponseImpl.getSearchContainer(); _searchContext = searchResponseImpl.getSearchContext(); } public int getCollatedSpellCheckResultDisplayThreshold() { if (_collatedSpellCheckResultDisplayThreshold != null) { return _collatedSpellCheckResultDisplayThreshold; } int collatedSpellCheckResultScoresThreshold = _indexSearchPropsValues. getCollatedSpellCheckResultScoresThreshold(); _collatedSpellCheckResultDisplayThreshold = GetterUtil.getInteger( _portletPreferences.getValue( "collatedSpellCheckResultDisplayThreshold", null), collatedSpellCheckResultScoresThreshold); if (_collatedSpellCheckResultDisplayThreshold < 0) { _collatedSpellCheckResultDisplayThreshold = collatedSpellCheckResultScoresThreshold; } return _collatedSpellCheckResultDisplayThreshold; } public List<SearchFacet> getEnabledSearchFacets() { if (_enabledSearchFacets != null) { return _enabledSearchFacets; } _enabledSearchFacets = ListUtil.filter( SearchFacetTracker.getSearchFacets(), new PredicateFilter<SearchFacet>() { @Override public boolean filter(SearchFacet searchFacet) { return isDisplayFacet(searchFacet.getClassName()); } }); return _enabledSearchFacets; } public Hits getHits() { return _hits; } public String getKeywords() { return ParamUtil.getString( _renderRequest, SearchPortletParameterNames.KEYWORDS, null); } public PortletURL getPortletURL() throws PortletException { return _portletURLFactory.getPortletURL(); } public PortletURLFactory getPortletURLFactory() { return _portletURLFactory; } public QueryConfig getQueryConfig() { if (_queryConfig != null) { return _queryConfig; } _queryConfig = new QueryConfig(); _queryConfig.setCollatedSpellCheckResultEnabled( isCollatedSpellCheckResultEnabled()); _queryConfig.setCollatedSpellCheckResultScoresThreshold( getCollatedSpellCheckResultDisplayThreshold()); _queryConfig.setQueryIndexingEnabled(isQueryIndexingEnabled()); _queryConfig.setQueryIndexingThreshold(getQueryIndexingThreshold()); _queryConfig.setQuerySuggestionEnabled(isQuerySuggestionsEnabled()); _queryConfig.setQuerySuggestionScoresThreshold( getQuerySuggestionsDisplayThreshold()); _queryConfig.setQuerySuggestionsMax(getQuerySuggestionsMax()); return _queryConfig; } public int getQueryIndexingThreshold() { if (_queryIndexingThreshold != null) { return _queryIndexingThreshold; } _queryIndexingThreshold = GetterUtil.getInteger( _portletPreferences.getValue("queryIndexingThreshold", null), _indexSearchPropsValues.getQueryIndexingThreshold()); if (_queryIndexingThreshold < 0) { _queryIndexingThreshold = _indexSearchPropsValues.getQueryIndexingThreshold(); } return _queryIndexingThreshold; } public int getQuerySuggestionsDisplayThreshold() { if (_querySuggestionsDisplayThreshold != null) { return _querySuggestionsDisplayThreshold; } _querySuggestionsDisplayThreshold = GetterUtil.getInteger( _portletPreferences.getValue( "querySuggestionsDisplayThreshold", null), _indexSearchPropsValues.getQuerySuggestionScoresThreshold()); if (_querySuggestionsDisplayThreshold < 0) { _querySuggestionsDisplayThreshold = _indexSearchPropsValues.getQuerySuggestionScoresThreshold(); } return _querySuggestionsDisplayThreshold; } public int getQuerySuggestionsMax() { if (_querySuggestionsMax != null) { return _querySuggestionsMax; } _querySuggestionsMax = GetterUtil.getInteger( _portletPreferences.getValue("querySuggestionsMax", null), _indexSearchPropsValues.getQuerySuggestionMax()); if (_querySuggestionsMax <= 0) { _querySuggestionsMax = _indexSearchPropsValues.getQuerySuggestionMax(); } return _querySuggestionsMax; } public String[] getQueryTerms() { Hits hits = getHits(); return hits.getQueryTerms(); } public String getSearchConfiguration() { if (_searchConfiguration != null) { return _searchConfiguration; } _searchConfiguration = _portletPreferences.getValue( "searchConfiguration", StringPool.BLANK); return _searchConfiguration; } public SearchContainer<Document> getSearchContainer() { return _searchContainer; } public SearchContext getSearchContext() { return _searchContext; } public SearchResultPreferences getSearchResultPreferences() { return _searchResultPreferences; } public long getSearchScopeGroupId() { SearchScope searchScope = getSearchScope(); if (searchScope == SearchScope.EVERYTHING) { return 0; } ThemeDisplay themeDisplay = getThemeDisplay(); return themeDisplay.getScopeGroupId(); } public String getSearchScopeParameterString() { SearchScope searchScope = getSearchScope(); return searchScope.getParameterString(); } public String getSearchScopePreferenceString() { if (_searchScopePreferenceString != null) { return _searchScopePreferenceString; } _searchScopePreferenceString = _portletPreferences.getValue( "searchScope", StringPool.BLANK); return _searchScopePreferenceString; } public boolean isCollatedSpellCheckResultEnabled() { if (_collatedSpellCheckResultEnabled != null) { return _collatedSpellCheckResultEnabled; } _collatedSpellCheckResultEnabled = GetterUtil.getBoolean( _portletPreferences.getValue( "collatedSpellCheckResultEnabled", null), _indexSearchPropsValues.isCollatedSpellCheckResultEnabled()); return _collatedSpellCheckResultEnabled; } public boolean isDisplayFacet(String className) { return GetterUtil.getBoolean( _portletPreferences.getValue(className, null), true); } public boolean isDisplayMainQuery() { if (_displayMainQuery != null) { return _displayMainQuery; } _displayMainQuery = GetterUtil.getBoolean( _portletPreferences.getValue("displayMainQuery", null)); return _displayMainQuery; } public boolean isDisplayOpenSearchResults() { if (_displayOpenSearchResults != null) { return _displayOpenSearchResults; } _displayOpenSearchResults = GetterUtil.getBoolean( _portletPreferences.getValue("displayOpenSearchResults", null)); return _displayOpenSearchResults; } public boolean isDisplayResultsInDocumentForm() { return _searchResultPreferences.isDisplayResultsInDocumentForm(); } public boolean isDLLinkToViewURL() { if (_dlLinkToViewURL != null) { return _dlLinkToViewURL; } _dlLinkToViewURL = false; return _dlLinkToViewURL; } public boolean isHighlightEnabled() { QueryConfig queryConfig = getQueryConfig(); return queryConfig.isHighlightEnabled(); } public boolean isIncludeSystemPortlets() { if (_includeSystemPortlets != null) { return _includeSystemPortlets; } _includeSystemPortlets = false; return _includeSystemPortlets; } public boolean isQueryIndexingEnabled() { if (_queryIndexingEnabled != null) { return _queryIndexingEnabled; } _queryIndexingEnabled = GetterUtil.getBoolean( _portletPreferences.getValue("queryIndexingEnabled", null), _indexSearchPropsValues.isQueryIndexingEnabled()); return _queryIndexingEnabled; } public boolean isQuerySuggestionsEnabled() { if (_querySuggestionsEnabled != null) { return _querySuggestionsEnabled; } _querySuggestionsEnabled = GetterUtil.getBoolean( _portletPreferences.getValue("querySuggestionsEnabled", null), _indexSearchPropsValues.isQuerySuggestionEnabled()); return _querySuggestionsEnabled; } public boolean isSearchScopePreferenceEverythingAvailable() { ThemeDisplay themeDisplay = getThemeDisplay(); Group group = themeDisplay.getScopeGroup(); if (group.isStagingGroup()) { return false; } return true; } public boolean isSearchScopePreferenceLetTheUserChoose() { SearchScopePreference searchScopePreference = getSearchScopePreference(); if (searchScopePreference == SearchScopePreference.LET_THE_USER_CHOOSE) { return true; } return false; } public boolean isShowMenu() { for (SearchFacet searchFacet : SearchFacetTracker.getSearchFacets()) { if (isDisplayFacet(searchFacet.getClassName())) { return true; } } return false; } public boolean isViewInContext() { return _searchResultPreferences.isViewInContext(); } protected void addEnabledSearchFacets(SearchSettings searchSettings) { ThemeDisplay themeDisplay = _themeDisplaySupplier.getThemeDisplay(); long companyId = themeDisplay.getCompanyId(); Collection<SearchFacet> searchFacets = getEnabledSearchFacets(); Stream<SearchFacet> searchFacetsStream = searchFacets.stream(); Stream<Optional<Facet>> facetOptionalsStream = searchFacetsStream.map( searchFacet -> createFacet( searchFacet, companyId, searchSettings.getSearchContext())); facetOptionalsStream.forEach( facetOptional -> facetOptional.ifPresent(searchSettings::addFacet)); } protected void contributeSearchSettings(SearchSettings searchSettings) { searchSettings.setKeywords(getKeywords()); QueryConfig queryConfig = searchSettings.getQueryConfig(); queryConfig.setCollatedSpellCheckResultEnabled( isCollatedSpellCheckResultEnabled()); queryConfig.setCollatedSpellCheckResultScoresThreshold( getCollatedSpellCheckResultDisplayThreshold()); queryConfig.setQueryIndexingEnabled(isQueryIndexingEnabled()); queryConfig.setQueryIndexingThreshold(getQueryIndexingThreshold()); queryConfig.setQuerySuggestionEnabled(isQuerySuggestionsEnabled()); queryConfig.setQuerySuggestionScoresThreshold( getQuerySuggestionsDisplayThreshold()); queryConfig.setQuerySuggestionsMax(getQuerySuggestionsMax()); addEnabledSearchFacets(searchSettings); filterByThisSite(searchSettings); } protected Optional<Facet> createFacet( SearchFacet searchFacet, long companyId, SearchContext searchContext) { try { searchFacet.init( companyId, getSearchConfiguration(), searchContext); } catch (RuntimeException re) { throw re; } catch (Exception e) { throw new RuntimeException(e); } return Optional.ofNullable(searchFacet.getFacet()); } protected void filterByThisSite(SearchSettings searchSettings) { Optional<Long> groupIdOptional = getThisSiteGroupId(); groupIdOptional.ifPresent( groupId -> { searchSettings.addCondition( new BooleanClauseImpl( new TermQueryImpl( Field.GROUP_ID, String.valueOf(groupId)), BooleanClauseOccur.MUST)); }); } protected SearchScope getSearchScope() { String scopeString = ParamUtil.getString( _renderRequest, SearchPortletParameterNames.SCOPE); if (Validator.isNotNull(scopeString)) { return SearchScope.getSearchScope(scopeString); } SearchScopePreference searchScopePreference = getSearchScopePreference(); SearchScope searchScope = searchScopePreference.getSearchScope(); if (searchScope == null) { throw new IllegalArgumentException( "Scope parameter is empty and no default is set in " + "preferences"); } return searchScope; } protected SearchScopePreference getSearchScopePreference() { return SearchScopePreference.getSearchScopePreference( getSearchScopePreferenceString()); } protected ThemeDisplay getThemeDisplay() { return _themeDisplaySupplier.getThemeDisplay(); } protected Optional<Long> getThisSiteGroupId() { long searchScopeGroupId = getSearchScopeGroupId(); if (searchScopeGroupId == 0) { return Optional.empty(); } return Optional.of(searchScopeGroupId); } private Integer _collatedSpellCheckResultDisplayThreshold; private Boolean _collatedSpellCheckResultEnabled; private Boolean _displayMainQuery; private Boolean _displayOpenSearchResults; private Boolean _dlLinkToViewURL; private List<SearchFacet> _enabledSearchFacets; private final Hits _hits; private Boolean _includeSystemPortlets; private final IndexSearchPropsValues _indexSearchPropsValues; private final PortletPreferences _portletPreferences; private final PortletURLFactory _portletURLFactory; private QueryConfig _queryConfig; private Boolean _queryIndexingEnabled; private Integer _queryIndexingThreshold; private Integer _querySuggestionsDisplayThreshold; private Boolean _querySuggestionsEnabled; private Integer _querySuggestionsMax; private final RenderRequest _renderRequest; private String _searchConfiguration; private final SearchContainer<Document> _searchContainer; private final SearchContext _searchContext; private final SearchResultPreferences _searchResultPreferences; private String _searchScopePreferenceString; private final ThemeDisplaySupplier _themeDisplaySupplier; }