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 4a32bba77f..17b34c2f06 100644 --- a/source/java/org/alfresco/rest/api/search/impl/SearchMapper.java +++ b/source/java/org/alfresco/rest/api/search/impl/SearchMapper.java @@ -27,6 +27,7 @@ package org.alfresco.rest.api.search.impl; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.search.impl.lucene.LuceneQueryLanguageSPI; import org.alfresco.rest.api.search.model.Default; import org.alfresco.rest.api.search.model.FacetField; import org.alfresco.rest.api.search.model.FacetFields; @@ -64,6 +65,8 @@ import static org.alfresco.service.cmr.search.SearchService.*; import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Maps from a json request and a solr SearchParameters object. @@ -278,11 +281,29 @@ public class SearchMapper throw new InvalidArgumentException(InvalidArgumentException.DEFAULT_MESSAGE_ID, new Object[] { ": filterQueries {} not allowed with cmis language" }); } - for (FilterQuery fq:filterQueries) { ParameterCheck.mandatoryString("filterQueries query", fq.getQuery()); - sp.addFilterQuery(fq.getQuery()); + String query = fq.getQuery().trim(); + if (fq.getTags() == null || fq.getTags().isEmpty() || query.contains("afts tag")) + { + //If its already got tags then just let it through + sp.addFilterQuery(query); + } + else + { + String tags = "tag="+String.join(",", fq.getTags()); + Matcher matcher = LuceneQueryLanguageSPI.AFTS_QUERY.matcher(query); + if (matcher.find()) + { + query = "{!afts "+tags+" "+matcher.group(1).trim()+"}"+matcher.group(2); + } + else + { + query = "{!afts "+tags+" }"+query; + } + sp.addFilterQuery(query); + } } } } @@ -331,8 +352,11 @@ public class SearchMapper { ParameterCheck.mandatoryString("facetFields facet field", facet.getField()); String field = facet.getField(); - //String label = facet.getLabel()!=null?facet.getLabel():field; - //field = "{key='"+label+"'}"+field; + if (facet.getExcludeFilters() != null && !facet.getExcludeFilters().isEmpty()) + { + int startIndex = field.startsWith("{!afts")?7:0; + field = "{!afts ex="+String.join(",", facet.getExcludeFilters())+"}"+field.substring(startIndex); + } FieldFacet ff = new FieldFacet(field); @@ -366,7 +390,6 @@ public class SearchMapper ff.setOffset(facet.getOffset()); ff.setMinCount(facet.getMincount()); ff.setEnumMethodCacheMinDF(facet.getFacetEnumCacheMinDf()); - sp.addFieldFacet(ff); } } diff --git a/source/java/org/alfresco/rest/api/search/model/FacetField.java b/source/java/org/alfresco/rest/api/search/model/FacetField.java index 8174d6ba74..d4e03b9541 100644 --- a/source/java/org/alfresco/rest/api/search/model/FacetField.java +++ b/source/java/org/alfresco/rest/api/search/model/FacetField.java @@ -30,6 +30,9 @@ import org.alfresco.service.cmr.search.SearchParameters.FieldFacetSort; import org.codehaus.jackson.annotate.JsonCreator; import org.codehaus.jackson.annotate.JsonProperty; +import java.util.Collections; +import java.util.List; + /** * POJO class representing the FacetField * @@ -47,6 +50,7 @@ public class FacetField private final Integer offset; private final Integer mincount; private final Integer facetEnumCacheMinDf; + private final List excludeFilters; @JsonCreator public FacetField(@JsonProperty("field") String field, @@ -58,6 +62,7 @@ public class FacetField @JsonProperty("limit") Integer limit, @JsonProperty("offset") Integer offset, @JsonProperty("mincount") Integer mincount, + @JsonProperty("excludeFilters") List excludeFilters, @JsonProperty("facetEnumCacheMinDf") Integer facetEnumCacheMinDf) { this.field = field; @@ -69,17 +74,14 @@ public class FacetField this.limit = limit; //Can be null this.offset = offset == null?0:offset; this.mincount = mincount == null?1:mincount; + this.excludeFilters = excludeFilters == null? Collections.emptyList():excludeFilters; this.facetEnumCacheMinDf = facetEnumCacheMinDf == null?0:facetEnumCacheMinDf; } - /** - "excludeFilters": [ - "string" - ], - - "contains": "string", - "containsIgnoreCase": true, - **/ + public List getExcludeFilters() + { + return excludeFilters; + } public String getField() { 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 e08e12c352..5f26a99dc3 100644 --- a/source/test-java/org/alfresco/rest/api/search/SearchMapperTests.java +++ b/source/test-java/org/alfresco/rest/api/search/SearchMapperTests.java @@ -58,10 +58,13 @@ import org.alfresco.service.cmr.search.LimitBy; import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.search.SearchParameters.FieldFacet; import org.alfresco.service.cmr.search.SearchService; +import org.junit.Assert; import org.junit.Test; import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Tests the SearchMapper class @@ -304,7 +307,7 @@ public class SearchMapperTests //Doesn't error searchMapper.fromFilterQuery(searchParameters, null); - searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("hedgehog", null), new FilterQuery("king", Arrays.asList("not", "used")))); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("hedgehog", null), new FilterQuery("king", null))); assertEquals(2 ,searchParameters.getFilterQueries().size()); assertEquals("hedgehog" ,searchParameters.getFilterQueries().get(0)); assertEquals("king" ,searchParameters.getFilterQueries().get(1)); @@ -321,6 +324,33 @@ public class SearchMapperTests //You can't specify FilterQuery when using the CMIS language assertNotNull(iae); } + + searchParameters = new SearchParameters(); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts}description:xyz", Arrays.asList("desc1", "desc2")))); + assertEquals("{!afts tag=desc1,desc2 }description:xyz" ,searchParameters.getFilterQueries().get(0)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts}description:xyz", Arrays.asList("desc1")))); + assertEquals("{!afts tag=desc1 }description:xyz" ,searchParameters.getFilterQueries().get(1)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("description:xyz", Arrays.asList("desc1")))); + assertEquals("{!afts tag=desc1 }description:xyz" ,searchParameters.getFilterQueries().get(2)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts} description:xyz", Arrays.asList("desc1")))); + assertEquals("{!afts tag=desc1 } description:xyz" ,searchParameters.getFilterQueries().get(3)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery(" {!afts cake} description:xyz", Arrays.asList("desc1")))); + assertEquals("{!afts tag=desc1 cake} description:xyz" ,searchParameters.getFilterQueries().get(4)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts tag=desc1}description:xyz", Arrays.asList("desc1")))); + assertEquals("{!afts tag=desc1}description:xyz" ,searchParameters.getFilterQueries().get(5)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("created:2011", Arrays.asList("desc1")))); + assertEquals("{!afts tag=desc1 }created:2011" ,searchParameters.getFilterQueries().get(6)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("=cm:name:cabbage", Arrays.asList("desc1")))); + assertEquals("{!afts tag=desc1 }=cm:name:cabbage" ,searchParameters.getFilterQueries().get(7)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{http://www.alfresco.org/model/content/1.0}title:workflow", null))); + assertEquals("{http://www.alfresco.org/model/content/1.0}title:workflow" ,searchParameters.getFilterQueries().get(8)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{http://www.alfresco.org/model/content/1.0}title:workflow", Arrays.asList("desc1")))); + assertEquals("{!afts tag=desc1 }{http://www.alfresco.org/model/content/1.0}title:workflow" ,searchParameters.getFilterQueries().get(9)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{!afts} description:xyz", Arrays.asList("desc1", "desc2")))); + assertEquals("{!afts tag=desc1,desc2 }description:xyz" ,searchParameters.getFilterQueries().get(0)); + searchMapper.fromFilterQuery(searchParameters, Arrays.asList(new FilterQuery("{ !afts } description:xyz", Arrays.asList("desc1", "desc2")))); + assertEquals("{!afts tag=desc1,desc2 }description:xyz" ,searchParameters.getFilterQueries().get(0)); + } @Test @@ -427,14 +457,14 @@ public class SearchMapperTests try { - searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField(null,null,null,null,null,null,null,null,null,null)))); + searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField(null,null,null,null,null,null,null,null,null,null,null)))); fail(); } catch (IllegalArgumentException iae) { assertTrue(iae.getLocalizedMessage().contains("facetFields facet field is a mandatory parameter")); } - searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,null,null,null,null,null,null,null)))); + searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,null,null,null,null,null,null,null,null)))); assertEquals(1 ,searchParameters.getFieldFacets().size()); FieldFacet ff = searchParameters.getFieldFacets().get(0); @@ -449,7 +479,7 @@ public class SearchMapperTests // assertEquals("{key='myfield'}myfield" ,ff.getField()); searchParameters = new SearchParameters(); - searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield","mylabel","myprefix",null,null,null,null,null,null,null)))); + searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield","mylabel","myprefix",null,null,null,null,null,null,null,null)))); ff = searchParameters.getFieldFacets().get(0); // assertEquals("{key='mylabel'}myfield" ,ff.getField()); @@ -457,7 +487,7 @@ public class SearchMapperTests try { - searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"badsort",null,null,null,null,null,null)))); + searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"badsort",null,null,null,null,null,null,null)))); fail(); } catch (InvalidArgumentException iae) @@ -468,7 +498,7 @@ public class SearchMapperTests try { - searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null, null,"badmethod",null,null,null,null,null)))); + searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null, null,"badmethod",null,null,null,null,null,null)))); fail(); } catch (InvalidArgumentException iae) @@ -478,12 +508,25 @@ public class SearchMapperTests } searchParameters = new SearchParameters(); - searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"INDEX","ENUM",null,null,null,null,null)))); + searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"INDEX","ENUM",null,null,null,null,null,null)))); ff = searchParameters.getFieldFacets().get(0); assertEquals("INDEX" ,ff.getSort().toString()); assertEquals("ENUM" ,ff.getMethod().toString()); } + @Test + public void fromMultiSelectFacetFields() throws Exception + { + SearchParameters searchParameters = new SearchParameters(); + searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("myfield",null,null,"INDEX","ENUM",null,null,null,null,Arrays.asList("tag1"),null)))); + FieldFacet ff = searchParameters.getFieldFacets().get(0); + assertEquals("{!afts ex=tag1}myfield" , ff.getField()); + searchParameters = new SearchParameters(); + searchMapper.fromFacetFields(searchParameters, new FacetFields(Arrays.asList(new FacetField("{!afts}thefield",null,null,null,null,null,null,null,null,Arrays.asList("tag5"),null)))); + ff = searchParameters.getFieldFacets().get(0); + assertEquals("{!afts ex=tag5}thefield" , ff.getField()); + } + @Test public void fromLimits() throws Exception {