Skip to content

Instantly share code, notes, and snippets.

@mhewedy
Created January 30, 2026 22:27
Show Gist options
  • Select an option

  • Save mhewedy/5666cb93adf212673c375542189184a7 to your computer and use it in GitHub Desktop.

Select an option

Save mhewedy/5666cb93adf212673c375542189184a7 to your computer and use it in GitHub Desktop.
import com.github.mhewedy.expressions.Expression;
import com.github.mhewedy.expressions.Expressions;
import com.github.mhewedy.expressions.Operator;
import org.springframework.data.domain.*;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.github.mhewedy.expressions.Expressions.Field;
public class SearchUtil {
public static Pageable sortById(Pageable pageable, boolean override) {
return sortBy(pageable, "id", override);
}
public static Pageable sortBy(Pageable pageable, String field, boolean override) {
if (override || pageable.getSort().isUnsorted()) {
return PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(field));
} else {
return pageable;
}
}
public static <T> Page<T> listToPage(List<T> list, Pageable pageable) {
int pageSize = Math.min(pageable.getPageSize(), list.size());
int fromIndex = pageable.getPageNumber() * pageSize;
var subList = list.subList(fromIndex, Math.min(fromIndex + pageSize, list.size()));
return new PageImpl<>(subList, pageable, list.size());
}
public static void checkAllowedFields(Expressions expressions, String... allowedFields) {
Set<String> exprFields = expressions.extractFields().stream().map(Field::name).collect(Collectors.toSet());
Set<String> allowedFieldsSet = new HashSet<>(Arrays.asList(allowedFields));
if (!allowedFieldsSet.containsAll(exprFields)) {
throw new IllegalArgumentException("expression.contains.disallowed.fields");
}
}
public static void checkAllowedOperators(Expressions expressions, Operator... allowedOperator) {
Set<Operator> exprFields = expressions.extractFields().stream().map(Field::operator).collect(Collectors.toSet());
Set<Operator> allowedFieldsSet = new HashSet<>(Arrays.asList(allowedOperator));
if (!allowedFieldsSet.containsAll(exprFields)) {
throw new IllegalArgumentException("expression.contains.disallowed.operator");
}
}
public static Optional<Field> findField(Expressions expressions, String field) {
return expressions.extractFields().stream().filter(it -> it.name().equals(field)).findFirst();
}
public static void replaceField(Expressions expressions, String fieldName, Function<Field, Expression> expressionFn) {
SearchUtil.findField(expressions, fieldName).ifPresent(field -> {
SearchUtil.removeField(expressions, field.name());
Expression expression = expressionFn.apply(field);
if (expression != null) {
expressions.and(expression);
}
});
}
/**
* Recursively removes all occurrences of a key from a nested Map structure
* and removes empty parents all the way up.
*
* @param expressions The map to search through
* @param field The key to remove
* @return true if the map is empty after removals, false otherwise
*/
public static boolean removeField(Map<String, Object> expressions, String field) {
Iterator<Map.Entry<String, Object>> iterator = expressions.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
// Check if this is the key we want to remove
if (entry.getKey().equals(field)) {
iterator.remove();
continue;
}
Object value = entry.getValue();
// Recurse into nested map
if (value instanceof Map<?, ?> map) {
@SuppressWarnings("unchecked")
Map<String, Object> nestedMap = (Map<String, Object>) map;
boolean isEmpty = removeField(nestedMap, field);
if (isEmpty) {
iterator.remove();
}
}
// Recurse into collections
else if (value instanceof Collection<?> collection) {
removeFromCollection(collection, field);
if (collection.isEmpty() || isCollectionEmpty(collection)) {
iterator.remove();
}
}
}
return expressions.isEmpty();
}
private static void removeFromCollection(Collection<?> collection, String field) {
Iterator<?> iterator = collection.iterator();
while (iterator.hasNext()) {
Object item = iterator.next();
if (item instanceof Map<?, ?> map) {
@SuppressWarnings("unchecked")
Map<String, Object> nestedMap = (Map<String, Object>) map;
boolean isEmpty = removeField(nestedMap, field);
if (isEmpty) {
iterator.remove();
}
}
}
}
/**
* Checks if a collection is empty or contains only empty maps
*/
private static boolean isCollectionEmpty(Collection<?> collection) {
for (Object item : collection) {
if (item instanceof Map<?, ?> map) {
if (!map.isEmpty()) {
return false;
}
} else {
return false;
}
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment