88import org .apache .commons .lang3 .tuple .Pair ;
99
1010import javax .annotation .Nullable ;
11+ import java .math .BigDecimal ;
1112import java .util .HashMap ;
1213import java .util .Map ;
1314import java .util .Optional ;
@@ -21,11 +22,15 @@ public final class RangeUtils {
2122 private RangeUtils () {
2223 }
2324
24- public static Map <FacetRange < String > , RangeStats > mapRangeToStats (final RangeFacetResult facetResult ) {
25- final Map <FacetRange < String > , RangeStats > rangeToStats = new HashMap <>();
25+ public static Map <String , RangeStats > mapRangeToStats (final RangeFacetResult facetResult ) {
26+ final Map <String , RangeStats > rangeToStats = new HashMap <>();
2627 facetResult .getRanges ()
27- .forEach (stats -> parseFacetRange (stats .getLowerEndpoint (), stats .getUpperEndpoint ())
28- .ifPresent (range -> rangeToStats .put (range , stats )));
28+ .forEach (stats -> {
29+ final String lowerEndpoint = cleanEndpointDecimal (stats .getLowerEndpoint ());
30+ final String upperEndpoint = cleanEndpointDecimal (stats .getUpperEndpoint ());
31+ parseFacetRange (lowerEndpoint , upperEndpoint )
32+ .ifPresent (range -> rangeToStats .put (range .toString (), stats ));
33+ });
2934 return rangeToStats ;
3035 }
3136
@@ -41,6 +46,7 @@ public static Optional<FacetRange<String>> parseFacetRange(@Nullable final Strin
4146
4247 /**
4348 * Parses a range of the form {@code (x to y)} to a {@link FilterRange}.
49+ * Ranges of the form {@code (* to *)} are not supported.
4450 * @param rangeAsString range of the form {@code (x to y)}
4551 * @return the {@link FilterRange} corresponding to that range, or empty if it could not be parsed
4652 */
@@ -55,11 +61,13 @@ public static Optional<FilterRange<String>> parseFilterRange(final String rangeA
5561 } else {
5662 return FilterRange .atMost (pair .getRight ());
5763 }
58- });
64+ })
65+ .filter (RangeUtils ::hasNoBounds );
5966 }
6067
6168 /**
6269 * Parses a range of the form {@code (x to y)} to a {@link FacetRange}.
70+ * Ranges of the form {@code (* to *)} are not supported.
6371 * @param rangeAsString range of the form {@code (x to y)}
6472 * @return the {@link FacetRange} corresponding to that range, or empty if it could not be parsed
6573 */
@@ -74,7 +82,8 @@ public static Optional<FacetRange<String>> parseFacetRange(final String rangeAsS
7482 } else {
7583 return FacetRange .lessThan (pair .getRight ());
7684 }
77- });
85+ })
86+ .filter (RangeUtils ::hasNoBounds );
7887 }
7988
8089 @ Nullable
@@ -89,17 +98,48 @@ private static Pair<String, String> parseRangeToPair(final String rangeAsString)
8998 }
9099
91100 private static String buildRange (@ Nullable final String lowerEndpoint , @ Nullable final String upperEndpoint ) {
92- return String .format ("(\" %s \" to \" %s \" )" ,
101+ return String .format ("(%s to %s )" ,
93102 boundEndpointOrAsterisk (lowerEndpoint ),
94103 boundEndpointOrAsterisk (upperEndpoint ));
95104 }
96105
97106 @ Nullable
98107 private static String boundEndpointOrNull (@ Nullable final String endpoint ) {
99- return endpoint == null || endpoint . equals ( "*" ) ? null : endpoint ;
108+ return isEndpointBoundless ( endpoint ) ? null : endpoint ;
100109 }
101110
102111 private static String boundEndpointOrAsterisk (@ Nullable final String endpoint ) {
103- return endpoint == null ? "*" : endpoint ;
112+ return isEndpointBoundless (endpoint ) ? "*" : endpoint ;
113+ }
114+
115+ private static boolean isEndpointBoundless (@ Nullable final String endpoint ) {
116+ return endpoint == null || endpoint .equals ("*" );
117+ }
118+
119+ private static <T extends Comparable <T >> boolean hasNoBounds (final FacetRange <T > range ) {
120+ return range .lowerBound () != null || range .upperBound () != null ;
121+ }
122+
123+ private static <T extends Comparable <T >> boolean hasNoBounds (final FilterRange <T > range ) {
124+ return range .lowerBound () != null || range .upperBound () != null ;
125+ }
126+
127+ /**
128+ * Cleans the decimal part of the endpoint value due to the backend answering with decimals but not accepting them.
129+ * For example, the backend might answer with 9002.0, but it needs to be converted to 9002.
130+ * @param endpointValue the value of the endpoint to be cleaned
131+ * @return the value of the endpoint without the decimal part, in case the value was a number
132+ */
133+ @ Nullable
134+ private static String cleanEndpointDecimal (@ Nullable final String endpointValue ) {
135+ if (endpointValue != null ) {
136+ try {
137+ final int value = new BigDecimal (endpointValue ).intValue ();
138+ return String .valueOf (value );
139+ } catch (NumberFormatException e ) {
140+ // Fallbacks to default case
141+ }
142+ }
143+ return endpointValue ;
104144 }
105145}
0 commit comments