com.amazon.unifiedsearch.service.transformers.SRDSTransformer.java Source code

Java tutorial

Introduction

Here is the source code for com.amazon.unifiedsearch.service.transformers.SRDSTransformer.java

Source

/**
 * SRDSTransformer.java
 *
 * Copyright (c) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * PROPRIETARY/CONFIDENTIAL
 *
 * Use is subject to license terms
 */
package com.amazon.unifiedsearch.service.transformers;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import com.amazon.searchapp.retailsearch.entity.DepartmentEntity;
import com.amazon.searchapp.retailsearch.entity.DidYouMeanEntity;
import com.amazon.searchapp.retailsearch.entity.FKMREntity;
import com.amazon.searchapp.retailsearch.entity.ImageEntity;
import com.amazon.searchapp.retailsearch.entity.LinkEntity;
import com.amazon.searchapp.retailsearch.entity.NoResultsSetEntity;
import com.amazon.searchapp.retailsearch.entity.PageEntity;
import com.amazon.searchapp.retailsearch.entity.PaginationEntity;
import com.amazon.searchapp.retailsearch.entity.PreloadImagesEntity;
import com.amazon.searchapp.retailsearch.entity.RefinementsEntity;
import com.amazon.searchapp.retailsearch.entity.RelatedSearchesEntity;
import com.amazon.searchapp.retailsearch.entity.ResponseMetadataEntity;
import com.amazon.searchapp.retailsearch.entity.SpellCorrectedEntity;
import com.amazon.searchapp.retailsearch.entity.StyledTextEntity;
import com.amazon.searchapp.retailsearch.entity.TrackingInfoEntity;
import com.amazon.searchapp.retailsearch.model.DidYouMean;
import com.amazon.searchapp.retailsearch.model.FKMR;
import com.amazon.searchapp.retailsearch.model.Image;
import com.amazon.searchapp.retailsearch.model.Link;
import com.amazon.searchapp.retailsearch.model.NoResultsSet;
import com.amazon.searchapp.retailsearch.model.Page;
import com.amazon.searchapp.retailsearch.model.Pagination;
import com.amazon.searchapp.retailsearch.model.Refinements;
import com.amazon.searchapp.retailsearch.model.RelatedSearches;
import com.amazon.searchapp.retailsearch.model.ResponseMetadata;
import com.amazon.searchapp.retailsearch.model.SpellCorrected;
import com.amazon.searchapp.retailsearch.model.StyledText;
import com.amazon.searchapp.retailsearch.model.TrackingInfo;
import com.amazon.unifiedsearch.service.entities.PreloadImages;
import com.amazon.unifiedsearch.service.entities.SearchResultEntity;
import com.amazon.unifiedsearch.service.entities.StoreSearchResMetaData;
import com.amazon.unifiedsearch.service.entities.StoreSearchResponse;
import com.amazon.unifiedsearch.service.entities.rsas.RSASResult;
import com.amazon.unifiedsearch.service.helpers.StoreSearchConstants;
import com.amazon.unifiedsearch.service.model.SRDSTransformerInput;
import com.amazon.unifiedsearch.service.model.SearchResult;
import com.amazon.unifiedsearch.service.util.SRDSTransFormerUtil;
import com.amazon.unifiedsearch.service.util.SRDSTransformerRefinementsBuilder;
import com.amazon.unifiedsearch.service.util.SRDSTransformerResultsBuilder;
import com.fasterxml.jackson.databind.ObjectMapper;

import amazon.RemoteSearchAggregator.Page.FKMRKeyword;
import lombok.extern.slf4j.Slf4j;

/**
 * Transformer to convert the USAS response to SRDS response
 */
@Slf4j
public class SRDSTransformer implements ITransformer<SRDSTransformerInput, String> {

    private final ObjectMapper srdsObjMapper;

    public SRDSTransformer(final ObjectMapper srdsObjMapper) {
        // TODO Auto-generated constructor stub
        this.srdsObjMapper = srdsObjMapper;
    }

    @Override
    public String transform(SRDSTransformerInput input) throws TransformerException {
        final SearchResult searchResult = new SearchResultEntity();
        String jsonString = StringUtils.EMPTY;
        try {
            //set the serachResult results attribute based on srdsTransformerInput
            setSearchResults(input, searchResult);
            //set FKM results
            setFKMRResults(input, searchResult);
            // setSpellCorrectedResults
            setSpellCorrectedResults(input, searchResult);
            // setRelatedSearches
            setRelatedSearches(input, searchResult);
            jsonString = srdsObjMapper.writeValueAsString(searchResult);
        } catch (Exception e) {
            log.error("Exception while store search response transform", e);
            throw new TransformerException("SRDSTransformer exception");
        }
        return jsonString;
    }

