diff --git a/source/java/org/alfresco/rest/api/search/context/SearchRequestContext.java b/source/java/org/alfresco/rest/api/search/context/SearchRequestContext.java index f16f268ac4..4706b22915 100644 --- a/source/java/org/alfresco/rest/api/search/context/SearchRequestContext.java +++ b/source/java/org/alfresco/rest/api/search/context/SearchRequestContext.java @@ -53,16 +53,6 @@ public class SearchRequestContext this.includeRequest = includeRequest; this.pivotKeys = new HashMap<>(); this.stores = new HashSet<>(); - - /** - this.facetQueries = facetQueries!=null?Collections.unmodifiableList(facetQueries): Collections.emptyList(); - this.facetFields = new FacetFields(facetFields!=null?Collections.unmodifiableList(facetFields.getFacets()):Collections.emptyList()); - this.facetIntervals = facetIntervals!=null? - new IntervalParameters(Collections.unmodifiableList(facetIntervals.getSets()), - Collections.unmodifiableList(facetIntervals.getIntervals())) - : - new IntervalParameters(Collections.emptyList(),Collections.emptyList()); - this.pivots = pivots!=null?Collections.unmodifiableList(pivots): Collections.emptyList();**/ } public static final SearchRequestContext from(SearchQuery searchQuery) diff --git a/source/java/org/alfresco/rest/api/search/impl/RangeResultMapper.java b/source/java/org/alfresco/rest/api/search/impl/RangeResultMapper.java deleted file mode 100644 index 83eac40e67..0000000000 --- a/source/java/org/alfresco/rest/api/search/impl/RangeResultMapper.java +++ /dev/null @@ -1,133 +0,0 @@ -/*- - * #%L - * Alfresco Remote API - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ - -package org.alfresco.rest.api.search.impl; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericBucket; -import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericFacetResponse; -import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericFacetResponse.FACET_TYPE; -import org.alfresco.repo.search.impl.solr.facet.facetsresponse.Metric; -import org.alfresco.repo.search.impl.solr.facet.facetsresponse.Metric.METRIC_TYPE; -import org.alfresco.repo.search.impl.solr.facet.facetsresponse.SimpleMetric; -import org.alfresco.rest.api.search.model.SearchQuery; -import org.alfresco.service.cmr.search.RangeParameters; - -/**Helper to map range results. - * - * @author Michael Suzuki - */ -public class RangeResultMapper -{ - /** - * Transforms the facet range response into generic facet response. - * @param facetFields - * @param searchQuery - * @return GenericFacetResponse - */ - public static List getGenericFacetsForRanges( Map>> facetFields, SearchQuery searchQuery) - { - List ffcs = new ArrayList<>(facetFields.size()); - if (facetFields != null && !facetFields.isEmpty() && searchQuery.getQuery() != null) - { - for (Entry>> facet : facetFields.entrySet()) - { - List buckets = new ArrayList<>(); - facet.getValue().forEach(action -> buckets.add(buildGenericBucketFromRange(facet.getKey(), - (Map) action, - searchQuery.getFacetRanges()))); - ffcs.add(new GenericFacetResponse(FACET_TYPE.range, facet.getKey(), buckets)); - } - } - return ffcs; - } - - /** - * Builds the generic facet response out of range results. - * @param facetField - * @param facet - * @return - */ - private static GenericBucket buildGenericBucketFromRange(String facetField, Map facet, List ranges) - { - String start = facet.get(GenericFacetResponse.START); - String end = facet.get(GenericFacetResponse.END); - boolean startInclusive = true; - boolean endInclusive = false; - - for(RangeParameters range : ranges) - { - if(range.getField().equalsIgnoreCase(facetField)) - { - List includes = range.getInclude(); - if(includes != null && !includes.isEmpty()) - { - startInclusive = range.isRangeStartInclusive(); - endInclusive = range.isRangeEndInclusive(); - } - } - } - - facet.put(GenericFacetResponse.START_INC.toString(), Boolean.toString(startInclusive)); - facet.put(GenericFacetResponse.END_INC.toString(), Boolean.toString(endInclusive)); - - facet.remove(GenericFacetResponse.LABEL); - StringBuilder filterQ = new StringBuilder(); - filterQ.append(facetField).append(":") - .append(startInclusive ? "[" :"<") - .append(start).append(" TO ") - .append(end) - .append(endInclusive ? "]" :">"); - - Set metrics = new HashSet( - Arrays.asList(new SimpleMetric( - METRIC_TYPE.count,facet.get( - GenericFacetResponse.COUNT)))); - facet.remove("count"); - - StringBuilder label = new StringBuilder(); - label.append(startInclusive ? "[" :"(") - .append(start) - .append(" - ") - .append(end) - .append(endInclusive ? "]" :")"); - - return new GenericBucket(label.toString(), - filterQ.toString(), - null, - metrics, - null, - facet); - - } -} diff --git a/source/java/org/alfresco/rest/api/search/impl/ResultMapper.java b/source/java/org/alfresco/rest/api/search/impl/ResultMapper.java index c65c8696d9..1d0e7a0d32 100644 --- a/source/java/org/alfresco/rest/api/search/impl/ResultMapper.java +++ b/source/java/org/alfresco/rest/api/search/impl/ResultMapper.java @@ -50,6 +50,7 @@ import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericFacetRespo import org.alfresco.repo.search.impl.solr.facet.facetsresponse.GenericFacetResponse.FACET_TYPE; import org.alfresco.repo.search.impl.solr.facet.facetsresponse.Metric; import org.alfresco.repo.search.impl.solr.facet.facetsresponse.Metric.METRIC_TYPE; +import org.alfresco.repo.search.impl.solr.facet.facetsresponse.RangeResultMapper; import org.alfresco.repo.search.impl.solr.facet.facetsresponse.SimpleMetric; import org.alfresco.repo.security.permissions.impl.acegi.FilteringResultSet; import org.alfresco.repo.version.Version2Model; @@ -340,7 +341,7 @@ public class ResultMapper facets.addAll(getGenericFacetsForIntervals(facetInterval, searchQuery)); Map>> facetRanges = solrResultSet.getFacetRanges(); - facets.addAll(RangeResultMapper.getGenericFacetsForRanges(facetRanges, searchQuery)); + facets.addAll(RangeResultMapper.getGenericFacetsForRanges(facetRanges, searchQuery.getFacetRanges())); List stats = getFieldStats(searchRequestContext, solrResultSet.getStats()); List pimped = getPivots(searchRequestContext, solrResultSet.getPivotFacets(), stats); diff --git a/source/java/org/alfresco/rest/api/search/impl/SearchMapper.java b/source/java/org/alfresco/rest/api/search/impl/SearchMapper.java index a6073e56d1..b33d11768e 100644 --- a/source/java/org/alfresco/rest/api/search/impl/SearchMapper.java +++ b/source/java/org/alfresco/rest/api/search/impl/SearchMapper.java @@ -78,9 +78,7 @@ import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.ListIterator; import java.util.Locale; -import java.util.Locale.Builder; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -126,7 +124,7 @@ public class SearchMapper fromDefault(sp, searchQuery.getDefaults()); fromFilterQuery(sp, searchQuery.getFilterQueries()); fromFacetQuery(sp, searchQuery.getFacetQueries()); - fromPivot(sp, searchQuery.getStats(), searchQuery.getFacetFields(), searchQuery.getPivots(), searchRequestContext); + fromPivot(sp, searchQuery.getStats(), searchQuery.getFacetFields(), searchQuery.getFacetRanges(), searchQuery.getPivots(), searchRequestContext); fromStats(sp, searchQuery.getStats()); fromFacetFields(sp, searchQuery.getFacetFields()); fromSpellCheck(sp, searchQuery.getSpellcheck()); @@ -576,20 +574,22 @@ public class SearchMapper } - public void fromPivot(SearchParameters sp, List stats, FacetFields facetFields, List multiplePivots, SearchRequestContext searchRequestContext) + public void fromPivot(SearchParameters sp, List stats, FacetFields facetFields, List ranges, List multiplePivots, + SearchRequestContext searchRequestContext) { if (multiplePivots != null && !multiplePivots.isEmpty()) { multiplePivots.forEach(aPivot -> { List pivotKeys = new ArrayList<>(); - buildPivotKeys(pivotKeys, aPivot, stats,facetFields, searchRequestContext); + buildPivotKeys(pivotKeys, aPivot, stats, facetFields, ranges, searchRequestContext); sp.addPivots(pivotKeys); }); } } - protected void buildPivotKeys(List pivotKeys, Pivot aPivot, List stats, FacetFields facetFields, SearchRequestContext searchRequestContext) + protected void buildPivotKeys(List pivotKeys, Pivot aPivot, List stats, FacetFields facetFields, + List ranges, SearchRequestContext searchRequestContext) { if (aPivot == null) return; String pivotKey = null; @@ -617,7 +617,7 @@ public class SearchMapper if (pivotKey == null && ((aPivot.getPivots() == null) || aPivot.getPivots().isEmpty())) { - //It is the last one so it can reference stats + //It is the last one so it can reference stats or range if (stats != null && !stats.isEmpty()) { Optional foundStat = stats.stream().filter(stas -> aPivot.getKey().equals(stas.getLabel()!=null?stas.getLabel():stas.getField())).findFirst(); @@ -628,12 +628,25 @@ public class SearchMapper searchRequestContext.getPivotKeys().put(pivotKey, pivotKey); } } + + if (ranges != null && !ranges.isEmpty()) + { + for (RangeParameters aRange:ranges) + { + if (aRange.getTags().contains(aPivot.getKey())) + { + pivotKey = aPivot.getKey(); + pivotKeys.add(pivotKey); + searchRequestContext.getPivotKeys().put(pivotKey, pivotKey); + } + } + } } if (pivotKey == null) { throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, - new Object[] { ": Pivot parameter " + aPivot.getKey() + " does not reference a facet Field or stats." }); + new Object[] { ": Pivot parameter " + aPivot.getKey() + " does not reference a facet Field, range or stats." }); } if (aPivot.getPivots() != null && !aPivot.getPivots().isEmpty() && aPivot.getPivots().size()>1) @@ -644,7 +657,7 @@ public class SearchMapper aPivot.getPivots().forEach(subPivot -> { - buildPivotKeys(pivotKeys, subPivot, stats, facetFields, searchRequestContext); + buildPivotKeys(pivotKeys, subPivot, stats, facetFields, ranges, searchRequestContext); }); } diff --git a/source/test-java/org/alfresco/rest/api/search/SearchMapperTests.java b/source/test-java/org/alfresco/rest/api/search/SearchMapperTests.java index 350570f557..10f493c8f4 100644 --- a/source/test-java/org/alfresco/rest/api/search/SearchMapperTests.java +++ b/source/test-java/org/alfresco/rest/api/search/SearchMapperTests.java @@ -34,14 +34,6 @@ import static org.alfresco.service.cmr.search.SearchService.LANGUAGE_FTS_ALFRESC import static org.alfresco.service.cmr.search.SearchService.LANGUAGE_LUCENE; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; - import org.alfresco.rest.api.search.context.SearchRequestContext; import org.alfresco.rest.api.search.impl.SearchMapper; import org.alfresco.rest.api.search.impl.StoreMapper; @@ -77,6 +69,13 @@ import org.alfresco.service.cmr.search.StatsRequestParameters; import org.junit.BeforeClass; import org.junit.Test; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; + /** * Tests the SearchMapper class * @@ -827,13 +826,13 @@ public class SearchMapperTests public void fromPivot() throws Exception { SearchParameters searchParameters = new SearchParameters(); - searchMapper.fromPivot(searchParameters, null, null, null, null); + searchMapper.fromPivot(searchParameters, null, null, null, null, null); List facets = new ArrayList<>(1); facets.add(new FacetField("myfield",null,null,null,null,null,null,null,null,null,null)); FacetFields ff = new FacetFields(facets); searchMapper.fromFacetFields(searchParameters,ff); - searchMapper.fromPivot(searchParameters, null, ff, null, null); + searchMapper.fromPivot(searchParameters, null, ff, null, null, null); assertEquals(1 ,searchParameters.getFieldFacets().size()); assertEquals(0 ,searchParameters.getPivots().size()); @@ -842,7 +841,7 @@ public class SearchMapperTests try { - searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot(null, null)), null); + searchMapper.fromPivot(searchParameters, null, ff, null, Arrays.asList(new Pivot(null, null)), null); fail(); } catch (IllegalArgumentException iae) @@ -853,7 +852,7 @@ public class SearchMapperTests try { - searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot("", null)), null); + searchMapper.fromPivot(searchParameters, null, ff, null, Arrays.asList(new Pivot("", null)), null); fail(); } catch (IllegalArgumentException iae) @@ -866,16 +865,17 @@ public class SearchMapperTests //"bob" doesn't refer to a field facet but its the last one so needs to refer to a stat StatsRequestParameters bobf = new StatsRequestParameters("bob", null, null, null,null, null, null, null,null, null, null, null,null, null, null, null); StatsRequestParameters bobL = new StatsRequestParameters("creator", "bob", null, null,null, null, null, null,null, null, null, null,null, null, null, null); - searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, Arrays.asList(new Pivot("bob", null)), searchRequestContext); + searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, null, Arrays.asList(new Pivot("bob", null)), searchRequestContext); assertEquals(1 ,searchParameters.getPivots().size()); searchParameters = new SearchParameters(); - searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, Arrays.asList(new Pivot("bob", null)), searchRequestContext); + searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, null, Arrays.asList(new Pivot("bob", null)), searchRequestContext); assertEquals(1 ,searchParameters.getPivots().size()); try { - searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot("ken", null),new Pivot("bob", null)), searchRequestContext); + searchMapper.fromPivot(searchParameters, null, ff, null, + Arrays.asList(new Pivot("ken", null),new Pivot("bob", null)), searchRequestContext); fail(); } catch (InvalidArgumentException iae) @@ -886,7 +886,7 @@ public class SearchMapperTests searchParameters = new SearchParameters(); - searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot("myfield", null)), searchRequestContext); + searchMapper.fromPivot(searchParameters, null, ff, null, Arrays.asList(new Pivot("myfield", null)), searchRequestContext); searchMapper.fromFacetFields(searchParameters,ff); //Moved from a field facet to a pivot assertEquals(0 ,searchParameters.getFieldFacets().size()); @@ -896,7 +896,8 @@ public class SearchMapperTests searchParameters = new SearchParameters(); try { - searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, Arrays.asList(new Pivot("bob", Arrays.asList(new Pivot("hope", null)))), searchRequestContext); + searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, null, + Arrays.asList(new Pivot("bob", Arrays.asList(new Pivot("hope", null)))), searchRequestContext); fail(); } catch (InvalidArgumentException iae) @@ -909,7 +910,8 @@ public class SearchMapperTests facets = new ArrayList<>(1); facets.add(new FacetField("king",null,null,null,null,null,null,null,null,null,null)); ff = new FacetFields(facets); - searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, Arrays.asList(new Pivot("king", Arrays.asList(new Pivot("bob", null)))), searchRequestContext); + searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, null, + Arrays.asList(new Pivot("king", Arrays.asList(new Pivot("bob", null)))), searchRequestContext); assertEquals(1 ,searchParameters.getPivots().size()); assertEquals(2 ,searchParameters.getPivots().get(0).size()); assertEquals("king" ,searchParameters.getPivots().get(0).get(0)); @@ -922,13 +924,30 @@ public class SearchMapperTests facets.add(new FacetField("kong",null,null,null,null,null,null,null,null,null,null)); facets.add(new FacetField("kang",null,null,null,null,null,null,null,null,null,null)); ff = new FacetFields(facets); - searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, Arrays.asList(new Pivot("king", Arrays.asList(new Pivot("bob", null))), new Pivot("kong", null)), searchRequestContext); + searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, null, + Arrays.asList(new Pivot("king", Arrays.asList(new Pivot("bob", null))), new Pivot("kong", null)), searchRequestContext); assertEquals(2 ,searchParameters.getPivots().size()); assertEquals(2 ,searchParameters.getPivots().get(0).size()); assertEquals("king" ,searchParameters.getPivots().get(0).get(0)); assertEquals("bob" ,searchParameters.getPivots().get(0).get(1)); assertEquals("kong" ,searchParameters.getPivots().get(1).get(0)); + searchRequestContext = SearchRequestContext.from(minimalQuery()); + searchParameters = new SearchParameters(); + List rangeParams = new ArrayList(); + facets = new ArrayList<>(2); + facets.add(new FacetField("king",null,null,null,null,null,null,null,null,null,null)); + facets.add(new FacetField("kong",null,null,null,null,null,null,null,null,null,null)); + ff = new FacetFields(facets); + rangeParams.add(new RangeParameters("content.size", "0", "100000", "1000",true,null,null,Arrays.asList("hope"),null)); + searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, rangeParams, + Arrays.asList(new Pivot("king", Arrays.asList(new Pivot("bob", null))), new Pivot("hope", null)), searchRequestContext); + assertEquals(2 ,searchParameters.getPivots().size()); + assertEquals(2 ,searchParameters.getPivots().get(0).size()); + assertEquals("king" ,searchParameters.getPivots().get(0).get(0)); + assertEquals("bob" ,searchParameters.getPivots().get(0).get(1)); + assertEquals("hope" ,searchParameters.getPivots().get(1).get(0)); + } @Test @@ -1021,7 +1040,7 @@ public class SearchMapperTests SearchQuery sq = new SearchQuery(query, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,null, null,FacetFormat.V2); - + SearchRequestContext searchRequestContext = SearchRequestContext.from(sq); SearchParameters searchParameters = searchMapper.toSearchParameters(ResultMapperTests.EMPTY_PARAMS, sq, searchRequestContext); assertNotNull(searchParameters); @@ -1031,9 +1050,10 @@ public class SearchMapperTests assertEquals("workspaces store is the default", StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, searchParameters.getStores().get(0)); assertEquals(LimitBy.FINAL_SIZE, searchParameters.getLimitBy()); assertEquals(100, searchParameters.getLimit()); + } - + @Test public void facetRange() {