Index: branches/pssGrails3/grails-app/services/com/lemanscorp/search/solr/SolrResponseService.groovy =================================================================== diff -u -r8884 -r8888 --- branches/pssGrails3/grails-app/services/com/lemanscorp/search/solr/SolrResponseService.groovy (.../SolrResponseService.groovy) (revision 8884) +++ branches/pssGrails3/grails-app/services/com/lemanscorp/search/solr/SolrResponseService.groovy (.../SolrResponseService.groovy) (revision 8888) @@ -1,993 +1,988 @@ package com.lemanscorp.search.solr - +import com.lemanscorp.search.SearchException +import com.lemanscorp.search.SearchUtils import grails.converters.JSON +import org.json.JSONObject import java.util.regex.Matcher import java.util.regex.Pattern -import org.codehaus.groovy.grails.web.json.JSONObject - -import com.lemanscorp.search.SearchException -import com.lemanscorp.search.SearchUtils - class SolrResponseService { - def solrRequestService + def solrRequestService - def solrService + def solrService - SearchUtils searchUtils =new SearchUtils() + SearchUtils searchUtils = new SearchUtils() - /** - * - * @param params - * @param selectedFacetsMap - * @param nextFacets - * @param solrResponse - * @param renderers - * @param sortBys - * @param hitlistDoc - * @param psResponse - * @param selectedConfigFacets - to get the display name and sequence from database config. - * @return - */ - PartSearchResponse processJSON(params, selectedFacetsMap, nextFacets, solrResponse, renderers, sortBys, hitlistDoc, psResponse, selectedConfigFacets, domainConfigFacets, uiConfig){ + /** + * + * @param params + * @param selectedFacetsMap + * @param nextFacets + * @param solrResponse + * @param renderers + * @param sortBys + * @param hitlistDoc + * @param psResponse + * @param selectedConfigFacets - to get the display name and sequence from database config. + * @return + */ + PartSearchResponse processJSON(params, selectedFacetsMap, nextFacets, solrResponse, renderers, sortBys, hitlistDoc, psResponse, + selectedConfigFacets, domainConfigFacets, uiConfig) { - def solrJson = JSON.parse(solrResponse) + def solrJson = JSON.parse(solrResponse) - /* Header */ - List selectedFCs = populateSelectedFacets(params, selectedFacetsMap, solrJson, selectedConfigFacets, domainConfigFacets); + /* Header */ + List selectedFCs = populateSelectedFacets(params, selectedFacetsMap, solrJson, selectedConfigFacets, domainConfigFacets) - Header header = psResponse.header - //set original search term in response as we are sending solr query syntax in q field now. - def term = solrService.nullToGenricSearch(params.q) - header.q = term - header.fq = solrJson.responseHeader.params.fq - header.rows = solrJson.responseHeader.params.rows as int - header.start = solrJson.response.start - header.facets = selectedFCs - //set requested page numbers - //selected start and end page + Header header = psResponse.header + //set original search term in response as we are sending solr query syntax in q field now. + def term = solrService.nullToGenricSearch(params.q) + header.q = term + header.fq = solrJson.responseHeader.params.fq + header.rows = solrJson.responseHeader.params.rows as int + header.start = solrJson.response.start + header.facets = selectedFCs + //set requested page numbers + //selected start and end page // header.pageNumbers.pageStart = params.pageStart // header.pageNumbers.pageEnd = params.pageEnd - header.pageNumbers.pn = params.pn - //context (could be ci or ct*) - start and end page - header.pageNumbers.contextPageStart = uiConfig?.contextPageStart - header.pageNumbers.contextPageEnd = uiConfig?.contextPageEnd + header.pageNumbers.pn = params.pn + //context (could be ci or ct*) - start and end page + header.pageNumbers.contextPageStart = uiConfig?.contextPageStart + header.pageNumbers.contextPageEnd = uiConfig?.contextPageEnd - //echo back the query params for search fields. Currently on search fields e.g. sf_partNumber are echoed back. - params?.keySet()?.findAll{it?.startsWith('sf_')}.collect { - header.queryParams."$it" = params."$it" - } + //echo back the query params for search fields. Currently on search fields e.g. sf_partNumber are echoed back. + params?.keySet()?.findAll { it?.startsWith('sf_') }.collect { + header.queryParams."$it" = params."$it" + } + //set total count on the header + header.facets.each { facet -> + facet.count = getTotalFacetCount(facet) + } - //set total count on the header - header.facets.each{ facet-> - facet.count = getTotalFacetCount(facet) - } + /* Set Renderer */ - /* Set Renderer */ + header.renderers = renderers - header.renderers = renderers + if (solrJson.spellcheck?.suggestions) { + def suggestions = solrJson.spellcheck?.suggestions + def suggestionsList = [] + def collations = [] + suggestions.eachWithIndex { item, i -> + if (item == 'collation') { + collations.addAll(suggestions[i + 1]) + } else if (item instanceof JSONObject) { + suggestionsList.addAll(item?.suggestion?.toArray()) + } + } + def collation = solrJson.spellcheck?.collations + collation.eachWithIndex { item, i -> + if (item == 'collation') { + collations.addAll(collation[i + 1]) + } + } + header.spellcheck = ['collation': collations, suggestions: suggestionsList] - if(solrJson.spellcheck?.suggestions) { - def suggestions = solrJson.spellcheck?.suggestions - def suggestionsList = [] - def collations = [] - suggestions.eachWithIndex {item, i -> - if(item == 'collation') { - collations.addAll(suggestions.getAt(i+1)) - } else if (item instanceof JSONObject) { - suggestionsList.addAll(item?.suggestion?.toArray()) - } - } - def collation = solrJson.spellcheck?.collations - collation.eachWithIndex {item, i -> - if(item == 'collation') { - collations.addAll(collation.getAt(i+1)) - } - } - header.spellcheck =['collation':collations , suggestions: suggestionsList] + } - } + /* Next Facets */ + psResponse.facets = populateNextFacets(params, selectedFacetsMap, nextFacets, solrJson, domainConfigFacets) - /* Next Facets */ - psResponse.facets = populateNextFacets(params, selectedFacetsMap, nextFacets, solrJson, domainConfigFacets) + /* Based on renderer populate hitlist & total count */ + renderers.each { renderer -> + switch (renderer) { + case 'part': + header.total = solrJson.response.numFound + if (params?.outfields) { + psResponse.hitlist.parts = solrJson.response?.docs + } else { + psResponse.hitlist.parts = processPartResponse(solrJson) + } + break + case 'inactivePart': + header.total = solrJson.response.numFound + if (params?.outfields) { + psResponse.hitlist.parts = solrJson.response?.docs + } else { + psResponse.hitlist.parts = processPartResponse(solrJson) + } + break + case 'fitment': + header.total = solrJson.response.numFound + //do not need hitlist for this doc type + psResponse.hitlist.fitments = [] + break + case 'product': + //set the total properties to header for products. This will overwrite the parts total count + header.total = solrJson.response.numFound + //set the products + psResponse.hitlist.type = 'pr' + if (params?.outfields) { + psResponse.hitlist.products = solrJson.response?.docs + } else { + psResponse.hitlist.products = processProductResponse(solrJson) + } + break + case 'masterProduct': + header.total = solrJson.response.numFound + psResponse.hitlist.type = 'mpr' + if (params?.outfields) { + psResponse.hitlist.masterProducts = solrJson.response?.docs + } else { + psResponse.hitlist.masterProducts = processProductResponse(solrJson) + } + break + case 'productGroup': + //set the total properties to header for products. This will overwrite the parts total count + header.total = solrJson.response.numFound + //set the products + psResponse.hitlist.type = 'prg' + if (params?.outfields) { + psResponse.hitlist.productGroups = solrJson.response?.docs + } else { + psResponse.hitlist.productGroups = processProductGroupResponse(solrJson) + } + break + case 'category': + def ct = solrRequestService.getNextCategory(params) + psResponse.hitlist.type = "$ct" + header.total = hitlistDoc.categories.catalog.size() + psResponse.hitlist.categories = processCategoryResponse(hitlistDoc) + break + case 'catalog': + psResponse.hitlist.type = 'ci' + header.total = hitlistDoc.catalogs.catalog.size() + psResponse.hitlist.catalogs = processCatalogResponse(hitlistDoc) + break - /* Based on renderer populate hitlist & total count */ - renderers.each{ renderer-> - switch (renderer) { - case 'part': - header.total = solrJson.response.numFound - if(params?.outfields) { - psResponse.hitlist.parts = solrJson.response?.docs - } else { - psResponse.hitlist.parts = processPartResponse(solrJson) - } - break; - case 'inactivePart': - header.total = solrJson.response.numFound - if(params?.outfields) { - psResponse.hitlist.parts = solrJson.response?.docs - } else { - psResponse.hitlist.parts = processPartResponse(solrJson) - } - break; - case 'fitment': - header.total = solrJson.response.numFound - //do not need hitlist for this doc type - psResponse.hitlist.fitments = [] - break; - case 'product': - //set the total properties to header for products. This will overwrite the parts total count - header.total = solrJson.response.numFound - //set the products - psResponse.hitlist.type = 'pr' - if(params?.outfields) { - psResponse.hitlist.products = solrJson.response?.docs - } else { - psResponse.hitlist.products = processProductResponse(solrJson) - } - break; - case 'masterProduct': - header.total = solrJson.response.numFound - psResponse.hitlist.type = 'mpr' - if(params?.outfields) { - psResponse.hitlist.masterProducts = solrJson.response?.docs - } else { - psResponse.hitlist.masterProducts = processProductResponse(solrJson) - } - break - case 'productGroup': - //set the total properties to header for products. This will overwrite the parts total count - header.total = solrJson.response.numFound - //set the products - psResponse.hitlist.type = 'prg' - if(params?.outfields) { - psResponse.hitlist.productGroups = solrJson.response?.docs - } else { - psResponse.hitlist.productGroups = processProductGroupResponse(solrJson) - } - break; - case 'category': - def ct = solrRequestService.getNextCategory(params) - psResponse.hitlist.type = "$ct" - header.total = hitlistDoc.categories.catalog.size() - psResponse.hitlist.categories = processCategoryResponse(hitlistDoc) - break; - case 'catalog': - psResponse.hitlist.type = 'ci' - header.total = hitlistDoc.catalogs.catalog.size() - psResponse.hitlist.catalogs = processCatalogResponse(hitlistDoc) - break; + default: + break + } + } - default: - break; - } - } + psResponse + } - return psResponse - } + /** + * Populate Header + * @param params + * @param selectedFacetsMap + * @param solrJson + * @return + */ + List populateSelectedFacets(params, selectedFacetsMap, solrJson, selectedConfigFacets, domainConfigFacets) { + def retFeatures = [] - /** - * Populate Header - * @param params - * @param selectedFacetsMap - * @param solrJson - * @return - */ - List populateSelectedFacets(params, selectedFacetsMap, solrJson, selectedConfigFacets, domainConfigFacets){ + def avMap = [:] - def retFeatures = [] + def selectedFacets = selectedFacetsMap.keySet() - def avMap = [:] + def jsonFacetFields = solrJson.facet_counts.facet_fields - def selectedFacets = selectedFacetsMap.keySet() + def dm = params.dm ? params.dm : '\\d*' + def ci = selectedFacetsMap.get('ci') ? selectedFacetsMap.get('ci').join('|') : '\\d*' + def ct1 = selectedFacetsMap.get('ct1') ? selectedFacetsMap.get('ct1').join('|') : '\\d*' + def ct2 = selectedFacetsMap.get('ct2') ? selectedFacetsMap.get('ct2').join('|') : '\\d*' + def pns = selectedFacetsMap.get('pn') ? selectedFacetsMap.get('pn').join('|') : '\\d*' - def jsonFacetFields = solrJson.facet_counts.facet_fields + //create patterns - def dm = params.dm ? params.dm : '\\d*' - def ci = selectedFacetsMap.get('ci') ? selectedFacetsMap.get('ci').join('|') : '\\d*' - def ct1 = selectedFacetsMap.get('ct1') ? selectedFacetsMap.get('ct1').join('|') : '\\d*' - def ct2 = selectedFacetsMap.get('ct2') ? selectedFacetsMap.get('ct2').join('|') : '\\d*' - def ct3 = selectedFacetsMap.get('ct3') ? selectedFacetsMap.get('ct3').join('|') : '\\d*' - def yrs = selectedFacetsMap.get('yr') ? selectedFacetsMap.get('yr').join('|') : null - def mds = selectedFacetsMap.get('md') ? selectedFacetsMap.get('md').join('|') : null - def mks = selectedFacetsMap.get('mk') ? selectedFacetsMap.get('mk').join('|') : null - def pr = params.pr ? params.pr : null - def pns = selectedFacetsMap.get('pn') ? selectedFacetsMap.get('pn').join('|') : '\\d*' - - - //create patterns - def ci_pattern = Pattern.compile(/^$dm\|($ci)\|(.+)$/) - - selectedFacets.minus(['dm', 'av', 'pr']).each { selectedFacet -> - def exp + selectedFacets - ['dm', 'av', 'pr'].each { selectedFacet -> + def exp // try { - def cnt - def facets - def selectedFacetIds - def selectedIds - Facet facet - Matcher matcher - def pattern - //def selectedFacetConfig = selectedConfigFacets.find {it.abbr == selectedFacet} - def domainFacetconfig - //create pre-compiled pattern based on the selected facet - /* Fix for AVP's */ - if(selectedFacet.startsWith('av')){ - selectedFacetIds = selectedFacet.minus('av') - selectedIds = selectedFacetsMap.get(selectedFacet).join('|') - selectedFacet = 'av' - facets = jsonFacetFields."av_FC" - pattern = Pattern.compile(/^($selectedFacetIds)\|(.+)\|($selectedIds)\|(.+)$/) + def cnt + def facets + def selectedFacetIds + def selectedIds + Facet facet + Matcher matcher + def pattern + //def selectedFacetConfig = selectedConfigFacets.find {it.abbr == selectedFacet} + def domainFacetconfig + //create pre-compiled pattern based on the selected facet + /* Fix for AVP's */ + if (selectedFacet.startsWith('av')) { + selectedFacetIds = selectedFacet - 'av' + selectedIds = selectedFacetsMap.get(selectedFacet).join('|') + selectedFacet = 'av' + facets = jsonFacetFields.'av_FC' + pattern = Pattern.compile(/^($selectedFacetIds)\|(.+)\|($selectedIds)\|(.+)$/) - } else { - domainFacetconfig = solrService.findDomainConfigFor(selectedFacet, domainConfigFacets) - facet = new Facet(type: "${selectedFacet}" - , name: domainFacetconfig?.displayName - , seq:domainFacetconfig?.sequence?: new Integer(0) - , valueBooleanOperator:domainFacetconfig?.valueBooleanOperator - , isMultiSelect:domainFacetconfig?.isMultiSelect) + } else { + domainFacetconfig = solrService.findDomainConfigFor(selectedFacet, domainConfigFacets) + facet = new Facet(type: "${selectedFacet}" + , name: domainFacetconfig?.displayName + , seq: domainFacetconfig?.sequence ?: 0 + , valueBooleanOperator: domainFacetconfig?.valueBooleanOperator + , isMultiSelect: domainFacetconfig?.isMultiSelect) - selectedIds = selectedFacetsMap.get(selectedFacet).join('|') - facets = jsonFacetFields."${selectedFacet}_FC" - if (selectedFacet == 'ci') { - pattern = Pattern.compile(/^$dm\|($ci)\|(.+)$/) - } else if (selectedFacet == 'ct1') { - pattern = Pattern.compile(/^$dm\|($ci)\|($selectedIds)\|(.+)$/) - } else if (selectedFacet == 'ct2') { - pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|($selectedIds)\|(.+)$/) - } else if (selectedFacet == 'ct3') { - pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|($ct2)\|($selectedIds)\|(.+)$/) - } else if (selectedFacet == 'ct4') { - // this isn't entirely correct because it is possible to have selected Id's that belong to other selected facet Id's - pattern = Pattern.compile(/^($selectedFacetIds)\|(.+)\|($selectedIds)\|(.+)$/) - } else if (selectedFacet == 'pn') { - pattern = Pattern.compile(/^$ci\|($pns)$/) - } else { - pattern = Pattern.compile(/^($selectedIds)\|(.+)$/) - } - } + selectedIds = selectedFacetsMap.get(selectedFacet).join('|') + facets = jsonFacetFields."${selectedFacet}_FC" + if (selectedFacet == 'ci') { + pattern = Pattern.compile(/^$dm\|($ci)\|(.+)$/) + } else if (selectedFacet == 'ct1') { + pattern = Pattern.compile(/^$dm\|($ci)\|($selectedIds)\|(.+)$/) + } else if (selectedFacet == 'ct2') { + pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|($selectedIds)\|(.+)$/) + } else if (selectedFacet == 'ct3') { + pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|($ct2)\|($selectedIds)\|(.+)$/) + } else if (selectedFacet == 'ct4') { + // this isn't entirely correct because it is possible to have selected Id's that belong to other selected facet Id's + pattern = Pattern.compile(/^($selectedFacetIds)\|(.+)\|($selectedIds)\|(.+)$/) + } else if (selectedFacet == 'pn') { + pattern = Pattern.compile(/^$ci\|($pns)$/) + } else { + pattern = Pattern.compile(/^($selectedIds)\|(.+)$/) + } + } - for(int i = 0; i < facets.length(); i=i+2){ - exp = facets[i] - cnt = facets[i+1] + for (int i = 0; i < facets.length(); i = i + 2) { + exp = facets[i] + cnt = facets[i + 1] - matcher = pattern.matcher(exp) - if(matcher.find()){ - switch(selectedFacet){ - case 'ci': - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(2), count:cnt)) - break; - case 'ct1': - facet.values.add(new Value(id:matcher.group(2), name:matcher.group(3), count:cnt)) - break; - case 'ct2': - facet.values.add(new Value(id:matcher.group(3), name:matcher.group(4), count:cnt)) - break; - case 'ct3': - facet.values.add(new Value(id:matcher.group(4), name:matcher.group(5), count:cnt)) - break; - case 'ct4': - facet.values.add(new Value(id:matcher.group(5), name:matcher.group(6), count:cnt)) - break; - case 'ci': - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(1), count:cnt)) - case 'pn': - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(1), count:cnt)) - break; - case 'av': - domainFacetconfig = solrService.findDomainConfigFor(selectedFacet, domainConfigFacets) - String key = "${selectedFacet}${matcher.group(1)}" - facet = avMap.get(key) - if (!facet) { - facet = new Facet(type: key - , name: matcher.group(2) - , seq:domainFacetconfig?.sequence - , valueBooleanOperator:domainFacetconfig?.valueBooleanOperator - , isMultiSelect:domainFacetconfig?.isMultiSelect) - avMap.put(key, facet) - } - facet.values.add(new Value(id:matcher.group(3), name:matcher.group(4), count:cnt)) - break; - default: - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(2), count:cnt)) - } - } - } - if (facet) { - retFeatures.add(facet) - } + matcher = pattern.matcher(exp) + if (matcher.find()) { + switch (selectedFacet) { + case 'ci': + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(2), count: cnt)) + break + case 'ct1': + facet.values.add(new Value(id: matcher.group(2), name: matcher.group(3), count: cnt)) + break + case 'ct2': + facet.values.add(new Value(id: matcher.group(3), name: matcher.group(4), count: cnt)) + break + case 'ct3': + facet.values.add(new Value(id: matcher.group(4), name: matcher.group(5), count: cnt)) + break + case 'ct4': + facet.values.add(new Value(id: matcher.group(5), name: matcher.group(6), count: cnt)) + break + case 'ci': + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(1), count: cnt)) + case 'pn': + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(1), count: cnt)) + break + case 'av': + domainFacetconfig = solrService.findDomainConfigFor(selectedFacet, domainConfigFacets) + String key = "${selectedFacet}${matcher.group(1)}" + facet = avMap.get(key) + if (!facet) { + facet = new Facet(type: key + , name: matcher.group(2) + , seq: domainFacetconfig?.sequence + , valueBooleanOperator: domainFacetconfig?.valueBooleanOperator + , isMultiSelect: domainFacetconfig?.isMultiSelect) + avMap.put(key, facet) + } + facet.values.add(new Value(id: matcher.group(3), name: matcher.group(4), count: cnt)) + break + default: + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(2), count: cnt)) + } + } + } + if (facet) { + retFeatures.add(facet) + } // } catch (Exception exception){ // log.error "Exception while processing the header " + exception // exception.printStackTrace() -// throw new SearchException(exception, "Exception while processing selected header for facet ${selectedFacet} with value ${exp}") +// throw new SearchException(exception, "Exception while processing selected header for facet ${selectedFacet} with value +// ${exp}") // } - //sort the selected facets - retFeatures.sort{it.seq} + //sort the selected facets + retFeatures.sort { it.seq } - } - //nullify temp map to track avp facets - avMap = null - return retFeatures - } + } + //nullify temp map to track avp facets + avMap = null + retFeatures + } - List populateNextFacets(params, selectedFacetsMap, nextFacets, solrJson, domainConfigFacets){ + List populateNextFacets(params, selectedFacetsMap, nextFacets, solrJson, domainConfigFacets) { - //[av, ci, ct, mk, yr] - def retFeatures = [] - def avMap = [:] - def jsonFacetFields = solrJson.facet_counts.facet_fields + //[av, ci, ct, mk, yr] + def retFeatures = [] + def avMap = [:] + def jsonFacetFields = solrJson.facet_counts.facet_fields - def dm = params.dm ? params.dm : '\\d*' - def ci = selectedFacetsMap.get('ci') ? selectedFacetsMap.get('ci').join('|') : '\\d*' - def ct1 = selectedFacetsMap.get('ct1') ? selectedFacetsMap.get('ct1').join('|') : '\\d*' - def ct2 = selectedFacetsMap.get('ct2') ? selectedFacetsMap.get('ct2').join('|') : '\\d*' - def ct3 = selectedFacetsMap.get('ct3') ? selectedFacetsMap.get('ct3').join('|') : '\\d*' - def yrs = selectedFacetsMap.get('yr') ? selectedFacetsMap.get('yr').join('|') : null - def mds = selectedFacetsMap.get('md') ? selectedFacetsMap.get('md').join('|') : null - def mks = selectedFacetsMap.get('mk') ? selectedFacetsMap.get('mk').join('|') : null - def pr = params.pr ? params.pr : null - def domainFacetconfig - def exp - nextFacets.each { nextFacet -> - def nextFacetAbbr = nextFacet.abbr - try { - def cnt - def facets - def selectedIds - Pattern pattern + def dm = params.dm ? params.dm : '\\d*' + def ci = selectedFacetsMap.get('ci') ? selectedFacetsMap.get('ci').join('|') : '\\d*' + def ct1 = selectedFacetsMap.get('ct1') ? selectedFacetsMap.get('ct1').join('|') : '\\d*' + def ct2 = selectedFacetsMap.get('ct2') ? selectedFacetsMap.get('ct2').join('|') : '\\d*' + def ct3 = selectedFacetsMap.get('ct3') ? selectedFacetsMap.get('ct3').join('|') : '\\d*' + def yrs = selectedFacetsMap.get('yr') ? selectedFacetsMap.get('yr').join('|') : null + def mds = selectedFacetsMap.get('md') ? selectedFacetsMap.get('md').join('|') : null + def mks = selectedFacetsMap.get('mk') ? selectedFacetsMap.get('mk').join('|') : null + def domainFacetconfig + def exp + nextFacets.each { nextFacet -> + def nextFacetAbbr = nextFacet.abbr + try { + def cnt + def facets + Pattern pattern - if (nextFacetAbbr == 'ct') { - if (selectedFacetsMap.get('ct3')) { - facets = jsonFacetFields."ct4_FC" - pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|($ct2)\|($ct3)\|(\d+)\|(.+)$/) - nextFacetAbbr = 'ct4' - } else if (selectedFacetsMap.get('ct2')) { - facets = jsonFacetFields."ct3_FC" - pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|($ct2)\|(\d+)\|(.+)$/) - nextFacetAbbr = 'ct3' - } else if (selectedFacetsMap.get('ct1')) { - facets = jsonFacetFields."ct2_FC" - pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|(\d+)\|(.+)$/) - nextFacetAbbr = 'ct2' - } else if (selectedFacetsMap.get('ci')) { - facets = jsonFacetFields."ct1_FC" - pattern = Pattern.compile(/^$dm\|($ci)\|(\d+)\|(.+)$/) - nextFacetAbbr = 'ct1' - } - } else if (nextFacetAbbr == 'mk') { - if (mds && yrs) { - facets = jsonFacetFields."mk_yr_md_FC" - pattern = Pattern.compile(/^(\d+)\|(.+)\|($yrs)\|($mds)\|(.+)$/) - } else if (yrs) { - facets = jsonFacetFields."yr_mk_FC" - pattern = Pattern.compile(/^($yrs)\|(\d+)\|(.+)$/) - } else { - facets = jsonFacetFields."mk_FC" - pattern = Pattern.compile(/^(\d*)\|(.*)$/) - } - } else if (nextFacetAbbr == 'yr') { - if (mks && mds) { - facets = jsonFacetFields."mk_yr_md_FC" - pattern = Pattern.compile(/^($mks)\|(.+)\|(\d+)\|($mds)\|(.+)$/) - } else if (mks) { - facets = jsonFacetFields."mk_yr_FC" - pattern = Pattern.compile(/^($mks)\|(\d+)\|(.+)$/) - } else { - facets = jsonFacetFields."yr_FC" - pattern = Pattern.compile(/^(\d*)\|(.*)$/) - } - } else if (nextFacetAbbr == 'md') { - if (mks && yrs) { - facets = jsonFacetFields."mk_yr_md_FC" - pattern = Pattern.compile(/^($mks)\|(.+)\|($yrs)\|(\d+)\|(.+)$/) - } else if (mks) { - facets = jsonFacetFields."mk_md_FC" - pattern = Pattern.compile(/^($mks)\|(\d+)\|(.+)$/) - } else if (yrs) { - facets = jsonFacetFields."yr_md_FC" - pattern = Pattern.compile(/^($yrs)\|(\d+)\|(.+)$/) - } else { - facets = jsonFacetFields."md_FC" - pattern = Pattern.compile(/^(\d*)\|(.*)$/) - } - } else if(nextFacetAbbr == 'pn'){ - facets = jsonFacetFields."${nextFacetAbbr}_FC" - pattern = Pattern.compile(/^$ci\|(.+)$/) - } else { - facets = jsonFacetFields."${nextFacetAbbr}_FC" - if (nextFacetAbbr == 'ci') { - pattern = Pattern.compile(/^$dm\|(\d+)\|(.+)$/) - } else if (nextFacetAbbr == 'av') { - pattern = Pattern.compile(/^(\d+)\|(.+)\|(\d+)\|(.+)$/) - } else { - pattern = Pattern.compile(/^([A-Za-z0-9-]*)\|(.*)$/) - } - } - domainFacetconfig = solrService.findDomainConfigFor(nextFacetAbbr, domainConfigFacets) + if (nextFacetAbbr == 'ct') { + if (selectedFacetsMap.get('ct3')) { + facets = jsonFacetFields.'ct4_FC' + pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|($ct2)\|($ct3)\|(\d+)\|(.+)$/) + nextFacetAbbr = 'ct4' + } else if (selectedFacetsMap.get('ct2')) { + facets = jsonFacetFields.'ct3_FC' + pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|($ct2)\|(\d+)\|(.+)$/) + nextFacetAbbr = 'ct3' + } else if (selectedFacetsMap.get('ct1')) { + facets = jsonFacetFields.'ct2_FC' + pattern = Pattern.compile(/^$dm\|($ci)\|($ct1)\|(\d+)\|(.+)$/) + nextFacetAbbr = 'ct2' + } else if (selectedFacetsMap.get('ci')) { + facets = jsonFacetFields.'ct1_FC' + pattern = Pattern.compile(/^$dm\|($ci)\|(\d+)\|(.+)$/) + nextFacetAbbr = 'ct1' + } + } else if (nextFacetAbbr == 'mk') { + if (mds && yrs) { + facets = jsonFacetFields.'mk_yr_md_FC' + pattern = Pattern.compile(/^(\d+)\|(.+)\|($yrs)\|($mds)\|(.+)$/) + } else if (yrs) { + facets = jsonFacetFields.'yr_mk_FC' + pattern = Pattern.compile(/^($yrs)\|(\d+)\|(.+)$/) + } else { + facets = jsonFacetFields.'mk_FC' + pattern = Pattern.compile(/^(\d*)\|(.*)$/) + } + } else if (nextFacetAbbr == 'yr') { + if (mks && mds) { + facets = jsonFacetFields.'mk_yr_md_FC' + pattern = Pattern.compile(/^($mks)\|(.+)\|(\d+)\|($mds)\|(.+)$/) + } else if (mks) { + facets = jsonFacetFields.'mk_yr_FC' + pattern = Pattern.compile(/^($mks)\|(\d+)\|(.+)$/) + } else { + facets = jsonFacetFields.'yr_FC' + pattern = Pattern.compile(/^(\d*)\|(.*)$/) + } + } else if (nextFacetAbbr == 'md') { + if (mks && yrs) { + facets = jsonFacetFields.'mk_yr_md_FC' + pattern = Pattern.compile(/^($mks)\|(.+)\|($yrs)\|(\d+)\|(.+)$/) + } else if (mks) { + facets = jsonFacetFields.'mk_md_FC' + pattern = Pattern.compile(/^($mks)\|(\d+)\|(.+)$/) + } else if (yrs) { + facets = jsonFacetFields.'yr_md_FC' + pattern = Pattern.compile(/^($yrs)\|(\d+)\|(.+)$/) + } else { + facets = jsonFacetFields.'md_FC' + pattern = Pattern.compile(/^(\d*)\|(.*)$/) + } + } else if (nextFacetAbbr == 'pn') { + facets = jsonFacetFields."${nextFacetAbbr}_FC" + pattern = Pattern.compile(/^$ci\|(.+)$/) + } else { + facets = jsonFacetFields."${nextFacetAbbr}_FC" + if (nextFacetAbbr == 'ci') { + pattern = Pattern.compile(/^$dm\|(\d+)\|(.+)$/) + } else if (nextFacetAbbr == 'av') { + pattern = Pattern.compile(/^(\d+)\|(.+)\|(\d+)\|(.+)$/) + } else { + pattern = Pattern.compile(/^([A-Za-z0-9-]*)\|(.*)$/) + } + } + domainFacetconfig = solrService.findDomainConfigFor(nextFacetAbbr, domainConfigFacets) - Facet facet = new Facet(type: nextFacetAbbr - , name: domainFacetconfig?.displayName - , seq:domainFacetconfig?.sequence?: new Integer(0) - , resultSortOrder:domainFacetconfig?.resultSortOrder - , resultListCount:domainFacetconfig?.resultListCount - , valueBooleanOperator:domainFacetconfig?.valueBooleanOperator - , isMultiSelect:domainFacetconfig?.isMultiSelect ) + Facet facet = new Facet(type: nextFacetAbbr + , name: domainFacetconfig?.displayName + , seq: domainFacetconfig?.sequence ?: 0 + , resultSortOrder: domainFacetconfig?.resultSortOrder + , resultListCount: domainFacetconfig?.resultListCount + , valueBooleanOperator: domainFacetconfig?.valueBooleanOperator + , isMultiSelect: domainFacetconfig?.isMultiSelect) - Matcher matcher - def ftMap = [:] - //for some reason invalid combination is entered .eg. ct2 without ct1 - if(facets) { - for(int i = 0; i < facets.length(); i=i+2){ - exp = facets[i] - cnt = facets[i+1] - matcher = pattern.matcher(exp) - if(matcher.find()) { - switch(nextFacetAbbr){ - case 'ci': - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(2), count:cnt)) - break; - case 'ct1': - facet.values.add(new Value(id:matcher.group(2), name:matcher.group(3), count:cnt)) - break; - case 'ct2': - facet.values.add(new Value(id:matcher.group(3), name:matcher.group(4), count:cnt)) - break; - case 'ct3': - facet.values.add(new Value(id:matcher.group(4), name:matcher.group(5), count:cnt)) - break; - case 'ct4': - facet.values.add(new Value(id:matcher.group(5), name:matcher.group(6), count:cnt)) - break; - case 'pn': - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(1), count:cnt)) - break; - case 'av': - String key = "av${matcher.group(1)}" - facet = avMap.get(key) - if (!facet) { - domainFacetconfig = solrService.findDomainConfigFor(nextFacetAbbr, domainConfigFacets) - facet = new Facet(type: key, name: matcher.group(2) - , seq:domainFacetconfig.sequence - , resultSortOrder:domainFacetconfig.resultSortOrder - , resultListCount:domainFacetconfig.resultListCount - , valueBooleanOperator:domainFacetconfig?.valueBooleanOperator - , isMultiSelect:domainFacetconfig?.isMultiSelect) - avMap.put(key, facet) - } - facet.values.add(new Value(id:matcher.group(3), name:matcher.group(4), count:cnt)) - break; - case 'mk': - if (mds && yrs) { - String key = matcher.group(1) + '|' + matcher.group(2) - def existingCount = ftMap.get(key) - if (!existingCount) { - ftMap.put(key, cnt) - } else { - ftMap.put(key, existingCount + cnt) - } - } else if (yrs) { - //avoid duplicate makes for multiple years - if(!facet.values.find{it.id == matcher.group(2)}) { - facet.values.add(new Value(id:matcher.group(2), name:matcher.group(3), count:cnt)) - } - } else { - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(2), count:cnt)) - } - break; - case 'yr': - if (mks && mds) { - String key = matcher.group(3) + '|' + matcher.group(3) - def existingCount = ftMap.get(key) - if (!existingCount) { - ftMap.put(key, cnt) - } else { - ftMap.put(key, existingCount + cnt) - } - } else if (mks) { - if(!facet.values.find{it.id == matcher.group(2)}) { - facet.values.add(new Value(id:matcher.group(2), name:matcher.group(3), count:cnt)) - } - } else { - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(2), count:cnt)) - } - break; - case 'md': - if (mks && yrs) { - String key = matcher.group(4) + '|' + matcher.group(5) - def existingCount = ftMap.get(key) - if (!existingCount) { - ftMap.put(key, cnt) - } else { - ftMap.put(key, existingCount + cnt) - } - } else if (mks) { - if(!facet.values.find{it.id == matcher.group(2)}) { - facet.values.add(new Value(id:matcher.group(2), name:matcher.group(3), count:cnt)) - } - } else if (yrs) { - if(!facet.values.find{it.id == matcher.group(2)}) { - facet.values.add(new Value(id:matcher.group(2), name:matcher.group(3), count:cnt)) - } - } else { - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(2), count:cnt)) - } - break - default: - matcher = pattern.matcher(exp) - if(matcher.find()){ - facet.values.add(new Value(id:matcher.group(1), name:matcher.group(2), count:cnt)) - } - } - } - } - } + Matcher matcher + def ftMap = [:] + //for some reason invalid combination is entered .eg. ct2 without ct1 + if (facets) { + for (int i = 0; i < facets.length(); i = i + 2) { + exp = facets[i] + cnt = facets[i + 1] + matcher = pattern.matcher(exp) + if (matcher.find()) { + switch (nextFacetAbbr) { + case 'ci': + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(2), count: cnt)) + break + case 'ct1': + facet.values.add(new Value(id: matcher.group(2), name: matcher.group(3), count: cnt)) + break + case 'ct2': + facet.values.add(new Value(id: matcher.group(3), name: matcher.group(4), count: cnt)) + break + case 'ct3': + facet.values.add(new Value(id: matcher.group(4), name: matcher.group(5), count: cnt)) + break + case 'ct4': + facet.values.add(new Value(id: matcher.group(5), name: matcher.group(6), count: cnt)) + break + case 'pn': + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(1), count: cnt)) + break + case 'av': + String key = "av${matcher.group(1)}" + facet = avMap.get(key) + if (!facet) { + domainFacetconfig = solrService.findDomainConfigFor(nextFacetAbbr, domainConfigFacets) + facet = new Facet(type: key, name: matcher.group(2) + , seq: domainFacetconfig.sequence + , resultSortOrder: domainFacetconfig.resultSortOrder + , resultListCount: domainFacetconfig.resultListCount + , valueBooleanOperator: domainFacetconfig?.valueBooleanOperator + , isMultiSelect: domainFacetconfig?.isMultiSelect) + avMap.put(key, facet) + } + facet.values.add(new Value(id: matcher.group(3), name: matcher.group(4), count: cnt)) + break + case 'mk': + if (mds && yrs) { + String key = matcher.group(1) + '|' + matcher.group(2) + def existingCount = ftMap.get(key) + if (existingCount) { + ftMap.put(key, existingCount + cnt) + } else { + ftMap.put(key, cnt) + } + } else if (yrs) { + //avoid duplicate makes for multiple years + if (!facet.values.find { it.id == matcher.group(2) }) { + facet.values.add(new Value(id: matcher.group(2), name: matcher.group(3), count: cnt)) + } + } else { + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(2), count: cnt)) + } + break + case 'yr': + if (mks && mds) { + String key = matcher.group(3) + '|' + matcher.group(3) + def existingCount = ftMap.get(key) + if (existingCount) { + ftMap.put(key, existingCount + cnt) + } else { + ftMap.put(key, cnt) + } + } else if (mks) { + if (!facet.values.find { it.id == matcher.group(2) }) { + facet.values.add(new Value(id: matcher.group(2), name: matcher.group(3), count: cnt)) + } + } else { + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(2), count: cnt)) + } + break + case 'md': + if (mks && yrs) { + String key = matcher.group(4) + '|' + matcher.group(5) + def existingCount = ftMap.get(key) + if (existingCount) { + ftMap.put(key, existingCount + cnt) + } else { + ftMap.put(key, cnt) + } + } else if (mks) { + if (!facet.values.find { it.id == matcher.group(2) }) { + facet.values.add(new Value(id: matcher.group(2), name: matcher.group(3), count: cnt)) + } + } else if (yrs) { + if (!facet.values.find { it.id == matcher.group(2) }) { + facet.values.add(new Value(id: matcher.group(2), name: matcher.group(3), count: cnt)) + } + } else { + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(2), count: cnt)) + } + break + default: + matcher = pattern.matcher(exp) + if (matcher.find()) { + facet.values.add(new Value(id: matcher.group(1), name: matcher.group(2), count: cnt)) + } + } + } + } + } - ftMap.each {it-> - String key = it.key - def values = key.split("\\|") - facet.values.add(new Value(id:values[0], name:values[1], count:it.value)) - } - if (facet && nextFacetAbbr != 'av') { - retFeatures.add(facet) - } - } catch(Exception exception){ - log.error "Exception while processing next facet" + exception - throw new SearchException(exception, "Exception while processing next facet: ${nextFacetAbbr} with value: ${exp}") - } - } + ftMap.each { it -> + String key = it.key + def values = key.split('\\|') + facet.values.add(new Value(id: values[0], name: values[1], count: it.value)) + } + if (facet && nextFacetAbbr != 'av') { + retFeatures.add(facet) + } + } catch (Exception exception) { + log.error 'Exception while processing next facet' + exception + throw new SearchException(exception, "Exception while processing next facet: ${nextFacetAbbr} with value: ${exp}") + } + } - //add av facet to the facet list - def avpList = avMap.values() as List - def avFacetConfig = domainConfigFacets.find {it.abbr == 'av'} - if(avFacetConfig) { - def attrSortOrderConfig = avFacetConfig.resultSortOrder.split('\\+') - avpList.sort{it."${attrSortOrderConfig[0]}"} - if (attrSortOrderConfig[1] == 'desc'){ - Collections.reverse(avpList) - } - } - retFeatures.addAll(avpList) + //add av facet to the facet list + def avpList = avMap.values() as List + def avFacetConfig = domainConfigFacets.find { it.abbr == 'av' } + if (avFacetConfig) { + def attrSortOrderConfig = avFacetConfig.resultSortOrder.split('\\+') + avpList.sort { it."${attrSortOrderConfig[0]}" } + if (attrSortOrderConfig[1] == 'desc') { + Collections.reverse(avpList) + } + } + retFeatures.addAll(avpList) - //TODO: 80% Rule, filter selected facets and remove empty facets - //filter the facets - int partCount = solrJson.response.numFound as int - filterFacets(retFeatures, partCount, selectedFacetsMap) + //TODO: 80% Rule, filter selected facets and remove empty facets + //filter the facets + int partCount = solrJson.response.numFound as int + filterFacets(retFeatures, partCount, selectedFacetsMap) + //sort the items in the facets + retFeatures.each { retFeature -> + if (retFeature?.resultSortOrder) { + def sortOrderConfig = retFeature.resultSortOrder.split('\\+') + retFeature.values.sort { it."${sortOrderConfig[0]}" } + if (sortOrderConfig[1] == 'desc') { + Collections.reverse(retFeature.values) + } + } + } + //sort the facets itself. + retFeatures.sort { it.seq } + retFeatures + } - //sort the items in the facets - retFeatures.each {retFeature-> - if(retFeature?.resultSortOrder) { - def sortOrderConfig = retFeature.resultSortOrder.split('\\+') - retFeature.values.sort{it."${sortOrderConfig[0]}"} - if (sortOrderConfig[1] == 'desc'){ - Collections.reverse(retFeature.values) - } - } - } - //sort the facets itself. - retFeatures.sort{it.seq} + /** + * Process catalog hitlist xml document + * @param histlistDoc + * @return + */ + List processCatalogResponse(histlistDoc) { + def catalogs = [] + histlistDoc.catalogs.catalog.each { doc -> + Catalog catalog = new Catalog() + catalog.id = doc.catalogInstanceId.text() as int + catalog.instanceName = doc.instanceName.text() + catalog.mediaUrl = doc.mediaUrl.text() + catalog.prefixUrl = doc.prefixUrl.text() + catalog.extension = doc.extension.text() + catalogs.add(catalog) + } + catalogs + } - return retFeatures - } + /** + * Process category hitlist xml document + * @param histlistDoc + * @return + */ + List processCategoryResponse(histlistDoc) { + def categories = [] + histlistDoc.categories.category.each { doc -> + Category category = new Category() + category.id = doc.categoryId.text() as int + category.categoryName = doc.categoryName.text() + category.mediaUrl = doc.mediaUrl.text() + category.prefixUrl = doc.prefixUrl.text() + category.extension = doc.extension.text() - /** - * Process catalog hitlist xml document - * @param histlistDoc - * @return - */ - List processCatalogResponse(histlistDoc){ - def catalogs = [] - histlistDoc.catalogs.catalog.each { doc-> - Catalog catalog = new Catalog() - catalog.id = doc.catalogInstanceId.text() as int - catalog.instanceName = doc.instanceName.text() - catalog.mediaUrl = doc.mediaUrl.text() - catalog.prefixUrl = doc.prefixUrl.text() - catalog.extension = doc.extension.text() - catalogs.add(catalog) - } - return catalogs - } + categories.add(category) + } + categories + } - /** - * Process category hitlist xml document - * @param histlistDoc - * @return - */ - List processCategoryResponse(histlistDoc){ - def categories = [] - histlistDoc.categories.category.each { doc-> - Category category = new Category() - category.id = doc.categoryId.text() as int - category.categoryName = doc.categoryName.text() - category.mediaUrl = doc.mediaUrl.text() - category.prefixUrl = doc.prefixUrl.text() - category.extension = doc.extension.text() + /** + * Process the part response. + * @param partsJson + * @return + */ + List processPartResponse(partsJson) { + def parts = [] + partsJson.response.docs.each { doc -> - categories.add(category) - } - return categories - } + Part part = new Part() + part.with { + id = doc.partNumber + partNumber = doc.partNumber + punctuatedPartNumber = doc.punctuatedPartNumber + partDescr = doc.partDescr + subComCodeId = doc.subComCodeId + subComCode = doc.subComCode + subComCodeDescr = doc.subComCodeDescr + subComCodeAlias = doc.subComCodeAlias + subComCodeAlias = doc.subComCodeAlias + brandId = doc.brandId + brandCode = doc.brandCode + brandName = doc.brandName + brandMediaUrl = doc.brandMediaUrl + brandPrefixUrl = doc.brandPrefixUrl + brandExtension = doc.brandExtension + vendorPartNumber = doc.vendorPartNumber + vendorPunctuatedPartNumber = doc.vendorPunctuatedPartNumber + } + doc.oemPartNumber?.collect { oemPN -> + part.oemPartNumbers.add(oemPN) + } + doc.oemPunctuatedPartNumber?.collect { oemPPN -> + part.oemPunctuatedPartNumbers.add(oemPPN) + } + doc.xrefPartNumber?.collect { xrefPN -> + part.xRefPartNumbers.add(xrefPN) + } + doc.xrefPunctuatedPartNumber?.collect { xrefPPN -> + part.xRefPunctuatedPartNumbers.add(xrefPPN) + } + part.with { + uom = doc.uom + retailPrice = new Double((doc.retailPrice)) + warehouseCountry = doc.warehouseCountry + partStatus = doc.partStatus + mediaUrl = doc.mediaUrl + prefixUrl = doc.prefixUrl + extension = doc.extension + } + parts.add(part) + } + parts + } - /** - * Process the part response. - * @param partsJson - * @return - */ - List processPartResponse(partsJson){ - def parts = [] - partsJson.response.docs.each { doc-> + /** + * Process the product response. + * @param productResponse + * @return + */ + List processProductResponse(prodJson) { - Part part = new Part() - part.id = doc.partNumber - part.partNumber = doc.partNumber - part.punctuatedPartNumber = doc.punctuatedPartNumber - part.partDescr = doc.partDescr - part.subComCodeId = doc.subComCodeId - part.subComCode = doc.subComCode - part.subComCodeDescr = doc.subComCodeDescr - part.subComCodeAlias = doc.subComCodeAlias - part.subComCodeAlias = doc.subComCodeAlias - part.brandId = doc.brandId - part.brandCode = doc.brandCode - part.brandName = doc.brandName - part.brandMediaUrl = doc.brandMediaUrl - part.brandPrefixUrl = doc.brandPrefixUrl - part.brandExtension = doc.brandExtension - part.vendorPartNumber = doc.vendorPartNumber - part.vendorPunctuatedPartNumber = doc.vendorPunctuatedPartNumber - doc.oemPartNumber?.collect {oemPN -> - part.oemPartNumbers.add(oemPN) - } - doc.oemPunctuatedPartNumber?.collect {oemPPN -> - part.oemPunctuatedPartNumbers.add(oemPPN) - } - doc.xrefPartNumber?.collect {xrefPN -> - part.xRefPartNumbers.add(xrefPN) - } - doc.xrefPunctuatedPartNumber?.collect {xrefPPN -> - part.xRefPunctuatedPartNumbers.add(xrefPPN) - } - part.uom = doc.uom - part.retailPrice = new Double((doc.retailPrice)) - part.warehouseCountry = doc.warehouseCountry - part.partStatus = doc.partStatus - part.mediaUrl = doc.mediaUrl - part.prefixUrl = doc.prefixUrl - part.extension = doc.extension + def products = [] + prodJson.response.docs.each { doc -> + Product product = new Product() + product.with { + id = doc.productId as int + catalogInstanceId = doc.catalogInstanceId as int + catalogInstanceName = doc.catalogInstanceName + pageNumber = doc.pageNumber as int + sequence = doc.sequence as int + description = doc.description + } + if (doc.brandId != '') { + product.brandId = doc.brandId as int + } + product.with { + brandName = doc.brandName + brandCode = doc.brandCode + caption = doc.caption + productName = doc.productName + mediaUrl = doc.mediaUrl + prefixUrl = doc.prefixUrl + extension = doc.extension + brandMediaUrl = doc.brandMediaUrl + brandPrefixUrl = doc.brandPrefixUrl + brandExtension = doc.brandExtension + baseDealerPriceLow = doc.baseDealerPriceLow as double + baseDealerPriceHigh = doc.baseDealerPriceHigh as double + retailPriceLow = doc.retailPriceLow as double + retailPriceHigh = doc.retailPriceHigh as double + retailPriceDisplayRange = doc.retailPriceDisplayRange + banner = doc.banner + partCount = doc.partCount as int + faqCount = doc.faqCount as int + tag = doc.tag + } - parts.add(part) - } - return parts - } + //Splits ct1, ct2, ct3 and ct4 records by pipe symbol to get categoryId and Name for 4 category level + for (int i = 1; i <= 4; i++) { + String[] categoryRecord = doc."ct$i".split('\\|') + if (categoryRecord.size() == 2) { + product."ct${i}Id" = categoryRecord[0] + product."ct${i}Name" = categoryRecord[1] + } + } - /** - * Process the product response. - * @param productResponse - * @return - */ - List processProductResponse(prodJson){ + doc.uniqueId.eachWithIndex { uniqueId, index -> + MediaGroup mg = new MediaGroup() + mg.with { + uniqueId = doc.uniqueId[index] + attributeName1 = doc.attributeName1[index] + attributeValue1 = doc.attributeValue1[index] + attributeName2 = doc.attributeName2[index] + attributeValue2 = doc.attributeValue2[index] + attributeName3 = doc.attributeName3[index] + attributeValue3 = doc.attributeValue3[index] + mediaGroupViewingAngleId = doc.mediaGroupViewingAngleId[index] + mediaGroupPrefixUrl = doc.mediaGroupPrefixUrl[index] + mediaGroupMediaUrl = doc.mediaGroupMediaUrl[index] + mediaGroupExtension = doc.mediaGroupExtension[index] + } + product.mediaGroups.add(mg) + } - def products = [] - prodJson.response.docs.each { doc-> - Product product = new Product() + doc.productGroupId.eachWithIndex { productGroupId, index -> + ProductGroup pg = new ProductGroup() + pg.with { + productGroupId = doc.productGroupId[index] + productGroupName = doc.productGroupName[index] + productGroupPrefixUrl = doc.productGroupPrefixUrl[index] + productGroupMediaUrl = doc.productGroupMediaUrl[index] + productGroupExtension = doc.productGroupExtension[index] + productGroupSequence = doc.productGroupSequence[index] + } + product.productGroups.add(pg) + } - product.id = doc.productId as int - product.catalogInstanceId = doc.catalogInstanceId as int - product.catalogInstanceName = doc.catalogInstanceName - product.pageNumber = doc.pageNumber as int - product.sequence = doc.sequence as int + def isSub = false + def bulletKey = '' + def subBullets + Feature feature + doc.featureSequence.eachWithIndex { featureSequence, index -> - product.description = doc.description - if(doc.brandId !=''){ - product.brandId = doc.brandId as int - } + def featureType = doc.featureType[index] + def featureText = doc.feature.get(index) - product.brandName = doc.brandName - product.brandCode = doc.brandCode - product.caption = doc.caption - product.productName = doc.productName - product.mediaUrl = doc.mediaUrl - product.prefixUrl = doc.prefixUrl - product.extension = doc.extension - product.brandMediaUrl = doc.brandMediaUrl - product.brandPrefixUrl = doc.brandPrefixUrl - product.brandExtension = doc.brandExtension - product.baseDealerPriceLow = doc.baseDealerPriceLow as double - product.baseDealerPriceHigh = doc.baseDealerPriceHigh as double - product.retailPriceLow = doc.retailPriceLow as double - product.retailPriceHigh = doc.retailPriceHigh as double - product.retailPriceDisplayRange = doc.retailPriceDisplayRange - product.banner = doc.banner - product.partCount = doc.partCount as int + switch (featureType?.toUpperCase()) { + case 'SUB': + isSub = true + bulletKey = featureText as String + subBullets = [] + feature = new Feature(text: featureText, type: featureType) + product.features.add(feature) + break + case 'BULLET': + if (isSub) { + def subBullet = new SubBullet(text: featureText, type: featureType) + subBullets.add(subBullet) + feature.subBullets = subBullets + } else { + feature = new Feature(text: featureText, type: featureType) + product.features.add(feature) + } + break + case 'NOTE': + isSub = false + feature = new Feature(text: featureText, type: featureType) + product.features.add(feature) + break + } + } + products.add(product) + } + products + } - product.faqCount=doc.faqCount as int - product.tag=doc.tag - //Splits ct1, ct2, ct3 and ct4 records by pipe symbol to get categoryId and Name for 4 category level - for(int i=1;i<=4;i++){ - String[] categoryRecord =doc."ct$i".split("\\|") - if(categoryRecord.size()==2){ - product."ct${i}Id"=categoryRecord[0] - product."ct${i}Name"=categoryRecord[1] - } - } + /** + * Process the product response. + * @param productResponse + * @return + */ + List processProductGroupResponse(prodGroupJson) { - doc.uniqueId.eachWithIndex {uniqueId, index -> - MediaGroup mg = new MediaGroup() - mg.uniqueId = doc.uniqueId.getAt(index ) - mg.attributeName1 = doc.attributeName1.getAt(index ) - mg.attributeValue1 = doc.attributeValue1.getAt(index ) - mg.attributeName2 = doc.attributeName2.getAt(index ) - mg.attributeValue2 = doc.attributeValue2.getAt(index ) - mg.attributeName3 = doc.attributeName3.getAt(index ) - mg.attributeValue3 = doc.attributeValue3.getAt(index ) - mg.mediaGroupViewingAngleId = doc.mediaGroupViewingAngleId.getAt(index ) - mg.mediaGroupPrefixUrl = doc.mediaGroupPrefixUrl.getAt(index ) - mg.mediaGroupMediaUrl = doc.mediaGroupMediaUrl.getAt(index ) - mg.mediaGroupExtension = doc.mediaGroupExtension.getAt(index ) + def productGroups = [] + prodGroupJson.response.docs.each { doc -> + ProductGroupNew productGroup = new ProductGroupNew() + productGroup.with { + id = doc.productGroupId as int + catalogInstanceId = doc.catalogInstanceId as int + catalogInstanceName = doc.catalogInstanceName + pageNumber = doc.pageNumber as int + sequence = doc.sequence as int + description = doc.description + } + if (doc.brandId != '') { + productGroup.brandId = doc.brandId as int + } - product.mediaGroups.add(mg) - } + productGroup.with { + brandName = doc.brandName + brandCode = doc.brandCode + caption = doc.caption + productName = doc.productName + productGroupName = doc.productGroupName + productId = doc.productId as int + mediaUrl = doc.mediaUrl + prefixUrl = doc.prefixUrl + extension = doc.extension + brandMediaUrl = doc.brandMediaUrl + brandPrefixUrl = doc.brandPrefixUrl + brandExtension = doc.brandExtension + baseDealerPriceLow = doc.baseDealerPriceLow as double + baseDealerPriceHigh = doc.baseDealerPriceHigh as double + retailPriceLow = doc.retailPriceLow as double + retailPriceHigh = doc.retailPriceHigh as double + retailPriceDisplayRange = doc.retailPriceDisplayRange + partCount = doc.partCount as int + faqCount = doc.faqCount as int + tag = doc.tag + } - doc.productGroupId.eachWithIndex {productGroupId, index -> - ProductGroup pg = new ProductGroup() - pg.productGroupId = doc.productGroupId.getAt(index ) - pg.productGroupName = doc.productGroupName.getAt(index ) - pg.productGroupPrefixUrl = doc.productGroupPrefixUrl.getAt(index ) - pg.productGroupMediaUrl = doc.productGroupMediaUrl.getAt(index ) - pg.productGroupExtension = doc.productGroupExtension.getAt(index ) - pg.productGroupSequence = doc.productGroupSequence.getAt(index ) + //Splits ct1, ct2, ct3 and ct4 records by pipe symbol to get categoryId and Name for 4 category level + for (int i = 1; i <= 4; i++) { + String[] categoryRecord = doc."ct$i".split('\\|') + if (categoryRecord.size() == 2) { + productGroup."ct${i}Id" = categoryRecord[0] + productGroup."ct${i}Name" = categoryRecord[1] + } + } + def isSub = false + def bulletKey = '' + def subBullets + Feature feature + doc.featureSequence.eachWithIndex { featureSequence, index -> - product.productGroups.add(pg) - } + def featureType = doc.featureType[index] + def featureText = doc.feature.get(index) - def isSub = false - def bulletKey ='' - def subBullets - Feature feature - doc.featureSequence.eachWithIndex{ featureSequence, index -> + switch (featureType?.toUpperCase()) { + case 'SUB': + isSub = true + bulletKey = featureText as String + subBullets = [] + feature = new Feature(text: featureText, type: featureType) + productGroup.features.add(feature) + break + case 'BULLET': + if (isSub) { + def subBullet = new SubBullet(text: featureText, type: featureType) + subBullets.add(subBullet) + feature.subBullets = subBullets + } else { + feature = new Feature(text: featureText, type: featureType) + productGroup.features.add(feature) + } + break + case 'NOTE': + isSub = false + feature = new Feature(text: featureText, type: featureType) + productGroup.features.add(feature) + break + } + } + productGroups.add(productGroup) + } + productGroups + } - def featureType = doc.featureType.getAt(index ) - def featureText = doc.feature.get(index) + /** + * Iterate through facets + * - set the total count on facet + * - remove the facet if not applicable. + * @param facets + * @param partCount + */ + void filterFacets(facets, partCount, selectedFacetsMap) { - switch(featureType?.toUpperCase()){ - case 'SUB': - isSub = true - bulletKey = featureText as String - subBullets = [] - feature = new Feature(text: featureText, type: featureType) - product.features.add(feature) - break; - case 'BULLET': - if(isSub){ - def subBullet = new SubBullet(text: featureText, type: featureType) - subBullets.add(subBullet) - feature.subBullets = subBullets - } else { - feature = new Feature(text: featureText, type: featureType) - product.features.add(feature) - } - break; - case 'NOTE': - isSub = false - feature = new Feature(text: featureText, type: featureType) - product.features.add(feature) - break; - } - } - products.add(product) - } - return products - } + Iterator itr = facets.iterator() + while (itr.hasNext()) { + def facet = itr.next() - /** - * Process the product response. - * @param productResponse - * @return - */ - List processProductGroupResponse(prodGroupJson){ + //set the total count on the facet + facet.count = getTotalFacetCount(facet) - def productGroups = [] - prodGroupJson.response.docs.each { doc-> - ProductGroupNew productGroup = new ProductGroupNew() + //remove the facets + if (shouldRemove(facet, partCount, selectedFacetsMap)) { + itr.remove() + } + } + } - productGroup.id = doc.productGroupId as int - productGroup.catalogInstanceId = doc.catalogInstanceId as int - productGroup.catalogInstanceName = doc.catalogInstanceName - productGroup.pageNumber = doc.pageNumber as int - productGroup.sequence = doc.sequence as int + /** + * set remove flag to true for facet with zero count + * Also apply the 80% rule on the avps + * @param facet + * @return + */ + boolean shouldRemove(facet, partCount, selectedFacetsMap) { - productGroup.description = doc.description - if(doc.brandId !=''){ - productGroup.brandId = doc.brandId as int - } + //remove facets which are already selected + if (selectedFacetsMap.containsKey(facet.type)) { + return true + } - productGroup.brandName = doc.brandName - productGroup.brandCode = doc.brandCode - productGroup.caption = doc.caption - productGroup.productName = doc.productName - productGroup.productGroupName=doc.productGroupName - productGroup.productId=doc.productId as int - productGroup.mediaUrl = doc.mediaUrl - productGroup.prefixUrl = doc.prefixUrl - productGroup.extension = doc.extension - productGroup.brandMediaUrl = doc.brandMediaUrl - productGroup.brandPrefixUrl = doc.brandPrefixUrl - productGroup.brandExtension = doc.brandExtension - productGroup.baseDealerPriceLow = doc.baseDealerPriceLow as double - productGroup.baseDealerPriceHigh = doc.baseDealerPriceHigh as double - productGroup.retailPriceLow = doc.retailPriceLow as double - productGroup.retailPriceHigh = doc.retailPriceHigh as double - productGroup.retailPriceDisplayRange = doc.retailPriceDisplayRange - productGroup.partCount = doc.partCount as int - productGroup.faqCount=doc.faqCount as int - productGroup.tag=doc.tag - //Splits ct1, ct2, ct3 and ct4 records by pipe symbol to get categoryId and Name for 4 category level - for(int i=1;i<=4;i++){ - String[] categoryRecord =doc."ct$i".split("\\|") - if(categoryRecord.size()==2){ - productGroup."ct${i}Id"=categoryRecord[0] - productGroup."ct${i}Name"=categoryRecord[1] - } - } - def isSub = false - def bulletKey ='' - def subBullets - Feature feature - doc.featureSequence.eachWithIndex{ featureSequence, index -> + //facet count zero + if (facet.count == 0) { + return true + } - def featureType = doc.featureType.getAt(index ) - def featureText = doc.feature.get(index) + //apply 80% rule + else if (facet.type.startsWith('av')) { - switch(featureType?.toUpperCase()){ - case 'SUB': - isSub = true - bulletKey = featureText as String - subBullets = [] - feature = new Feature(text: featureText, type: featureType) - productGroup.features.add(feature) - break; - case 'BULLET': - if(isSub){ - def subBullet = new SubBullet(text: featureText, type: featureType) - subBullets.add(subBullet) - feature.subBullets = subBullets - } else { - feature = new Feature(text: featureText, type: featureType) - productGroup.features.add(feature) - } - break; - case 'NOTE': - isSub = false - feature = new Feature(text: featureText, type: featureType) - productGroup.features.add(feature) - break; - } - } - productGroups.add(productGroup) - } - return productGroups - } + //remove av facet with name as Note + if (facet.name.equalsIgnoreCase('NOTE')) { + return true + } + //remove attribute facet with only 1 value in it - note this is different than count + // - which sums up the part numbers for all the values for that facet + if (facet?.values?.size() == 1) { + return true + } - /** - * Iterate through facets - * - set the total count on facet - * - remove the facet if not applicable. - * @param facets - * @param partCount - */ - void filterFacets(facets, partCount, selectedFacetsMap){ + def percent = (facet.count / partCount) * 100 + if (percent < 80) { + return true + } + facet.percent = percent + } + false + } - Iterator itr = facets.iterator() - while(itr.hasNext()){ - def facet = itr.next() + /** + * sum up the count on values and set it to facet. + * Used by next facet and header facet both + * @param facet + * @return + */ + int getTotalFacetCount(facet) { + facet.values*.count.sum() ?: 0 + } - //set the total count on the facet - facet.count = getTotalFacetCount(facet) + /** + * If sorting field id is specified in params use it for sorting based on expression in sortBys . + * else default it based on the renderer + * @param sb + * @param sortBys + * @param renderer + * @return + */ + String getSortingQS(sb, sortBys) { + def sortingQs = '' + //for some renderers like ci sortBys is null + if (sortBys) { + if (sb) { + def value = sortBys.find { it.id as String == sb } + if (value) { + sortingQs = "${value.expression}" + } + } else { + def defaultSortBy = sortBys.find { it.defaultSortBy == true } + if (defaultSortBy) { + sortingQs = "${defaultSortBy.expression}" + } + } + sortingQs = '&sort=' + sortingQs + } + sortingQs + } - //remove the facets - if(shouldRemove(facet, partCount, selectedFacetsMap)){ - itr.remove() - } - } - } - - - /** - * set remove flag to true for facet with zero count - * Also apply the 80% rule on the avps - * @param facet - * @return - */ - boolean shouldRemove(facet, partCount, selectedFacetsMap){ - - //remove facets which are already selected - if(selectedFacetsMap.containsKey(facet.type)) { - return true - } - - //facet count zero - if(facet.count == 0){ - return true - } - - //apply 80% rule - else if(facet.type.startsWith('av')){ - - //remove av facet with name as Note - if(facet.name.equalsIgnoreCase('NOTE')){ - return true - } - //remove attribute facet with only 1 value in it - note this is different than count - which sums up the part numbers for all the values for that facet - if(facet?.values?.size() == 1) { - return true - } - - def percent = (facet.count / partCount)*100 - if(percent < 80){ - return true - } - facet.percent = percent - } - return false; - } - - /** - * sum up the count on values and set it to facet. - * Used by next facet and header facet both - * @param facet - * @return - */ - int getTotalFacetCount(facet){ - return facet.values*.count.sum()?: 0 - } - - /** - * If sorting field id is specified in params use it for sorting based on expression in sortBys . - * else default it based on the renderer - * @param sb - * @param sortBys - * @param renderer - * @return - */ - String getSortingQS(sb, sortBys){ - def sortingQs = '' - //for some renderers like ci sortBys is null - if(sortBys) { - if(sb){ - def value = sortBys.find{ it.id as String == sb } - if(value){ - sortingQs = "${value.expression}" - } - } else { - def defaultSortBy = sortBys.find{it.defaultSortBy == true} - if(defaultSortBy){ - sortingQs = "${defaultSortBy.expression}" - } - } - sortingQs = "&sort="+sortingQs - } - return sortingQs - } - - /** - * Create pagination based on rows and offset. Defaults to 10 rows - */ - String getPaginationQueryString(rows, offset) { - def pagination="&rows=10&start=0" - if (rows) { - pagination="&rows=${rows}" - } - if (offset) { - pagination = pagination + "&start=${offset}" - } - return pagination - } + /** + * Create pagination based on rows and offset. Defaults to 10 rows + */ + String getPaginationQueryString(rows, offset) { + def pagination = '&rows=10&start=0' + if (rows) { + pagination = "&rows=${rows}" + } + if (offset) { + pagination = pagination + "&start=${offset}" + } + pagination + } }