io.katharsis.jpa.internal.query.QuerySortBuilder Maven / Gradle / Ivy
package io.katharsis.jpa.internal.query;
import java.util.ArrayList;
import java.util.List;
import io.katharsis.jpa.internal.meta.MetaAttribute;
import io.katharsis.jpa.internal.meta.MetaAttributePath;
import io.katharsis.jpa.internal.meta.MetaDataObject;
import io.katharsis.jpa.internal.meta.MetaKey;
import io.katharsis.jpa.internal.meta.MetaMapType;
import io.katharsis.jpa.internal.meta.MetaType;
import io.katharsis.jpa.internal.query.backend.JpaQueryBackend;
import io.katharsis.jpa.query.AnyTypeObject;
import io.katharsis.queryspec.Direction;
import io.katharsis.queryspec.SortSpec;
public class QuerySortBuilder {
protected JpaQueryBackend, O, ?, E> backend;
protected AbstractJpaQueryImpl query;
public QuerySortBuilder(AbstractJpaQueryImpl query, JpaQueryBackend, O, ?, E> backend) {
this.backend = backend;
this.query = query;
}
public void applySortSpec() {
List sortSpecs = query.getSortSpecs();
if (!sortSpecs.isEmpty()) {
backend.setOrder(sortSpecListToArray());
}
// ensure a total order, add primary key if necessary necssary
if (query.getEnsureTotalOrder() && !QueryUtil.hasTotalOrder(query.getMeta(), sortSpecs)) {
List totalOrderList = backend.getOrderList();
MetaKey primaryKey = query.getMeta().getPrimaryKey();
if (primaryKey != null) {
for (MetaAttribute primaryKeyElem : primaryKey.getElements()) {
E primaryKeyExpr = backend.getAttribute(new MetaAttributePath(primaryKeyElem));
O primaryKeyElemOrder = backend.newSort(primaryKeyExpr, Direction.ASC);
totalOrderList.add(primaryKeyElemOrder);
}
}
backend.setOrder(totalOrderList);
}
}
protected List sortSpecListToArray() {
ArrayList orderList = new ArrayList<>();
for (SortSpec sortSpec : query.getSortSpecs()) {
orderList.addAll(sortSpecToOrder(sortSpec));
}
return orderList;
}
private List sortSpecToOrder(SortSpec sortSpec) {
List orders = new ArrayList<>();
// check for AnyType
MetaAttributePath path = query.getMeta().resolvePath(sortSpec.getAttributePath(), true);
MetaAttribute attr = path.getLast();
MetaType valueType = attr.getType();
if (valueType instanceof MetaMapType) {
valueType = ((MetaMapType) valueType).getValueType();
}
boolean anyType = AnyTypeObject.class.isAssignableFrom(valueType.getImplementationClass());
if (anyType) {
// order by anything, if types are not mixed for a given key, it
// will be ok
MetaDataObject anyMeta = valueType.asDataObject();
for (MetaAttribute anyAttr : anyMeta.getAttributes()) {
if (!anyAttr.isDerived()) {
E expr = backend.getAttribute(path.concat(anyAttr));
orders.add(backend.newSort(expr, sortSpec.getDirection()));
}
}
} else {
E expr = backend.getAttribute(path);
orders.add(backend.newSort(expr, sortSpec.getDirection()));
}
return orders;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy