Refactoring and removing if null checks in chain filtering

281 views Asked by At

I'm doing some filtering on database entries and I ended up with somewhat ugly code, which I don't like.

I have my MyFilterResolverFactory class where I build and return my MyFilterResolver chain.

public abstract class MyFilterResolver {
    protected MyFilterResolver nextResolver = EMPTY;
    protected List<Predicate> predicates;

    public List<Predicate> resolve(MyFilter filter, CriteriaBuilder cb, Root<MyEntity> root) {
        this.predicates = new ArrayList<Predicate>();

        resolveFilter(filter, cb, root);

        this.predicates.addAll(this.nextResolver.resolve(filter, cb, root));
        return this.predicates;
    }

    protected abstract void resolveFilter(MyFilter filter, CriteriaBuilder cb, Root<MyEntity> root);

    public void attachNextResolver(MyFilterResolver nextResolver) {
        this.nextResolver = nextResolver;
    }

    public static MyFilterResolver EMPTY = new MyFilterResolver() {

        @Override
        public List<Predicate> resolve(MyFilter filter, CriteriaBuilder cb, Root<MyEntity> root) {
            return new ArrayList<Predicate>();
        }

        @Override
        protected void resolveFilter(MyFilter filter, CriteriaBuilder cb, Root<MyEntity> root) {
        }
    };
}

And an ugly, concrete implementation of it:

public class MyDateFilterResolver extends
    MyFilterResolver {

    @Override
    protected void resolveFilter(MyFilter filter, CriteriaBuilder cb,
        Root<MyEntity> root) {

        if (filter != null) {
            Date dateExact = filter.getDateExact();
            Date dateAfter = filter.getDateAfter();
            Date dateBefore = filter.getDateBefore();

            if (dateExact != null) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(dateExact);

                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);

                Date dayStart = calendar.getTime();

                calendar = Calendar.getInstance();
                calendar.setTime(dayStart);
                calendar.add(Calendar.DATE, 1);
                calendar.add(Calendar.MILLISECOND, -1);

                Date dayEnd = calendar.getTime();

                super.predicates.add(
                    cb.greaterThanOrEqualTo(
                        root.get("date").as(Date.class), 
                        dayStart
                    )
                );

                super.predicates.add(
                    cb.lessThanOrEqualTo(
                        root.get("date").as(Date.class), 
                        dayEnd
                    )
                );

            }

            if (dateAfter != null) {
                super.predicates.add(
                    cb.greaterThanOrEqualTo(
                        root.get("date").as(Date.class), 
                        dateAfter
                    )
                );
            }

            if (dateBefore != null) {
                predicates.add(
                    cb.lessThanOrEqualTo(
                        root.get("date").as(Date.class), 
                        dateBefore
                    )
                );
            }
        }
    }

}

MyFilter class is a regular POJO with getters/setters only.

I'd like to get rid of these if (something != null) checks, but I am not able to see how.

1

There are 1 answers

0
Michael Ford On

I don't see any reason to. A (poor) alternative would be to use one try/catch, but the if statements are more clear and better performing for the task in which they are used here.