    /**
     * @param input
     * @param searchResult
     */
    private void setRelatedSearches(SRDSTransformerInput input, final SearchResult searchResult) {
        if (input.getStoreSearchResponse() != null
                && CollectionUtils.isNotEmpty(input.getStoreSearchResponse().getRelatedSearches()))
            searchResult.setRelatedSearches(getRelatedSearches(input));
    }

    /**
     * @param input
     * @param searchResult
     */
    private void setFKMRResults(SRDSTransformerInput input, SearchResult searchResult) {
        final List<FKMR> fkmrResultList = getFKMRList(input);
        //Maintaining at max 4 fkmr results in parity with SRDS
        if (CollectionUtils.isNotEmpty(fkmrResultList)) {
            int counter = 0;
            final int listSize = fkmrResultList.size();
            if (listSize > counter && counter < StoreSearchConstants.MAX_FKMR_RESULTS) {
                searchResult.setFkmrResults0(fkmrResultList.get(counter));
                counter++;
                if (listSize > counter && counter < StoreSearchConstants.MAX_FKMR_RESULTS) {
                    searchResult.setFkmrResults1(fkmrResultList.get(counter));
                    counter++;
                    if (listSize > counter && counter < StoreSearchConstants.MAX_FKMR_RESULTS) {
                        searchResult.setFkmrResults2(fkmrResultList.get(counter));
                        counter++;
                        if (listSize > counter && counter < StoreSearchConstants.MAX_FKMR_RESULTS) {
                            searchResult.setFkmrResults3(fkmrResultList.get(counter));
                        }
                    }
                }
            }
        }
    }

    /**
     * @param input
     * @param searchResult
     */
    private void setSpellCorrectedResults(SRDSTransformerInput input, final SearchResult searchResult) {
        if (input.getStoreSearchResponse() != null
                && CollectionUtils.isNotEmpty(input.getStoreSearchResponse().getSpellCorrectedResults())) {
            final List<SpellCorrected> spellCorrectedList = getSpellCorrectedResult(input);
            if (CollectionUtils.isNotEmpty(spellCorrectedList)) {
                searchResult.setSpellCorrectedResults(spellCorrectedList.get(0));
                final String correctKeyword = searchResult.getSpellCorrectedResults().getCorrectedKeywords();
                //Need to set didYouMean when there is spellCorrection
                searchResult.setDidYouMean(SRDSTransFormerUtil.getDidYouMean(correctKeyword, input.getAlias()));
            }
        }
    }

    /**
     * @param input
     * @param searchResult
     */
    private void setSearchResults(SRDSTransformerInput input, SearchResult searchResult) {
        if (input.getStoreSearchResponse() != null) {

            searchResult.setResponseMetadata(SRDSTransFormerUtil.getSearchResponseMetadata());

            if (input.getStoreSearchResponse().getStoreSearchMetaData() != null) {
                searchResult.setTrackingInfo(getTrackingInfo(input));

                // To set noResults if there is ApplicationFailure and there is no results for the searched keyword
                if (input.getStoreSearchResponse().getStoreSearchMetaData().isApplicationFailure()
                        && input.getStoreSearchResponse().getResults() == null && input.getPage() == 1L) {
                    searchResult.setNoResults(getNoResults(input));
                    searchResult.setRefinements(SRDSTransformerRefinementsBuilder.getRefinements(input));
                }
                // To handle the case when there is no results but fkmrResults are expanding more than a page.
                else if (input.getStoreSearchResponse().getStoreSearchMetaData().isApplicationFailure()
                        && input.getStoreSearchResponse().getResults() == null && input.getPage() == 2L
                        && input.getStoreSearchResponse().getFkmrResults() != null) {
                    searchResult.setRefinements(SRDSTransformerRefinementsBuilder.getRefinements(input));
                } else {
                    searchResult.setPreloadImages(getPreloadImages(input));
                    // To set results and filters when results list is not empty
                    if (input.getStoreSearchResponse().getResults() != null && CollectionUtils
                            .isNotEmpty(input.getStoreSearchResponse().getResults().getResults())) {
                        searchResult.setResults(SRDSTransformerResultsBuilder.getResults(input));
                        searchResult.setResultsMetadata(SRDSTransformerResultsBuilder.getResultsMetadata(input));
                        searchResult.setSort(SRDSTransformerRefinementsBuilder.getSort(input));
                        searchResult.setRefinements(SRDSTransformerRefinementsBuilder.getRefinements(input));
                    } else {
                        Refinements srdsRefinements = new RefinementsEntity();
                        DepartmentEntity departmentEntity = new DepartmentEntity();
                        departmentEntity.setExpandCategories(false);
                        srdsRefinements.setDepartments(departmentEntity);
                        searchResult.setRefinements(srdsRefinements);
                    }
                    searchResult.setPagination(getPages(input));
                }
            }
        }
    }

