Skip to content

Commit

Permalink
Add ability to sort mixed-type lists to JsonSlurper
Browse files Browse the repository at this point in the history
  • Loading branch information
cdeszaq committed Oct 6, 2016
1 parent bae3fb3 commit b3bd292
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ Current

- [#45, removing sorting from weight check queries](https://github.com/yahoo/fili/pull/46)

- `JsonSlurper` can now handle sorting lists with mixed-type entries, even if the list starts with a string, number, or
boolean

### Known Issues:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/*
* Changed HashMap to LinkedHashMap for consistency. Added ability to optionally sort the lists and maps.
*/

import static groovy.json.JsonTokenType.CLOSE_BRACKET;
import static groovy.json.JsonTokenType.CLOSE_CURLY;
import static groovy.json.JsonTokenType.COLON;
Expand Down Expand Up @@ -50,7 +51,7 @@
@SuppressWarnings({ "rawtypes", "javadoc", "unchecked" })
public class JsonSlurper {

private final Comparator<Map> mapComparator;
private final Comparator<Object> variableTypedComparator;

private final JsonSortStrategy sortStrategy;

Expand All @@ -71,17 +72,17 @@ public JsonSlurper() {
* @param sortStrategy Strategy to use when sorting the parsed JSON object
*/
public JsonSlurper(JsonSortStrategy sortStrategy) {
this(sortStrategy, new ToStringComparator<Map>());
this(sortStrategy, new ToStringComparator<>());
}

/**
* Create a new JsonSlurper with the given sort strategy and map comparator.
*
* @param sortStrategy Strategy to use when sorting the parsed JSON object
* @param mapComparator Comparator to use when sorting a list of maps
* @param variableTypedComparator Comparator to use when sorting a list with variable types
*/
public JsonSlurper(JsonSortStrategy sortStrategy, Comparator<Map> mapComparator) {
this.mapComparator = mapComparator;
public JsonSlurper(JsonSortStrategy sortStrategy, Comparator<Object> variableTypedComparator) {
this.variableTypedComparator = variableTypedComparator;
this.sortStrategy = sortStrategy;
switch (sortStrategy) {
case SORT_BOTH:
Expand All @@ -103,8 +104,8 @@ public JsonSlurper(JsonSortStrategy sortStrategy, Comparator<Map> mapComparator)
}
}

public Comparator<Map> getMapComparator() {
return mapComparator;
public Comparator<Object> getVariableTypedComparator() {
return variableTypedComparator;
}

public JsonSortStrategy getSortStrategy() {
Expand All @@ -126,11 +127,16 @@ public boolean getSortMaps() {
*/
private void sortIfNeeded(List listToSort) {
if (sortLists) {
// Sort by the native compareTo if available, otherwise just sort by hash code to ensure consistent sorting
if (listToSort.size() > 0 && listToSort.get(0) instanceof Comparable) {
Collections.sort(listToSort);
// Sort by the native compareTo, otherwise just sort by the object comparator to ensure consistent sorting
if (listToSort.stream().anyMatch(it -> it instanceof Comparable)) {
try {
Collections.sort(listToSort);
} catch (ClassCastException ignored) {
// Failed to sort a consistently typed list of Comparables. Fall back to the collection comparator
Collections.sort(listToSort, variableTypedComparator);
}
} else {
Collections.sort(listToSort, mapComparator);
Collections.sort(listToSort, variableTypedComparator);
}
}
}
Expand Down

0 comments on commit b3bd292

Please sign in to comment.