com.daimler.spm.b2bacceleratoraddon.controllers.pages.AdvanceSearchPageController.java Source code

Java tutorial

Introduction

Here is the source code for com.daimler.spm.b2bacceleratoraddon.controllers.pages.AdvanceSearchPageController.java

Source

/*
 * [y] hybris Platform
 *
 * Copyright (c) 2017 SAP SE or an SAP affiliate company.  All rights reserved.
 *
 * This software is the confidential and proprietary information of SAP
 * ("Confidential Information"). You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with SAP.
 */
package com.daimler.spm.b2bacceleratoraddon.controllers.pages;

import de.hybris.platform.acceleratorservices.controllers.page.PageType;
import de.hybris.platform.acceleratorstorefrontcommons.breadcrumb.impl.SearchBreadcrumbBuilder;
import de.hybris.platform.acceleratorstorefrontcommons.constants.WebConstants;
import de.hybris.platform.acceleratorstorefrontcommons.controllers.ThirdPartyConstants;
import de.hybris.platform.acceleratorstorefrontcommons.controllers.pages.AbstractSearchPageController;
import de.hybris.platform.acceleratorstorefrontcommons.util.MetaSanitizerUtil;
import de.hybris.platform.acceleratorstorefrontcommons.util.XSSFilterUtil;
import com.daimler.spm.b2bacceleratoraddon.forms.AdvancedSearchForm;
import de.hybris.platform.b2bacceleratorfacades.api.search.SearchFacade;
import de.hybris.platform.b2bacceleratorfacades.search.data.ProductSearchStateData;
import de.hybris.platform.cms2.exceptions.CMSItemNotFoundException;
import de.hybris.platform.commercefacades.product.data.ProductData;
import de.hybris.platform.commercefacades.search.data.SearchQueryData;
import de.hybris.platform.commercefacades.search.data.SearchStateData;
import de.hybris.platform.commerceservices.search.facetdata.FacetData;
import de.hybris.platform.commerceservices.search.facetdata.FacetValueData;
import de.hybris.platform.commerceservices.search.facetdata.ProductSearchPageData;
import de.hybris.platform.commerceservices.search.pagedata.PageableData;
import de.hybris.platform.commerceservices.search.pagedata.PaginationData;
import de.hybris.platform.commerceservices.search.pagedata.SearchPageData;
import de.hybris.platform.util.Config;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.function.Predicate;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.common.collect.Lists;

@Controller
@RequestMapping("/search")
public class AdvanceSearchPageController extends AbstractSearchPageController {
    @SuppressWarnings("unused")
    private static final Logger LOG = Logger.getLogger(AdvanceSearchPageController.class);

    private static final String ADVANCED_FLEXIBLE_SEARCH_PAGE_SIZE_PARAM = "storefront.flexible.advance.search.pageSize";
    private static final String ADVANCED_SEARCH_PRODUCT_IDS_DELIMITER = "storefront.advancedsearch.delimiter";
    private static final String ADVANCED_SEARCH_PRODUCT_IDS_DELIMITER_DEFAULT = ",";
    private static final String ADVANCED_SEARCH_RESULT_TYPE_ORDER_FORM = "order-form";
    private static final String FUTURE_STOCK_ENABLED = "storefront.products.futurestock.enabled";
    private static final String NO_RESULTS_ADVANCED_PAGE_ID = "searchAdvancedEmpty";
    private static final Set<String> PAGINATION_PARAM_REMOVAL_LOOKUP_TABLE = new HashSet<>(
            Arrays.asList("PAGE", "SHOW", "SORT"));

    @Resource(name = "searchBreadcrumbBuilder")
    private SearchBreadcrumbBuilder searchBreadcrumbBuilder;

    @Resource(name = "b2bProductFlexibleSearchFacade")
    private SearchFacade<ProductData, SearchStateData> flexibleSearchProductSearchFacade;

    @Resource(name = "b2bSolrProductSearchFacade")
    private SearchFacade<ProductData, SearchStateData> b2bSolrProductSearchFacade;

