Subversion Repositories SmartDukaan

Rev

Rev 7263 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.serving.controllers;

import in.shop2020.datalogger.EventType;
import in.shop2020.model.v1.catalog.Category;
import in.shop2020.model.v1.order.HotspotStore;
//import in.shop2020.serving.cache.EhcacheWrapper.CacheKeys;
//import in.shop2020.serving.cache.SnippetCacheWrapper;
import in.shop2020.serving.cache.EhcacheWrapper.CacheKeys;
import in.shop2020.serving.cache.SnippetCacheWrapper;
import in.shop2020.serving.service.SearchService;
import in.shop2020.serving.utils.Utils;
import in.shop2020.thrift.clients.TransactionClient;
import in.shop2020.utils.CategoryManager;
import in.shop2020.utils.DataLogger;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.convention.annotation.Result;

import com.google.gson.Gson;


/**
 * @author rajveer
 *
 */
@Result(name="redirect", location="${location}", type="redirect")
public class SearchController extends BaseController {

    private static final long serialVersionUID = -8392433517042806559L;
    private static Logger log = Logger.getLogger(Class.class);

    private List<String> results;
    private Map<String, Double> dynamicSearchMap;

    /**
     * 
     */
    private Map<String, String> snippets;
    
    /**
     * 
     */
    private Map<String, List<String[]>> facets = null;
    
    /**
     * 
     */
    private Map<String, List<List<String>>> crumbs;
    
    private String  query;
    private String  q;
    private String sortOrder = null;
    private Double minPrice = null;
    private Double maxPrice = null;

    private long windowSize = 20;
    private long page = 1;
    private long totalResults;
    private long beginIndex = 0;
    private String url;
    private String priceUrl = "?";
    private String sortUrl;
    private String location;
    private static HashMap<String, List<String>> categoriesChildren = null;
    private static Map<Long, String> categoryLabelMap = null;
    
    /**
     * 
     * @return
     * @throws UnsupportedEncodingException
     */
    // GET /query

