Add some sanity checks when creating sort comparators (#1538)

This commit is contained in:
Roland Praml
2018-11-13 20:55:09 +13:00
committed by Rob Bygrave
parent cfba4d2deb
commit ec24374d72
4 changed files with 43 additions and 0 deletions
@@ -61,6 +61,7 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyLists;
import io.ebeaninternal.server.el.ElComparator;
import io.ebeaninternal.server.el.ElComparatorCompound;
import io.ebeaninternal.server.el.ElComparatorNoop;
import io.ebeaninternal.server.el.ElComparatorProperty;
import io.ebeaninternal.server.el.ElPropertyChainBuilder;
import io.ebeaninternal.server.el.ElPropertyDeploy;
@@ -2443,7 +2444,15 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
private ElComparator<T> createPropertyComparator(SortByClause.Property sortProp) {
ElPropertyValue elGetValue = getElGetValue(sortProp.getName());
if (elGetValue == null) {
logger.error("Sort property [" + sortProp + "] not found in " + beanType + ". Cannot sort.");
return new ElComparatorNoop<>();
}
if (elGetValue.isAssocMany()) {
logger.error("Sort property [" + sortProp + "] in " + beanType + " is a many-property. Cannot sort.");
return new ElComparatorNoop<>();
}
Boolean nullsHigh = sortProp.getNullsHigh();
if (nullsHigh == null) {
nullsHigh = Boolean.TRUE;
@@ -0,0 +1,23 @@
package io.ebeaninternal.server.el;
/**
* Comparator with no operation for unsortable properties.
*
* @author Roland Praml, FOCONIS AG
*
*/
public class ElComparatorNoop<T> implements ElComparator<T> {
private static final long serialVersionUID = -9060871822183687180L;
@Override
public int compare(T o1, T o2) {
return 0;
}
@Override
public int compareValue(Object value, T o2) {
return 0;
}
}
@@ -2,6 +2,8 @@ package io.ebeaninternal.server.el;
import java.util.Comparator;
import io.ebean.bean.EntityBean;
/**
* Comparator based on a ElGetValue.
*/
@@ -42,9 +44,15 @@ public final class ElComparatorProperty<T> implements Comparator<T>, ElComparato
if (val1 == null) {
return val2 == null ? 0 : nullOrder;
}
if (elGetValue.isAssocId()) {
val1 = elGetValue.getAssocIdValues((EntityBean) val1)[0]; // TODO: compound key not yet supported
}
if (val2 == null) {
return -1 * nullOrder;
}
if (elGetValue.isAssocId()) {
val2 = elGetValue.getAssocIdValues((EntityBean) val2)[0];
}
Comparable c = (Comparable) val1;
return asc * c.compareTo(val2);
}
@@ -266,6 +266,9 @@ public class ElPropertyChain implements ElPropertyValue {
@Override
public Object pathGet(Object bean) {
for (ElPropertyValue aChain : chain) {
if (aChain.isAssocMany()) {
throw new UnsupportedOperationException("pathGet not supported on [" + expression + "], because " + aChain + " is an assocMany property");
}
bean = aChain.pathGet(bean);
if (bean == null) {
return null;