Uses predicates to validate search parameters
I have a validate() method to check the parameters passed in the rest url.
The parameters are linked to the following model classes
class SearchCriteria {
String regno;
String hostid;
String domid;
String location;
String provider;
/*Getters and Setters*/
}
I have a utility class to check if the parameters are set.
public class SearchCriteriaUtil {
public static boolean isRegnoSet(SearchCriteria criteria) {
return null != criteria.getRegno();
}
public static boolean isHostIdSet(SearchCriteria criteria) {
return null != criteria.getHostId();
}
/* Similarly for domid, location, provider */
}
I have a predicate that tests against the conditions provided in util and generates a truth string
public class ParameterPredicate<T> implements Predicate<T>{
final Predicate<T> predicate;
final String sequence;
public ParameterPredicate(Predicate<T> predicate, String sequence) {
this.predicate = predicate;
this.sequence = sequence;
}
@Override
public String toString() {
return sequence;
}
@Override
public boolean test(T t) {
return predicate.test(t);
}
}
Now, based on the parameter set/notset,
regno -set, hostid -set, domid – notset, location – notset, provider – set
My predicate should be evaluated against the condition in SearchCriteriaUtil with the sequence set to the appropriate truth value… In this case,
“T T F F T”
In my verification method,
public void validateCriteria(SearchCriteria criteria) {
List<Predicate<SearchCriteria>> SearchCriteriaPredicate = Arrays.asList(SearchCriteriaUtil::isRegnoSet, SearchCriteriaUtil::isHostIdSet,
SearchCriteriaUtil::isDomidSet,
SearchCriteriaUtil::isLocationSet,
SearchCriteriaUtil::isProviderSet,
Collection<String> desired = Arrays.asList("T F F F F", "T F T T F", "T F T T F", "T F F F T", "T F F F T", "F T F F F");
I
can’t go beyond that, I have to set the sequence and check if it exists in the desired truth list.
I was referring to previous posts: Filtering with truth tables
Since I’m new to Java 8, any help is greatly appreciated.
Solution
Instead of using the util class and processing strings to check if a combination of conditions is valid, add the following to the SearchCriteria
class
public boolean hasDesiredCombination() {
return Criterion.DESIRED_COMBINATONS.contains(
Arrays.stream(Criterion.values())
.filter(s -> s.predicate.test(this))
.collect(Collectors.toCollection(
() -> EnumSet.noneOf(Criterion.class)))
);
}
private static enum Criterion {
REGNO(s -> s.regno != null),
HOSTID(s -> s.hostid != null),
DOMID(s -> s.domid != null),
LOCATION(s -> s.location != null),
PROVIDER(s -> s.provider != null);
private static Set<Set<Criterion>> DESIRED_COMBINATONS =
new HashSet<>(Arrays.asList(
EnumSet.of(REGNO),
EnumSet.of(REGNO, DOMID, LOCATION),
EnumSet.of(REGNO, PROVIDER),
EnumSet.of(HOSTID)
));
private Predicate<SearchCriteria> predicate;
private Criterion(Predicate<SearchCriteria> predicate) {
this.predicate = predicate;
}
}
Pros:
- You don’t have to expose getters and setters
- It is immediately clear from the source code which combinations are needed
- The logic is where it belongs: (indirectly) in the
SearchCriteria
class