    @RequestMapping(value = "/advanced", method = RequestMethod.GET)
    public String advanceSearchResults(
            @RequestParam(value = "keywords", required = false, defaultValue = StringUtils.EMPTY) String keywords,
            @RequestParam(value = "searchResultType", required = false, defaultValue = ADVANCED_SEARCH_RESULT_TYPE_ORDER_FORM) final String searchResultType,
            @RequestParam(value = "q", defaultValue = StringUtils.EMPTY) String searchQuery,
            @RequestParam(value = "onlyProductIds", required = false, defaultValue = "false") final boolean onlyProductIds,
            @RequestParam(value = "isCreateOrderForm", required = false, defaultValue = "false") final boolean isCreateOrderForm,
            @RequestParam(value = "page", defaultValue = "0") final int page,
            @RequestParam(value = "show", defaultValue = "Page") final ShowMode showMode,
            @RequestParam(value = "sort", required = false) final String sortCode, final Model model,
            final HttpServletRequest request) throws CMSItemNotFoundException {
        String searchTerm = keywords;
        if (StringUtils.isNotBlank(searchQuery)) {
            searchTerm = StringUtils.split(searchQuery, ":")[0];
        }
        // check if it is order form (either order form was selected or "Create Order Form"
        final boolean useFlexibleSearch = isUseFlexibleSearch(onlyProductIds, isCreateOrderForm);
        final PageableData pageableData = createPageableData(page, getResultsCountForPagination(), sortCode,
                showMode);
        final SearchStateData searchState = createSearchStateData(request.getRequestURI(), searchTerm,
                isPopulateVariants(searchResultType, isCreateOrderForm));

        final SearchPageData<ProductData> searchPageData = performSearch(searchState, pageableData,
                useFlexibleSearch);
        populateModel(model, searchPageData, showMode);

        final AdvancedSearchForm form = new AdvancedSearchForm();
        form.setOnlyProductIds(Boolean.valueOf(onlyProductIds));
        form.setKeywords(searchTerm);
        form.setCreateOrderForm(isCreateOrderForm);
        if (isCreateOrderForm) {
            form.setSearchResultType(ADVANCED_SEARCH_RESULT_TYPE_ORDER_FORM);
            form.setFilterSkus(splitSkusAsList(searchTerm));
            form.setCreateOrderForm(Boolean.FALSE);
            form.setOnlyProductIds(Boolean.TRUE);
        } else {
            form.setSearchResultType(searchResultType);
        }

        final String breadcrumbText = getMessageSource().getMessage("search.advanced.meta.description.title", null,
                getCurrentLocale());
        final String metaInfoText = MetaSanitizerUtil
                .sanitizeDescription((StringUtils.isEmpty(searchTerm)) ? breadcrumbText : searchTerm);
        model.addAttribute(WebConstants.BREADCRUMBS_KEY,
                searchBreadcrumbBuilder.getBreadcrumbs(null, breadcrumbText, false));
        model.addAttribute("advancedSearchForm", form);
        model.addAttribute("futureStockEnabled", Boolean.valueOf(Config.getBoolean(FUTURE_STOCK_ENABLED, false)));
        model.addAttribute("paginateUrl", getPaginationUrlFromHttpRequest(request));
        storeCmsPageInModel(model, getContentPageForLabelOrId(NO_RESULTS_ADVANCED_PAGE_ID));
        addMetaData(model, "search.meta.description.results", metaInfoText, "search.meta.description.on",
                PageType.PRODUCTSEARCH, ThirdPartyConstants.SeoRobots.NOINDEX_FOLLOW);

        return getViewForPage(model);
    }

    protected ProductSearchStateData createSearchStateData(final String url, final String term,
            final boolean populateVariants) {

        final ProductSearchStateData searchState = new ProductSearchStateData();
        final SearchQueryData searchQueryData = new SearchQueryData();
        searchQueryData.setValue(XSSFilterUtil.filter(term));
        searchState.setQuery(searchQueryData);
        searchState.setPopulateVariants(populateVariants);
        searchState.setUrl(url);

        return searchState;
    }

    protected void addMetaData(final Model model, final String metaPrefixKey, final String searchText,
            final String metaPostfixKey, final PageType pageType, final String robotsBehaviour) {
        final String metaDescription = MetaSanitizerUtil
                .sanitizeDescription(getMessageSource().getMessage(metaPrefixKey, null, getCurrentLocale()) + " "
                        + searchText + " " + getMessageSource().getMessage(metaPostfixKey, null, getCurrentLocale())
                        + " " + getSiteName());
        final String metaKeywords = MetaSanitizerUtil.sanitizeKeywords(searchText);
        setUpMetaData(model, metaKeywords, metaDescription);

        model.addAttribute("pageType", pageType.name());
        model.addAttribute(ThirdPartyConstants.SeoRobots.META_ROBOTS, robotsBehaviour);
    }

    protected List<String> splitSkusAsList(final String skus) {
        return Arrays.asList(StringUtils.split(skus, Config.getString(ADVANCED_SEARCH_PRODUCT_IDS_DELIMITER,
                ADVANCED_SEARCH_PRODUCT_IDS_DELIMITER_DEFAULT)));
    }

    protected Locale getCurrentLocale() {
        return getI18nService().getCurrentLocale();
    }

    protected boolean isUseFlexibleSearch(final boolean onlyProductIds, final boolean isCreateOrderForm) {
        return onlyProductIds || isCreateOrderForm;
    }

    protected boolean isPopulateVariants(final String searchResultType, final boolean isCreateOrderForm) {
        return (StringUtils.equals(searchResultType, ADVANCED_SEARCH_RESULT_TYPE_ORDER_FORM)) || isCreateOrderForm;
    }