    public String index() {
        String loginStatus = (String) request.getSession().getAttribute("LOGGED_IN");
        if(loginStatus == null || !loginStatus.equals("TRUE")){
            return "authfail";
        }
        
        storeId = Long.parseLong((String) request.getSession().getAttribute("STORE_ID"));
        if(!hotspotStores.containsKey(storeId)){
            try{
                HotspotStore hotSpotStore = (new TransactionClient()).getClient().getHotspotStore(storeId, "");
                hotspotStores.put(storeId, hotSpotStore);
            } catch (Exception e) {
                log.error("Unable to get store", e);
            }
        }
        
        log.info("this.request=" + this.request);
        
        //url = this.request.getRequestURL();
        query = this.request.getParameter("q");
        q = this.query;
        try {
            url = "q="+ URLEncoder.encode(query, "UTF-8");

            if(query.trim().isEmpty()){
                    location = "/";
                    return "redirect";
            }
            sortUrl = url;
            if(this.request.getParameter("sort") != null){
                url= url + "&sort=" + this.request.getParameter("sort");
                sortOrder = this.request.getParameter("sort");
            }
            priceUrl += url;
            if(this.request.getParameter("page") != null){
                this.page = Long.parseLong(this.request.getParameter("page"));
                this.beginIndex = this.windowSize * (this.page-1);
            }
            if(this.request.getParameter("minPrice") != null){
                this.minPrice = (new Double(this.request.getParameter("minPrice")));
                url= url + "&minPrice=" + this.request.getParameter("minPrice");
            }
            if(this.request.getParameter("maxPrice") != null){
                this.maxPrice = (new Double(this.request.getParameter("maxPrice")));
                url= url + "&maxPrice=" + this.request.getParameter("maxPrice");
            }       
            
            
            String[] fqrys = this.request.getParameterValues("fq");
            
            this.crumbs = new HashMap<String, List<List<String>>>();
            
                    
            String urlCrumb = "";
            if(query != null) {
                urlCrumb = url; 
            }else {
                
            }
            
            if(fqrys != null) {
                log.info("fqrys=" + Arrays.toString(fqrys));
                String filterUrl = "";
                for(int i=0; i<fqrys.length; i++){
                    urlCrumb += "&fq=" + URLEncoder.encode(fqrys[i], "UTF-8");
                    priceUrl += "&fq=" + URLEncoder.encode(fqrys[i], "UTF-8");
                    sortUrl += "&fq=" + URLEncoder.encode(fqrys[i], "UTF-8");
                    String facetName = StringUtils.split(fqrys[i], ":")[0];
                    String facetValue = StringUtils.split(fqrys[i], ":")[1];
                    String facetLabel = Utils.FACET_LABEL_MAP.get(facetName);
                    filterUrl = "&fq=" + URLEncoder.encode(fqrys[i], "UTF-8"); 
                    List<String> acrumb = Arrays.asList(facetValue, filterUrl);
                    if(!crumbs.containsKey(facetLabel)) {
                        crumbs.put(facetLabel, new ArrayList<List<String>>());
                    }
                    
                    this.crumbs.get(facetLabel).add(acrumb);
                }
            }
            url = urlCrumb;
    
            
            
            SearchService search = new SearchService(query, fqrys, (page-1)*windowSize, windowSize, minPrice, maxPrice, sortOrder, sourceId);
    
            this.results =  search.getResultMap(); 
            this.dynamicSearchMap = search.getDynamicPriceMap();
            // Facets
            List<String> fqs = null;
            if (fqrys != null) {
                fqs = Arrays.asList(fqrys);
            }else {
                fqs = new ArrayList<String>();
            }
            
            setFacet(fqs, search);
            
            //If 
            Map<String, Double> priceMap = search.getPriceStatsMap();
            if(priceMap != null){
                if (this.minPrice == null){
                    this.minPrice = priceMap.get("min");
                }
                if(this.maxPrice == null) {
                    this.maxPrice = priceMap.get("max");
                }
            } else{
                this.minPrice = 0.0;
                this.maxPrice = 0.0;
            }
            
            this.totalResults = search.getTotalResults();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "index";
    }


    private void setFacet(List<String> fqs, SearchService search) throws Exception{

        this.facets = new LinkedHashMap<String, List<String[]>>();
        List<String> filtrableFacets = search.getFilterableFacets();
        for (String filtrableFacet : filtrableFacets) {
            
            Map<String, Integer> facetDetailMap = search.getFacetDetails(filtrableFacet);
            if(facetDetailMap==null)
                continue;
            List<String[]> values = new ArrayList<String[]>();
            for(Entry<String, Integer> facetEntry : facetDetailMap.entrySet()){
                String selected = "";
                if(fqs.contains(filtrableFacet + ":" + facetEntry.getKey())) {
                    selected = "checked=\"checked\"";
                }
                String facet = facetEntry.getKey();
                String drilldownURL = "&fq=" +  
                    URLEncoder.encode( filtrableFacet + ":" + facet, "UTF-8"); 
                String[] afacet = new String[] { facet, 
                      facetEntry.getValue().toString(), drilldownURL,  selected};
                values.add(afacet);    
            }
            
            this.facets.put(Utils.FACET_LABEL_MAP.get(filtrableFacet), values);
        }
    }


    public Map<String, String> getSnippets() throws Exception {
        if(results != null){
            snippets = new HashMap<String, String>();   
            for(String docId: results){
                String snippet = (String)SnippetCacheWrapper.getSnippet(CacheKeys.CATEGORY_SNIPPET_CACHE_KEY, docId, sourceId);
                if (snippet != null) {
                    snippets.put(docId, snippet);
                }
            }
        }
        return snippets;
    }
    
    /**
     * 
     * @return
     */
    public String getQuery() {
        return this.query;
    }
    
    
    /**
     * 
     * @return
     */
    public List<String> getResults() {
        return this.results;
    }
    
    /**
     * 
     * @return
     */
    public Map<String, List<String[]>> getFacets() {
        return this.facets;
    }
    
    public long getTotalResults(){
        return totalResults;
    }
    
    public String getUrl(){
        return this.url;
    }

    public String getPriceUrl(){
        return this.priceUrl;
    }
    
    public String getSortUrl(){
        return this.sortUrl;
    }
    
    public long getBeginIndex(){
        if(totalResults>0)
            return beginIndex+1;
        return beginIndex;
    }

    public long getTotalPages() {
        return 1 + (totalResults-1)/windowSize;
    }

    public long getCurrentPage() {
        return this.page;
    }

    public Double getMinPrice() {
        return this.minPrice;
    }
    
    public Double getMaxPrice() {
        return this.maxPrice;
    }
    
    public Map<String, List<List<String>>> getCrumbs() {
        return this.crumbs;
    }

    public String getSortOrder(){
        return this.sortOrder;
    }
    
    public String getLocation(){
        return this.location;
    }
    
    public List<String> getChildren(String categoryLabel) {
        return getCategoriesChildren().get(categoryLabel);
    }
    
    public static Map<String, List<String>> getCategoriesChildren(){
        Map<Long,String> idLabelMap = new HashMap<Long, String>(); 
        if (categoriesChildren == null) {
            categoriesChildren = new HashMap<String, List<String>>();
            for (Category category: CategoryManager.getCategoryManager().getCategories().values()){
                idLabelMap.put(category.getId(), category.getLabel());
            }
            for (Category category: CategoryManager.getCategoryManager().getCategories().values()){
                if(category.getParent_category_id() != 10000 && category.getParent_category_id() != 0 &&
                        category.getParent_category_id() != Utils.MOBILE_PHONES_CATEGORY){
                    String parentLabel = idLabelMap.get(category.getParent_category_id());
                    if(!categoriesChildren.containsKey(parentLabel)){
                        categoriesChildren.put(parentLabel, new ArrayList<String>());
                    }
                    categoriesChildren.get(parentLabel).add(category.getLabel());
                }
            }
        }
        
        return categoriesChildren;
    }
    
    public static String getCategoryLabel(Long id){
        if(categoryLabelMap == null){
            Map<Long,String> idLabelMap = new HashMap<Long, String>(); 
            for (Category category: CategoryManager.getCategoryManager().getCategories().values()){
                idLabelMap.put(category.getId(), category.getLabel());
            }
            categoryLabelMap = idLabelMap;
        } 
        return categoryLabelMap.get(id);
    }
    
    public String getDynamicSearchMap(){
        if (this.dynamicSearchMap == null) {
            return "{}";
        } else {
            return new Gson().toJson(this.dynamicSearchMap);
        }
    }


        public void setQ(String q) {
                this.q = q;
        }


        public String getQ() {
                return q;
        }
}