diff --git a/solr/core/src/java/org/apache/solr/search/facet/DocValuesAcc.java b/solr/core/src/java/org/apache/solr/search/facet/DocValuesAcc.java index bb5c0e55a997..acafe5c54289 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/DocValuesAcc.java +++ b/solr/core/src/java/org/apache/solr/search/facet/DocValuesAcc.java @@ -37,7 +37,7 @@ * Accumulates stats separated by slot number for the fields with {@link org.apache.lucene.index.DocValues} */ public abstract class DocValuesAcc extends SlotAcc { - SchemaField sf; + protected SchemaField sf; public DocValuesAcc(FacetContext fcontext, SchemaField sf) throws IOException { super(fcontext); diff --git a/solr/core/src/java/org/apache/solr/search/facet/FacetModule.java b/solr/core/src/java/org/apache/solr/search/facet/FacetModule.java index 3cde18a5e4db..57504636d4d8 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/FacetModule.java +++ b/solr/core/src/java/org/apache/solr/search/facet/FacetModule.java @@ -354,7 +354,7 @@ class FacetComponentState { } // base class for facet functions that can be used in a sort - abstract static class FacetSortableMerger extends FacetMerger { + public abstract static class FacetSortableMerger extends FacetMerger { public void prepareSort() { } @@ -370,7 +370,7 @@ public void finish(Context mcontext) { public abstract int compareTo(FacetSortableMerger other, FacetRequest.SortDirection direction); } - abstract static class FacetDoubleMerger extends FacetSortableMerger { + public abstract static class FacetDoubleMerger extends FacetSortableMerger { @Override public abstract void merge(Object facetResult, Context mcontext); @@ -408,7 +408,7 @@ public static int compare(double a, double b, FacetRequest.SortDirection directi } } - static class FacetLongMerger extends FacetSortableMerger { + public static class FacetLongMerger extends FacetSortableMerger { long val; @Override @@ -429,7 +429,7 @@ public int compareTo(FacetSortableMerger other, FacetRequest.SortDirection direc // base class for facets that create buckets (and can hence have sub-facets) - abstract static class FacetBucketMerger extends FacetMerger { + public abstract static class FacetBucketMerger extends FacetMerger { FacetRequestT freq; public FacetBucketMerger(FacetRequestT freq) { @@ -469,7 +469,7 @@ FacetMerger createFacetMerger(String key, Object val) { } - static class FacetQueryMerger extends FacetBucketMerger { + public static class FacetQueryMerger extends FacetBucketMerger { FacetBucket bucket; public FacetQueryMerger(FacetQuery freq) { diff --git a/solr/core/src/java/org/apache/solr/search/facet/FacetParser.java b/solr/core/src/java/org/apache/solr/search/facet/FacetParser.java index 70ddc8ba2048..a23263e17a72 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/FacetParser.java +++ b/solr/core/src/java/org/apache/solr/search/facet/FacetParser.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import org.apache.solr.common.SolrException; @@ -34,7 +35,7 @@ import static org.apache.solr.common.params.CommonParams.SORT; -abstract class FacetParser { +public abstract class FacetParser { protected FacetRequestT facet; protected FacetParser parent; protected String key; @@ -133,23 +134,30 @@ public Object parseFacetOrStat(String key, Object o) throws SyntaxError { return parseFacetOrStat(key, type, args); } + public interface ParseHandler { + Object doParse(FacetParser parent, String key, Object args) throws SyntaxError; + } + + private static final Map REGISTERED_TYPES = new ConcurrentHashMap<>(); + + static { + ParseHandler fieldParser = (p, k, a) -> new FacetFieldParser(p, k).parse(a); + REGISTERED_TYPES.put("field", fieldParser); + REGISTERED_TYPES.put("terms", fieldParser); + REGISTERED_TYPES.put("query", (p, k, a) -> new FacetQueryParser(p, k).parse(a)); + REGISTERED_TYPES.put("range", (p, k, a) -> new FacetRangeParser(p, k).parse(a)); + REGISTERED_TYPES.put("heatmap", (p, k, a) -> new FacetHeatmap.Parser(p, k).parse(a)); + REGISTERED_TYPES.put("func", (p, k, a) -> p.parseStat(k, a)); + } + + public static void registerParseHandler(String type, ParseHandler parseHandler) { + REGISTERED_TYPES.put(type, parseHandler); + } + public Object parseFacetOrStat(String key, String type, Object args) throws SyntaxError { - // TODO: a place to register all these facet types? - - switch (type) { - case "field": - case "terms": - return new FacetFieldParser(this, key).parse(args); - case "query": - return new FacetQueryParser(this, key).parse(args); - case "range": - return new FacetRangeParser(this, key).parse(args); - case "topdocs": - return TopDocsAgg.AggParser.parse(args); - case "heatmap": - return new FacetHeatmap.Parser(this, key).parse(args); - case "func": - return parseStat(key, args); + ParseHandler parseHandler = REGISTERED_TYPES.get(type); + if (parseHandler != null) { + return parseHandler.doParse(this, key, args); } throw err("Unknown facet or stat. key=" + key + " type=" + type + " args=" + args); diff --git a/solr/core/src/java/org/apache/solr/search/facet/UniqueMultiDvSlotAcc.java b/solr/core/src/java/org/apache/solr/search/facet/UniqueMultiDvSlotAcc.java index 839fc520a172..89fbe7156974 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/UniqueMultiDvSlotAcc.java +++ b/solr/core/src/java/org/apache/solr/search/facet/UniqueMultiDvSlotAcc.java @@ -29,7 +29,7 @@ import org.apache.lucene.util.LongValues; import org.apache.solr.schema.SchemaField; -class UniqueMultiDvSlotAcc extends UniqueSlotAcc { +public class UniqueMultiDvSlotAcc extends UniqueSlotAcc { SortedSetDocValues topLevel; SortedSetDocValues[] subDvs; OrdinalMap ordMap; diff --git a/solr/core/src/java/org/apache/solr/search/facet/UniqueMultivaluedSlotAcc.java b/solr/core/src/java/org/apache/solr/search/facet/UniqueMultivaluedSlotAcc.java index 508da3840453..8d9de5894bb4 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/UniqueMultivaluedSlotAcc.java +++ b/solr/core/src/java/org/apache/solr/search/facet/UniqueMultivaluedSlotAcc.java @@ -25,7 +25,7 @@ import org.apache.solr.schema.SchemaField; import org.apache.solr.search.SolrIndexSearcher; -class UniqueMultivaluedSlotAcc extends UniqueSlotAcc implements UnInvertedField.Callback { +public class UniqueMultivaluedSlotAcc extends UniqueSlotAcc implements UnInvertedField.Callback { private UnInvertedField uif; private UnInvertedField.DocToTerm docToTerm; diff --git a/solr/core/src/java/org/apache/solr/search/facet/UniqueSinglevaluedSlotAcc.java b/solr/core/src/java/org/apache/solr/search/facet/UniqueSinglevaluedSlotAcc.java index 6057dd00986b..178c77b8f03d 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/UniqueSinglevaluedSlotAcc.java +++ b/solr/core/src/java/org/apache/solr/search/facet/UniqueSinglevaluedSlotAcc.java @@ -29,7 +29,7 @@ import org.apache.lucene.util.LongValues; import org.apache.solr.schema.SchemaField; -class UniqueSinglevaluedSlotAcc extends UniqueSlotAcc { +public class UniqueSinglevaluedSlotAcc extends UniqueSlotAcc { SortedDocValues topLevel; SortedDocValues[] subDvs; OrdinalMap ordMap; diff --git a/solr/core/src/java/org/apache/solr/search/facet/UniqueSlotAcc.java b/solr/core/src/java/org/apache/solr/search/facet/UniqueSlotAcc.java index 7d5a4de78fca..6f6a5524645c 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/UniqueSlotAcc.java +++ b/solr/core/src/java/org/apache/solr/search/facet/UniqueSlotAcc.java @@ -28,7 +28,7 @@ import org.apache.solr.schema.SchemaField; import org.apache.solr.util.hll.HLL; -abstract class UniqueSlotAcc extends SlotAcc { +public abstract class UniqueSlotAcc extends SlotAcc { HLLAgg.HLLFactory factory; SchemaField field; FixedBitSet[] arr; diff --git a/solr/core/src/test/org/apache/solr/search/function/AggValueSourceTest.java b/solr/core/src/test/org/apache/solr/search/function/AggValueSourceTest.java index 1fbf3a1d9710..7980b837db98 100644 --- a/solr/core/src/test/org/apache/solr/search/function/AggValueSourceTest.java +++ b/solr/core/src/test/org/apache/solr/search/function/AggValueSourceTest.java @@ -24,6 +24,7 @@ import org.apache.solr.SolrTestCase; import org.apache.solr.search.facet.FacetContext; import org.apache.solr.search.facet.FacetMerger; +import org.apache.solr.search.facet.FacetModule; import org.apache.solr.search.facet.SimpleAggValueSource; import org.apache.solr.search.facet.SlotAcc; import org.junit.Test; @@ -75,7 +76,8 @@ public Object getValue(int slot) { @Override public FacetMerger createFacetMerger(Object prototype) { - return new FacetMerger() { + // check these inner classes can be referenced by name + FacetModule.FacetSortableMerger merger = new FacetModule.FacetDoubleMerger() { double total = 0.0D; @Override @@ -84,13 +86,11 @@ public void merge(Object facetResult, Context mcontext) { } @Override - public void finish(Context mcontext) { } - - @Override - public Object getMergedResult() { + public double getDouble() { return total; } }; + return merger; } @Override