/**
* 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.result.display.builder;
import com.liferay.asset.kernel.AssetRendererFactoryRegistryUtil;
import com.liferay.asset.kernel.model.AssetEntry;
import com.liferay.asset.kernel.model.AssetRenderer;
import com.liferay.asset.kernel.model.AssetRendererFactory;
import com.liferay.asset.kernel.service.AssetEntryLocalService;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.language.Language;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.search.Document;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.Indexer;
import com.liferay.portal.kernel.search.IndexerRegistry;
import com.liferay.portal.kernel.search.IndexerRegistryUtil;
import com.liferay.portal.kernel.search.SearchException;
import com.liferay.portal.kernel.search.Summary;
import com.liferay.portal.kernel.security.permission.ResourceActions;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.search.web.internal.display.context.PortletURLFactory;
import com.liferay.portal.search.web.internal.display.context.SearchResultPreferences;
import com.liferay.portal.search.web.internal.result.display.context.SearchResultFieldDisplayContext;
import com.liferay.portal.search.web.internal.result.display.context.SearchResultSummaryDisplayContext;
import com.liferay.portal.search.web.internal.util.SearchUtil;
import com.liferay.portal.search.web.search.result.SearchResultImage;
import com.liferay.portal.search.web.search.result.SearchResultImageContributor;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.servlet.http.HttpServletRequest;
/**
* @author André de Oliveira
*/
public class SearchResultSummaryDisplayBuilder {
public SearchResultSummaryDisplayContext build() throws Exception {
String className = _document.get(Field.ENTRY_CLASS_NAME);
long classPK = getEntryClassPK();
AssetRendererFactory<?> assetRendererFactory =
getAssetRendererFactoryByClassName(className);
AssetRenderer<?> assetRenderer = null;
if (assetRendererFactory != null) {
long resourcePrimKey = GetterUtil.getLong(
_document.get(Field.ROOT_ENTRY_CLASS_PK));
if (resourcePrimKey > 0) {
classPK = resourcePrimKey;
}
assetRenderer = assetRendererFactory.getAssetRenderer(classPK);
}
Summary summary = getSummary(className, assetRenderer);
if (summary == null) {
return null;
}
return build(summary, className, classPK, assetRenderer);
}
public void setAbridged(boolean abridged) {
_abridged = abridged;
}
public void setAssetEntryLocalService(
AssetEntryLocalService assetEntryLocalService) {
_assetEntryLocalService = assetEntryLocalService;
}
public void setAssetRendererFactoryLookup(
AssetRendererFactoryLookup assetRendererFactoryLookup) {
_assetRendererFactoryLookup = assetRendererFactoryLookup;
}
public void setCurrentURL(String currentURL) {
_currentURL = currentURL;
}
public void setDocument(Document document) {
_document = document;
}
public void setHighlightEnabled(boolean highlightEnabled) {
_highlightEnabled = highlightEnabled;
}
public void setImageRequested(boolean imageRequested) {
_imageRequested = imageRequested;
}
public void setIndexerRegistry(IndexerRegistry indexerRegistry) {
_indexerRegistry = indexerRegistry;
}
public void setLanguage(Language language) {
_language = language;
}
public void setLocale(Locale locale) {
_locale = locale;
}
public void setPortletURLFactory(PortletURLFactory portletURLFactory) {
_portletURLFactory = portletURLFactory;
}
public void setQueryTerms(String[] queryTerms) {
_queryTerms = queryTerms;
}
public void setRenderRequest(RenderRequest renderRequest) {
_renderRequest = renderRequest;
}
public void setRenderResponse(RenderResponse renderResponse) {
_renderResponse = renderResponse;
}
public void setRequest(HttpServletRequest request) {
_request = request;
}
public void setResourceActions(ResourceActions resourceActions) {
_resourceActions = resourceActions;
}
public void setSearchResultImageContributorsStream(
Stream<SearchResultImageContributor>
searchResultImageContributorsStream) {
_searchResultImageContributorsStream =
searchResultImageContributorsStream;
}
public void setSearchResultPreferences(
SearchResultPreferences searchResultPreferences) {
_searchResultPreferences = searchResultPreferences;
}
public void setSearchResultViewURLSupplier(
SearchResultViewURLSupplier searchResultViewURLSupplier) {
_searchResultViewURLSupplier = searchResultViewURLSupplier;
}
public void setThemeDisplay(ThemeDisplay themeDisplay) {
_themeDisplay = themeDisplay;
}
protected SearchResultSummaryDisplayContext build(
Summary summary, String className, long classPK,
AssetRenderer<?> assetRenderer)
throws PortalException, PortletException {
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext =
new SearchResultSummaryDisplayContext();
if (Validator.isNotNull(summary.getContent())) {
searchResultSummaryDisplayContext.setContent(
summary.getHighlightedContent());
searchResultSummaryDisplayContext.setContentVisible(true);
}
searchResultSummaryDisplayContext.setHighlightedTitle(
summary.getHighlightedTitle());
if (_abridged) {
return searchResultSummaryDisplayContext;
}
AssetEntry assetEntry = _assetEntryLocalService.fetchEntry(
className, classPK);
buildAssetCategoriesOrTags(
searchResultSummaryDisplayContext, assetEntry, className, classPK);
buildAssetRendererURLDownload(
searchResultSummaryDisplayContext, assetRenderer, summary);
buildCreationDateString(searchResultSummaryDisplayContext);
buildCreatorUserName(searchResultSummaryDisplayContext);
buildDocumentForm(searchResultSummaryDisplayContext);
buildImage(searchResultSummaryDisplayContext, className, classPK);
buildLocaleReminder(searchResultSummaryDisplayContext, summary);
buildModelResource(searchResultSummaryDisplayContext, className);
buildUserPortrait(
searchResultSummaryDisplayContext, assetEntry, className);
buildViewURL(className, classPK, searchResultSummaryDisplayContext);
return searchResultSummaryDisplayContext;
}
protected void buildAssetCategoriesOrTags(
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext,
AssetEntry assetEntry, String className, long classPK)
throws PortletException {
if (hasAssetCategoriesOrTags(assetEntry)) {
searchResultSummaryDisplayContext.setAssetCategoriesOrTagsVisible(
true);
searchResultSummaryDisplayContext.setClassName(className);
searchResultSummaryDisplayContext.setClassPK(classPK);
searchResultSummaryDisplayContext.setFieldAssetCategoryIds(
Field.ASSET_CATEGORY_IDS);
searchResultSummaryDisplayContext.setFieldAssetTagNames(
Field.ASSET_TAG_NAMES);
searchResultSummaryDisplayContext.setPortletURL(
_portletURLFactory.getPortletURL());
}
}
protected void buildAssetRendererURLDownload(
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext,
AssetRenderer<?> assetRenderer, Summary summary) {
if (hasAssetRendererURLDownload(assetRenderer)) {
searchResultSummaryDisplayContext.setAssetRendererURLDownload(
assetRenderer.getURLDownload(_themeDisplay));
searchResultSummaryDisplayContext.
setAssetRendererURLDownloadVisible(true);
searchResultSummaryDisplayContext.setTitle(summary.getTitle());
}
}
protected void buildCreationDateString(
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext) {
String creation = StringUtil.trim(_document.get(Field.CREATE_DATE));
if (!Validator.isBlank(creation)) {
searchResultSummaryDisplayContext.setCreationDateString(
formatDate(creation));
searchResultSummaryDisplayContext.setCreationDateVisible(true);
}
}
protected void buildCreatorUserName(
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext) {
String creatorUserName = _document.get(Field.USER_NAME);
if (creatorUserName != null) {
searchResultSummaryDisplayContext.setCreatorUserName(
creatorUserName);
searchResultSummaryDisplayContext.setCreatorVisible(true);
}
}
protected void buildDocumentForm(
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext) {
if (_searchResultPreferences.isDisplayResultsInDocumentForm()) {
searchResultSummaryDisplayContext.
setDocumentFormFieldDisplayContexts(buildFields());
searchResultSummaryDisplayContext.setDocumentFormVisible(true);
}
}
protected SearchResultFieldDisplayContext buildField(Field field) {
SearchResultFieldDisplayContext searchResultFieldDisplayContext =
new SearchResultFieldDisplayContext();
searchResultFieldDisplayContext.setArray(isArray(field));
searchResultFieldDisplayContext.setBoost(field.getBoost());
searchResultFieldDisplayContext.setName(field.getName());
searchResultFieldDisplayContext.setNumeric(field.isNumeric());
searchResultFieldDisplayContext.setTokenized(field.isTokenized());
searchResultFieldDisplayContext.setValuesToString(
getValuesToString(field));
return searchResultFieldDisplayContext;
}
protected List<SearchResultFieldDisplayContext> buildFields() {
Map<String, Field> map = _document.getFields();
List<Map.Entry<String, Field>> entries = new LinkedList<>(
map.entrySet());
Collections.sort(
entries,
new Comparator<Map.Entry<String, Field>>() {
@Override
public int compare(
Map.Entry<String, Field> entry1,
Map.Entry<String, Field> entry2) {
String key = entry1.getKey();
return key.compareTo(entry2.getKey());
}
});
List<SearchResultFieldDisplayContext> searchResultFieldDisplayContexts =
new ArrayList<>(entries.size());
for (Map.Entry<String, Field> entry : entries) {
Field field = entry.getValue();
String fieldName = field.getName();
if (fieldName.equals(Field.UID)) {
continue;
}
searchResultFieldDisplayContexts.add(buildField(field));
}
return searchResultFieldDisplayContexts;
}
protected void buildImage(
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext,
String className, long classPK) {
if (!_imageRequested) {
return;
}
SearchResultImage searchResultsImage = new SearchResultImage() {
@Override
public String getClassName() {
return className;
}
@Override
public long getClassPK() {
return classPK;
}
@Override
public void setIcon(String iconName) {
searchResultSummaryDisplayContext.setIconId(iconName);
searchResultSummaryDisplayContext.setIconVisible(true);
searchResultSummaryDisplayContext.setPathThemeImages(
_themeDisplay.getPathThemeImages());
}
@Override
public void setThumbnail(String thumbnailURLString) {
searchResultSummaryDisplayContext.setThumbnailURLString(
thumbnailURLString);
searchResultSummaryDisplayContext.setThumbnailVisible(true);
}
};
_searchResultImageContributorsStream.forEach(
searchResultImageContributor -> {
searchResultImageContributor.contribute(searchResultsImage);
});
}
protected void buildLocaleReminder(
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext,
Summary summary) {
if (_locale != summary.getLocale()) {
Locale summaryLocale = summary.getLocale();
searchResultSummaryDisplayContext.setLocaleLanguageId(
LocaleUtil.toLanguageId(summaryLocale));
searchResultSummaryDisplayContext.setLocaleReminder(
_language.format(
_request,
"this-result-comes-from-the-x-version-of-this-content",
summaryLocale.getDisplayLanguage(_locale), false));
searchResultSummaryDisplayContext.setLocaleReminderVisible(true);
}
}
protected void buildModelResource(
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext,
String className) {
searchResultSummaryDisplayContext.setModelResource(
_resourceActions.getModelResource(
_themeDisplay.getLocale(), className));
}
protected void buildUserPortrait(
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext,
AssetEntry assetEntry, String className) {
long entryClassPK = getEntryClassPK();
AssetEntry childAssetEntry = _assetEntryLocalService.fetchEntry(
className, entryClassPK);
if (childAssetEntry != null) {
assetEntry = childAssetEntry;
}
if (assetEntry != null) {
searchResultSummaryDisplayContext.setAssetEntryUserId(
getAssetEntryUserId(assetEntry));
searchResultSummaryDisplayContext.setUserPortraitVisible(true);
}
}
protected void buildViewURL(
String className, long classPK,
SearchResultSummaryDisplayContext searchResultSummaryDisplayContext) {
String viewURL = getSearchResultViewURL(className, classPK);
searchResultSummaryDisplayContext.setViewURL(viewURL);
}
protected String formatDate(String dateString) {
SimpleDateFormat simpleDateFormatInput = new SimpleDateFormat(
"yyyyMMddHHmmss");
SimpleDateFormat simpleDateFormatOutput = new SimpleDateFormat(
"MMM dd yyyy, h:mm a");
try {
return simpleDateFormatOutput.format(
simpleDateFormatInput.parse(dateString));
}
catch (ParseException pe) {
throw new RuntimeException(pe);
}
}
protected long getAssetEntryUserId(AssetEntry assetEntry) {
if (Objects.equals(assetEntry.getClassName(), User.class.getName())) {
return assetEntry.getClassPK();
}
return assetEntry.getUserId();
}
protected AssetRendererFactory<?> getAssetRendererFactoryByClassName(
String className) {
if (_assetRendererFactoryLookup != null) {
return _assetRendererFactoryLookup.
getAssetRendererFactoryByClassName(className);
}
return AssetRendererFactoryRegistryUtil.
getAssetRendererFactoryByClassName(className);
}
protected long getEntryClassPK() {
return GetterUtil.getLong(_document.get(Field.ENTRY_CLASS_PK));
}
protected Indexer<Object> getIndexer(String className) {
if (_indexerRegistry != null) {
return _indexerRegistry.getIndexer(className);
}
return IndexerRegistryUtil.getIndexer(className);
}
protected String getSearchResultViewURL(String className, long classPK) {
if (_searchResultViewURLSupplier != null) {
return _searchResultViewURLSupplier.getSearchResultViewURL();
}
return SearchUtil.getSearchResultViewURL(
_renderRequest, _renderResponse, className, classPK,
_searchResultPreferences.isViewInContext(), _currentURL);
}
protected Summary getSummary(
String className, AssetRenderer<?> assetRenderer)
throws SearchException {
Summary summary = null;
Indexer indexer = getIndexer(className);
if (indexer != null) {
String snippet = _document.get(Field.SNIPPET);
summary = indexer.getSummary(
_document, snippet, _renderRequest, _renderResponse);
}
else if (assetRenderer != null) {
summary = new Summary(
_locale, assetRenderer.getTitle(_locale),
assetRenderer.getSearchSummary(_locale));
}
if (summary != null) {
summary.setHighlight(_highlightEnabled);
summary.setQueryTerms(_queryTerms);
}
return summary;
}
protected String getValuesToString(Field field) {
String[] values = field.getValues();
StringBundler sb = new StringBundler(4 * values.length);
for (int i = 0; i < values.length; i++) {
if (field.isNumeric()) {
sb.append(HtmlUtil.escape(values[i]));
}
else {
sb.append(StringPool.QUOTE);
sb.append(HtmlUtil.escape(values[i]));
sb.append(StringPool.QUOTE);
}
sb.append(StringPool.COMMA_AND_SPACE);
}
sb.setIndex(sb.index() - 1);
if (values.length > 1) {
sb.setStringAt(StringPool.OPEN_BRACKET, 0);
sb.append(StringPool.CLOSE_BRACKET);
}
return sb.toString();
}
protected boolean hasAssetCategoriesOrTags(AssetEntry assetEntry) {
if (assetEntry == null) {
return false;
}
if (ArrayUtil.isNotEmpty(assetEntry.getCategoryIds())) {
return true;
}
if (ArrayUtil.isNotEmpty(assetEntry.getTagNames())) {
return true;
}
return false;
}
protected boolean hasAssetRendererURLDownload(
AssetRenderer<?> assetRenderer) {
if (assetRenderer == null) {
return false;
}
if (Validator.isNull(assetRenderer.getURLDownload(_themeDisplay))) {
return false;
}
return true;
}
protected boolean isArray(Field field) {
String[] values = field.getValues();
if (values.length > 1) {
return true;
}
return false;
}
private boolean _abridged;
private AssetEntryLocalService _assetEntryLocalService;
private AssetRendererFactoryLookup _assetRendererFactoryLookup;
private String _currentURL;
private Document _document;
private boolean _highlightEnabled;
private boolean _imageRequested;
private IndexerRegistry _indexerRegistry;
private Language _language;
private Locale _locale;
private PortletURLFactory _portletURLFactory;
private String[] _queryTerms;
private RenderRequest _renderRequest;
private RenderResponse _renderResponse;
private HttpServletRequest _request;
private ResourceActions _resourceActions;
private Stream<SearchResultImageContributor>
_searchResultImageContributorsStream = Stream.empty();
private SearchResultPreferences _searchResultPreferences;
private SearchResultViewURLSupplier _searchResultViewURLSupplier;
private ThemeDisplay _themeDisplay;
}