    /**
     *
     * @param input
     * @return NoResultsSet
     */
    private NoResultsSet getNoResults(SRDSTransformerInput input) {
        NoResultsSet noResultsSet = new NoResultsSetEntity();
        noResultsSet.setStyledText(SRDSTransFormerUtil.getStyleTextForNoResult(input.getKeyword()));
        return noResultsSet;
    }

    /**
     *
     * @param input
     * @return PreloadImages
     */
    private com.amazon.searchapp.retailsearch.model.PreloadImages getPreloadImages(SRDSTransformerInput input) {
        final com.amazon.searchapp.retailsearch.model.PreloadImages preloadImages = new PreloadImagesEntity();
        List<Image> srdsImages = new ArrayList<Image>();
        final PreloadImages images = input.getStoreSearchResponse().getPreloadImages();
        if (images != null) {
            for (String imageUrl : images.getImageUrls()) {
                final ImageEntity imageEntity = new ImageEntity();
                imageEntity.setUrl(imageUrl);
                imageEntity.setWidth(StoreSearchConstants.DEFAULT_IMAGE_WIDTH);
                imageEntity.setHeight(StoreSearchConstants.DEFAULT_IMAGE_HEIGHT);
                srdsImages.add(imageEntity);
            }
        }
        if (srdsImages.size() > 0) {
            preloadImages.setImages(srdsImages);
        }
        return preloadImages;
    }

    /**
     *
     * @param input
     * @return TrackingInfo
     */
    private TrackingInfo getTrackingInfo(SRDSTransformerInput input) {
        final TrackingInfo trackingInfo = new TrackingInfoEntity();
        StoreSearchResMetaData storeSearchResMetaData = input.getStoreSearchResponse().getStoreSearchMetaData();
        trackingInfo.setIsUnsupportedRequest(storeSearchResMetaData.isUnsupportedRequest());
        trackingInfo.setIsApplicationFailure(storeSearchResMetaData.isApplicationFailure());
        trackingInfo.setRid(storeSearchResMetaData.getRequestid());
        trackingInfo.setQid(storeSearchResMetaData.getQueryId());
        trackingInfo.setSearchKeywords(storeSearchResMetaData.getSearchKeywords());
        trackingInfo.setSearchAlias(storeSearchResMetaData.getSearchAlias());
        trackingInfo.setSearchAliasDisplayName(storeSearchResMetaData.getSearchAliasDisplayName());
        return trackingInfo;
    }

    /**
     *
     * @param input
     * @return SpellCorrected List
     */
    private List<SpellCorrected> getSpellCorrectedResult(SRDSTransformerInput input) {
        final List<SpellCorrected> spellCorrectedResults = new ArrayList<SpellCorrected>();
        final List<RSASResult> rsasResultList = input.getStoreSearchResponse().getSpellCorrectedResults();
        for (RSASResult rsasResult : rsasResultList) {
            final SpellCorrected spellCorrected = new SpellCorrectedEntity();
            List<StyledText> styledTextList = new ArrayList<StyledText>();
            StyledText styledText = new StyledTextEntity();
            styledText.setStyle(StoreSearchConstants.PLAN_STYLE);
            styledText.setText(StoreSearchConstants.SPELL_CORRECTION_LABEL + "\"" + rsasResult.getSearch() + "\"");
            styledTextList.add(styledText);
            spellCorrected.setStyledText(styledTextList);
            //Set detailedStyledText when the result list is empty
            if (input.getStoreSearchResponse().getResults() == null
                    || CollectionUtils.isEmpty(input.getStoreSearchResponse().getResults().getResults()))
                spellCorrected
                        .setDetailedStyledText(SRDSTransFormerUtil.getStyleTextForNoResult(input.getKeyword()));
            if (CollectionUtils.isNotEmpty(rsasResult.getStoresearchResultList())) {
                spellCorrected
                        .setResults(SRDSTransFormerUtil.getEntityResults(rsasResult.getStoresearchResultList()));
            }
            spellCorrected.setCorrectedKeywords(rsasResult.getSearch());
            spellCorrectedResults.add(spellCorrected);
        }
        return spellCorrectedResults;
    }

