protected <T extends BinaryLogicOperator> List<Filter> collect( T filter, Class<T> type, Object extraData, List<Filter> collected) { for (Filter child : filter.getChildren()) { if (type.isInstance(child)) { T and = (T) child; collect(and, type, extraData, collected); } else { Filter cloned = (Filter) child.accept(this, extraData); if (type.isInstance(cloned)) { T and = (T) cloned; collect(and, type, extraData, collected); } else { collected.add(cloned); } } } return collected; }
@Override public Object visit(And filter, Object extraData) { // drill down and flatten List<Filter> filters = collect(filter, And.class, extraData, new ArrayList<Filter>()); filters = basicAndSimplification(filters); filters = extraAndSimplification(extraData, filters); // we might end up with an empty list if (filters.size() == 0) { return Filter.INCLUDE; } // remove the logic we have only one filter if (filters.size() == 1) { return filters.get(0); } return getFactory(extraData).and(filters); }
@Override public Object visit(Or filter, Object extraData) { // scan, clone and simplify the children List<Filter> filters = collect(filter, Or.class, extraData, new ArrayList<Filter>()); filters = basicOrSimplification(filters); filters = extraOrSimplification(extraData, filters); // we might end up with an empty list if (filters.size() == 0) { return Filter.EXCLUDE; } // remove the logic we have only one filter if (filters.size() == 1) { return filters.get(0); } // else return the cloned and simplified up list return getFactory(extraData).or(filters); }