package io.ebeaninternal.server.el;
import io.ebean.Filter;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
public final class ElFilter<T> implements Filter<T> {
private final BeanDescriptor<T> beanDescriptor;
private final ArrayList<ElMatcher<T>> matches = new ArrayList<>();
private int maxRows;
private String sortByClause;
public ElFilter(BeanDescriptor<T> beanDescriptor) {
this.beanDescriptor = beanDescriptor;
}
private Object convertValue(String propertyName, Object value) {
ElPropertyValue elGetValue = beanDescriptor.getElGetValue(propertyName);
return elGetValue.convert(value);
}
private ElComparator<T> getElComparator(String propertyName) {
return beanDescriptor.getElComparator(propertyName);
}
private ElPropertyValue getElGetValue(String propertyName) {
return beanDescriptor.getElGetValue(propertyName);
}
@Override
public Filter<T> sort(String sortByClause) {
this.sortByClause = sortByClause;
return this;
}
protected boolean isMatch(T bean) {
for (ElMatcher<T> matcher : matches) {
if (!matcher.isMatch(bean)) {
return false;
}
}
return true;
}
@Override
public Filter<T> in(String propertyName, Set<?> matchingValues) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.InSet<>(matchingValues, elGetValue));
return this;
}
@Override
public Filter<T> eq(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Eq<>(value, comparator));
return this;
}
@Override
public Filter<T> ne(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Ne<>(value, comparator));
return this;
}
@Override
public Filter<T> between(String propertyName, Object min, Object max) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
min = elGetValue.convert(min);
max = elGetValue.convert(max);
ElComparator<T> elComparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Between<>(min, max, elComparator));
return this;
}
@Override
public Filter<T> gt(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Gt<>(value, comparator));
return this;
}
@Override
public Filter<T> ge(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Ge<>(value, comparator));
return this;
}
@Override
public Filter<T> ieq(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.Ieq<>(elGetValue, value));
return this;
}
@Override
public Filter<T> isNotNull(String propertyName) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.IsNotNull<>(elGetValue));
return this;
}
@Override
public Filter<T> isNull(String propertyName) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.IsNull<>(elGetValue));
return this;
}
@Override
public Filter<T> le(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Le<>(value, comparator));
return this;
}
@Override
public Filter<T> lt(String propertyName, Object value) {
value = convertValue(propertyName, value);
ElComparator<T> comparator = getElComparator(propertyName);
matches.add(new ElMatchBuilder.Lt<>(value, comparator));
return this;
}
public Filter<T> regex(String propertyName, String regEx) {
return regex(propertyName, regEx, 0);
}
public Filter<T> regex(String propertyName, String regEx, int options) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.RegularExpr<>(elGetValue, regEx, options));
return this;
}
@Override
public Filter<T> contains(String propertyName, String value) {
String quote = ".*" + Pattern.quote(value) + ".*";
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.RegularExpr<>(elGetValue, quote, 0));
return this;
}
@Override
public Filter<T> icontains(String propertyName, String value) {
String quote = ".*" + Pattern.quote(value) + ".*";
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.RegularExpr<>(elGetValue, quote, Pattern.CASE_INSENSITIVE));
return this;
}
@Override
public Filter<T> endsWith(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.EndsWith<>(elGetValue, value));
return this;
}
@Override
public Filter<T> startsWith(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.StartsWith<>(elGetValue, value));
return this;
}
@Override
public Filter<T> iendsWith(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.IEndsWith<>(elGetValue, value));
return this;
}
@Override
public Filter<T> istartsWith(String propertyName, String value) {
ElPropertyValue elGetValue = getElGetValue(propertyName);
matches.add(new ElMatchBuilder.IStartsWith<>(elGetValue, value));
return this;
}
@Override
public Filter<T> maxRows(int maxRows) {
this.maxRows = maxRows;
return this;
}
@Override
public List<T> filter(List<T> list) {
if (sortByClause != null) {
list = new ArrayList<>(list);
beanDescriptor.sort(list, sortByClause);
}
ArrayList<T> filterList = new ArrayList<>();
for (T t : list) {
if (isMatch(t)) {
filterList.add(t);
if (maxRows > 0 && filterList.size() >= maxRows) {
break;
}
}
}
return filterList;
}
}