    /**
    *
    * @param input
    * @return fkmr List
    */
    private List<FKMR> getFKMRList(SRDSTransformerInput input) {
        List<FKMR> fkmrList = new ArrayList<FKMR>();

        final StoreSearchResponse storeSearchResponse = input.getStoreSearchResponse();

        // get RSASResultList from storeSearchResponse
        if (CollectionUtils.isNotEmpty(storeSearchResponse.getFkmrResults())) {
            final List<RSASResult> rsasResultList = storeSearchResponse.getFkmrResults();
            int count = 0;
            for (RSASResult rsasResult : rsasResultList) {
                count++;
                final FKMR fkmr = new FKMREntity();
                List<StyledText> keyWords = new ArrayList<StyledText>();
                final List<FKMRKeyword> fkmrKeywords = rsasResult.getFkmrSearchKeywords();
                String keyToSearch = StringUtils.EMPTY;
                if (fkmrKeywords != null) {
                    fkmr.setKeywords(SRDSTransFormerUtil.getFkmrKeyWords(fkmrKeywords));
                    for (StyledText styleFkmr : fkmr.getKeywords()) {
                        if (styleFkmr.getStyle() != StoreSearchConstants.STRIKE_STYLE)
                            keyToSearch += styleFkmr.getText();
                    }
                }
                if (count == 1) //Set styledText attribute for the first fkmr result
                    fkmr.setStyledText(SRDSTransFormerUtil.getStyleTextForNoResult(input.getKeyword()));
                if (CollectionUtils.isNotEmpty(rsasResult.getStoresearchResultList())) {
                    fkmr.setResults(SRDSTransFormerUtil.getEntityResults(rsasResult.getStoresearchResultList()));
                }
                fkmr.setTotalResults(rsasResult.getResultSize());
                final String encodeKeyword = SRDSTransFormerUtil.getEncodedString(keyToSearch);
                final String url = "/store?page=1&query=" + encodeKeyword + "&keywords=" + encodeKeyword
                        + "&department=" + input.getAlias();
                Link seeAllLink = new LinkEntity();
                seeAllLink.setText("See all " + rsasResult.getResultSize() + " results");
                seeAllLink.setUrl(url);
                fkmr.setSeeAllLink(seeAllLink);
                fkmrList.add(fkmr);
            }
        }
        return fkmrList;
    }

    /**
    *
    * @param input
    * @return Pagination
    */
    private Pagination getPages(SRDSTransformerInput input) {
        final Pagination paginationEntity = new PaginationEntity();
        paginationEntity.setNumPages(StoreSearchConstants.DEFAULT_PAGES_SIZE);
        List<Page> pageEntities = new ArrayList<Page>();
        // set current page
        final PageEntity currentPageEntity = new PageEntity();
        currentPageEntity.setPage(input.getPage().intValue());
        currentPageEntity.setType(StoreSearchConstants.CURRENT_PAGE);
        LinkEntity currentLinkEntity = new LinkEntity();
        currentLinkEntity.setText(input.getPage().toString());
        currentPageEntity.setLink(currentLinkEntity);
        pageEntities.add(currentPageEntity);

        if (input.getStoreSearchResponse().getResults() != null) {
            final PageEntity nextPageEntity = new PageEntity();
            // TODO take from request and set this
            final Long nextPage = input.getPage() + 1;
            nextPageEntity.setPage(nextPage.intValue());
            nextPageEntity.setType(StoreSearchConstants.NEXT_PAGE);
            final LinkEntity nextLinkEntity = new LinkEntity();
            nextLinkEntity.setText(StoreSearchConstants.NEXT_PAGE_TEXT);
            String url = "/store?page=" + nextPage.toString() + "&sortBy=" + input.getSort() + "&query="
                    + input.getKeyword() + "&department=" + input.getAlias();
            if (input.getRefinementsMap() != null && !input.getRefinementsMap().isEmpty()) {
                url += "&filters=" + SRDSTransformerRefinementsBuilder
                        .getRefinementsMapAsString(input.getRefinementsMap(), null);
            }
            nextLinkEntity.setUrl(url);
            nextPageEntity.setLink(nextLinkEntity);
            pageEntities.add(nextPageEntity);
        }

        paginationEntity.setPages(pageEntities);
        return paginationEntity;
    }

    /**
     *
     * @param input
     * @return RelatedSearches
     */
    private RelatedSearches getRelatedSearches(SRDSTransformerInput input) {
        final RelatedSearches relatedSearches = new RelatedSearchesEntity();
        // get RSASResultList from storeSearchResponse
        final List<String> relatedSearchList = input.getStoreSearchResponse().getRelatedSearches();
        List<Link> relatedLinks = new ArrayList<Link>();
        for (String relatedSearch : relatedSearchList) {
            final Link link = new LinkEntity();
            final String encodedSearch = SRDSTransFormerUtil.getEncodedString(relatedSearch);
            final String url = "/store?page=1&query=" + encodedSearch + "&keywords=" + encodedSearch
                    + "&department=" + input.getAlias();
            link.setText(relatedSearch);
            link.setUrl(url);
            relatedLinks.add(link);
        }
        if (CollectionUtils.isNotEmpty(relatedLinks)) {
            relatedSearches.setAltQueries(relatedLinks);
            relatedSearches.setLabel(StoreSearchConstants.RELATED_SEARCHES);
        }
        return relatedSearches;
    }
}