    protected ProductSearchPageData<SearchStateData, ProductData> performSearch(final SearchStateData searchState,
            final PageableData pageableData, final boolean useFlexibleSearch) {

        ProductSearchPageData<SearchStateData, ProductData> searchResult = createEmptySearchPageData();

        if (StringUtils.isNotBlank(searchState.getQuery().getValue())) {
            if (useFlexibleSearch) {
                searchResult = (ProductSearchPageData<SearchStateData, ProductData>) flexibleSearchProductSearchFacade
                        .search(searchState, pageableData);
            } else {
                // search using solr.
                searchResult = (ProductSearchPageData<SearchStateData, ProductData>) b2bSolrProductSearchFacade
                        .search(searchState, pageableData);
            }

        }

        return encodeSearchPageData(searchResult);
    }

    protected ProductSearchPageData<SearchStateData, ProductData> createEmptySearchPageData() {
        final ProductSearchPageData productSearchPageData = new ProductSearchPageData();

        productSearchPageData.setResults(Lists.newArrayList());
        final PaginationData pagination = new PaginationData();
        pagination.setTotalNumberOfResults(0);
        productSearchPageData.setPagination(pagination);
        productSearchPageData.setSorts(Lists.newArrayList());

        return productSearchPageData;
    }

    protected ProductSearchPageData<SearchStateData, ProductData> encodeSearchPageData(
            final ProductSearchPageData<SearchStateData, ProductData> searchPageData) {
        final SearchStateData currentQuery = searchPageData.getCurrentQuery();

        if (currentQuery != null) {
            final SearchQueryData query = currentQuery.getQuery();
            final String encodedQueryValue = StringEscapeUtils.escapeHtml(query.getValue());
            query.setValue(encodedQueryValue);
            currentQuery.setQuery(query);
            searchPageData.setCurrentQuery(currentQuery);

            final List<FacetData<SearchStateData>> facets = searchPageData.getFacets();
            if (CollectionUtils.isNotEmpty(facets)) {
                for (final FacetData<SearchStateData> facetData : facets) {
                    final List<FacetValueData<SearchStateData>> facetValueDatas = facetData.getValues();
                    if (CollectionUtils.isNotEmpty(facetValueDatas)) {
                        for (final FacetValueData<SearchStateData> facetValueData : facetValueDatas) {
                            final SearchStateData facetQuery = facetValueData.getQuery();
                            final SearchQueryData queryData = facetQuery.getQuery();
                            final String queryValue = queryData.getValue();
                            if (StringUtils.isNotBlank(queryValue)) {
                                final String[] queryValues = queryValue.split(":");
                                final StringBuilder queryValueBuilder = new StringBuilder();
                                queryValueBuilder.append(StringEscapeUtils.escapeHtml(queryValues[0]));
                                for (int i = 1; i < queryValues.length; i++) {
                                    queryValueBuilder.append(":").append(queryValues[i]);
                                }
                                queryData.setValue(queryValueBuilder.toString());
                            }
                        }
                    }

                    final List<FacetValueData<SearchStateData>> topFacetValueDatas = facetData.getTopValues();
                    if (CollectionUtils.isNotEmpty(topFacetValueDatas)) {
                        for (final FacetValueData<SearchStateData> topFacetValueData : topFacetValueDatas) {
                            final SearchStateData facetQuery = topFacetValueData.getQuery();
                            final SearchQueryData queryData = facetQuery.getQuery();
                            final String queryValue = queryData.getValue();
                            if (StringUtils.isNotBlank(queryValue)) {
                                final String[] queryValues = queryValue.split(":");
                                final StringBuilder queryValueBuilder = new StringBuilder();
                                queryValueBuilder.append(StringEscapeUtils.escapeHtml(queryValues[0]));
                                for (int i = 1; i < queryValues.length; i++) {
                                    queryValueBuilder.append(":").append(queryValues[i]);
                                }
                                queryData.setValue(queryValueBuilder.toString());
                            }
                        }
                    }
                }
            }
        }
        return searchPageData;
    }

    protected int getResultsCountForPagination() {
        return getSiteConfigService().getInt(ADVANCED_FLEXIBLE_SEARCH_PAGE_SIZE_PARAM, 25);
    }

    protected String getPaginationUrlFromHttpRequest(final HttpServletRequest request) {
        final Map<String, String[]> requestParamMap = request.getParameterMap();
        final StringBuilder queryParamBuilder = new StringBuilder();
        final Predicate<Map.Entry<String, String[]>> predicate = entry -> PAGINATION_PARAM_REMOVAL_LOOKUP_TABLE
                .contains(entry.getKey().trim().toUpperCase());
        queryParamBuilder.append("?");
        requestParamMap.entrySet().stream().filter(predicate.negate()).forEach(entry -> queryParamBuilder.append(
                ((queryParamBuilder.length() > 1) ? "&" : "") + entry.getKey() + "=" + entry.getValue()[0]));

        return queryParamBuilder.toString();
    }

}