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 6ac84defcc..01ac3a93f1 100644 --- a/source/java/org/alfresco/rest/api/search/impl/SearchMapper.java +++ b/source/java/org/alfresco/rest/api/search/impl/SearchMapper.java @@ -576,59 +576,78 @@ public class SearchMapper } } - public void fromPivot(SearchParameters sp, List stats, FacetFields facetFields, List pivots, SearchRequestContext searchRequestContext) + + public void fromPivot(SearchParameters sp, List stats, FacetFields facetFields, List multiplePivots, SearchRequestContext searchRequestContext) { - if (facetFields != null && pivots != null && !pivots.isEmpty()) + if (multiplePivots != null && !multiplePivots.isEmpty()) { - ParameterCheck.mandatory("facetFields facets", facetFields.getFacets()); + multiplePivots.forEach(aPivot -> { + List pivotKeys = new ArrayList<>(); + buildPivotKeys(pivotKeys, aPivot, stats,facetFields, searchRequestContext); + sp.addPivots(pivotKeys); + }); - ListIterator piterator = pivots.listIterator(); + } + } - while (piterator.hasNext()) { + protected void buildPivotKeys(List pivotKeys, Pivot aPivot, List stats, FacetFields facetFields, SearchRequestContext searchRequestContext) + { + if (aPivot == null) return; + String pivotKey = null; + ParameterCheck.mandatoryString("pivot key", aPivot.getKey()); - Pivot pivot = piterator.next(); - ParameterCheck.mandatoryString("pivot key", pivot.getKey()); - String pivotKey = pivot.getKey(); + if (facetFields.getFacets() != null && !facetFields.getFacets().isEmpty()) + { + Optional found = facetFields.getFacets().stream() + .filter(queryable -> aPivot.getKey().equals(queryable.getLabel() != null ? queryable.getLabel() : queryable.getField())).findFirst(); - if (facetFields.getFacets() != null && !facetFields.getFacets().isEmpty()) + if (found.isPresent()) + { + pivotKey = aPivot.getKey(); + if (searchRequestContext.getPivotKeys().containsValue(pivotKey)) { - Optional found = facetFields.getFacets().stream() - .filter(queryable -> pivotKey.equals(queryable.getLabel() != null ? queryable.getLabel() : queryable.getField())).findFirst(); - - if (found.isPresent()) - { - sp.addPivot(found.get().getField()); - facetFields.getFacets().remove(found.get()); - searchRequestContext.getPivotKeys().put(found.get().getField(), pivotKey); - continue; - } + throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, + new Object[] { ": Duplicate pivot parameter " + aPivot.getKey() + "" }); } - if (piterator.hasNext()) - { - //Its not the last one so lets complain - throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, - new Object[] { ": Pivot parameter " + pivotKey + " is does not reference a facet Field." }); - } - else - { - if (stats != null && !stats.isEmpty()) - { - //It is the last one so it can reference stats - Optional foundStat = stats.stream().filter(stas -> pivotKey.equals(stas.getLabel()!=null?stas.getLabel():stas.getField())).findFirst(); - if (foundStat.isPresent()) - { - sp.addPivot(pivotKey); - searchRequestContext.getPivotKeys().put(pivotKey, pivotKey); - continue; - } + pivotKeys.add(found.get().getField()); + facetFields.getFacets().remove(found.get()); + searchRequestContext.getPivotKeys().put(found.get().getField(), pivotKey); + } + } - } - throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, - new Object[] { ": Pivot parameter " + pivotKey + " is does not reference a facet Field or stats." }); + if (pivotKey == null && ((aPivot.getPivots() == null) || aPivot.getPivots().isEmpty())) + { + //It is the last one so it can reference stats + if (stats != null && !stats.isEmpty()) + { + Optional foundStat = stats.stream().filter(stas -> aPivot.getKey().equals(stas.getLabel()!=null?stas.getLabel():stas.getField())).findFirst(); + if (foundStat.isPresent()) + { + 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." }); + } + + if (aPivot.getPivots() != null && !aPivot.getPivots().isEmpty() && aPivot.getPivots().size()>1) + { + throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, + new Object[] { ": Currently only 1 nested pivot is supported, you have "+aPivot.getPivots().size()}); + } + + aPivot.getPivots().forEach(subPivot -> + { + buildPivotKeys(pivotKeys, subPivot, stats, facetFields, searchRequestContext); + }); + } public void fromStats(SearchParameters sp, List stats) diff --git a/source/java/org/alfresco/rest/api/search/model/Pivot.java b/source/java/org/alfresco/rest/api/search/model/Pivot.java index e3df93ed12..29f3540bd5 100644 --- a/source/java/org/alfresco/rest/api/search/model/Pivot.java +++ b/source/java/org/alfresco/rest/api/search/model/Pivot.java @@ -28,21 +28,31 @@ package org.alfresco.rest.api.search.model; import org.codehaus.jackson.annotate.JsonCreator; import org.codehaus.jackson.annotate.JsonProperty; +import java.util.Collections; +import java.util.List; + /** * POJO class representing Pivot */ public class Pivot { private final String key; + private final List pivots; @JsonCreator - public Pivot(@JsonProperty("key") String key) + public Pivot(@JsonProperty("key") String key, @JsonProperty("pivots") List pivots) { this.key = key; + this.pivots = pivots == null? Collections.emptyList():pivots; } public String getKey() { return key; } + + public List getPivots() + { + return pivots; + } } 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 359d4ac038..f7c1fd8dd7 100644 --- a/source/test-java/org/alfresco/rest/api/search/SearchMapperTests.java +++ b/source/test-java/org/alfresco/rest/api/search/SearchMapperTests.java @@ -848,7 +848,7 @@ public class SearchMapperTests try { - searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot(null)), null); + searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot(null, null)), null); fail(); } catch (IllegalArgumentException iae) @@ -859,12 +859,11 @@ public class SearchMapperTests try { - searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot("")), null); + searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot("", null)), null); fail(); } catch (IllegalArgumentException iae) { - //"bob" doesn't refer to a field facet assertNotNull(iae); } @@ -873,16 +872,16 @@ 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")), searchRequestContext); + searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, 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")), searchRequestContext); + searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, Arrays.asList(new Pivot("bob", null)), searchRequestContext); assertEquals(1 ,searchParameters.getPivots().size()); try { - searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot("ken"),new Pivot("bob")), searchRequestContext); + searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot("ken", null),new Pivot("bob", null)), searchRequestContext); fail(); } catch (InvalidArgumentException iae) @@ -893,12 +892,48 @@ public class SearchMapperTests searchParameters = new SearchParameters(); - searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot("myfield")), searchRequestContext); + searchMapper.fromPivot(searchParameters, null, ff, Arrays.asList(new Pivot("myfield", null)), searchRequestContext); searchMapper.fromFacetFields(searchParameters,ff); //Moved from a field facet to a pivot assertEquals(0 ,searchParameters.getFieldFacets().size()); assertEquals(1 ,searchParameters.getPivots().size()); - assertEquals("myfield" ,searchParameters.getPivots().get(0)); + assertEquals("myfield" ,searchParameters.getPivots().get(0).get(0)); + + searchParameters = new SearchParameters(); + try + { + searchMapper.fromPivot(searchParameters, Arrays.asList(bobf), ff, Arrays.asList(new Pivot("bob", Arrays.asList(new Pivot("hope", null)))), searchRequestContext); + fail(); + } + catch (InvalidArgumentException iae) + { + //"bob" doesn't refer to a field facet or stat + assertNotNull(iae); + } + + searchRequestContext = SearchRequestContext.from(minimalQuery()); + 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); + assertEquals(1 ,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)); + + searchRequestContext = SearchRequestContext.from(minimalQuery()); + searchParameters = new SearchParameters(); + facets = new ArrayList<>(1); + 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)); + 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); + 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)); }