Fix conversion for boolean (and other types) for the jpa criteria
builder Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>
This commit is contained in:
@@ -27,6 +27,8 @@ import org.eclipse.hawkbit.repository.FieldNameProvider;
|
|||||||
import org.eclipse.hawkbit.repository.FieldValueConverter;
|
import org.eclipse.hawkbit.repository.FieldValueConverter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.SimpleTypeConverter;
|
||||||
|
import org.springframework.beans.TypeMismatchException;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
|
||||||
import cz.jirutka.rsql.parser.RSQLParser;
|
import cz.jirutka.rsql.parser.RSQLParser;
|
||||||
@@ -76,7 +78,6 @@ public final class RSQLUtility {
|
|||||||
* private constructor due utility class.
|
* private constructor due utility class.
|
||||||
*/
|
*/
|
||||||
private RSQLUtility() {
|
private RSQLUtility() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,11 +164,13 @@ public final class RSQLUtility {
|
|||||||
private final Root<T> root;
|
private final Root<T> root;
|
||||||
private final CriteriaBuilder cb;
|
private final CriteriaBuilder cb;
|
||||||
private final Class<A> enumType;
|
private final Class<A> enumType;
|
||||||
|
private final SimpleTypeConverter simpleTypeConverter;
|
||||||
|
|
||||||
private JpqQueryRSQLVisitor(final Root<T> root, final CriteriaBuilder cb, final Class<A> enumType) {
|
private JpqQueryRSQLVisitor(final Root<T> root, final CriteriaBuilder cb, final Class<A> enumType) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
this.cb = cb;
|
this.cb = cb;
|
||||||
this.enumType = enumType;
|
this.enumType = enumType;
|
||||||
|
this.simpleTypeConverter = new SimpleTypeConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -199,10 +202,8 @@ public final class RSQLUtility {
|
|||||||
validateMapParamter(propertyEnum, node, graph);
|
validateMapParamter(propertyEnum, node, graph);
|
||||||
|
|
||||||
// sub entity need minium 1 dot
|
// sub entity need minium 1 dot
|
||||||
if (!propertyEnum.getSubEntityAttributes().isEmpty()) {
|
if (!propertyEnum.getSubEntityAttributes().isEmpty() && graph.length < 2) {
|
||||||
if (graph.length < 2) {
|
throw createRSQLParameterUnsupportedException(node);
|
||||||
throw createRSQLParameterUnsupportedException(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < graph.length; i++) {
|
for (int i = 1; i < graph.length; i++) {
|
||||||
@@ -353,7 +354,12 @@ public final class RSQLUtility {
|
|||||||
return convertedValue;
|
return convertedValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
|
||||||
|
try {
|
||||||
|
return simpleTypeConverter.convertIfNecessary(value, javaType);
|
||||||
|
} catch (final TypeMismatchException e) {
|
||||||
|
throw new RSQLParameterSyntaxException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
@@ -377,7 +383,7 @@ public final class RSQLUtility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Predicate> mapToPredicate(final ComparisonNode node, Path<Object> fieldPath,
|
private List<Predicate> mapToPredicate(final ComparisonNode node, final Path<Object> fieldPath,
|
||||||
final List<String> values, final List<Object> transformedValues, final A enumField) {
|
final List<String> values, final List<Object> transformedValues, final A enumField) {
|
||||||
// only 'equal' and 'notEqual' can handle transformed value like
|
// only 'equal' and 'notEqual' can handle transformed value like
|
||||||
// enums. The JPA API
|
// enums. The JPA API
|
||||||
@@ -391,29 +397,38 @@ public final class RSQLUtility {
|
|||||||
singleList.add(mapPredicate);
|
singleList.add(mapPredicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldPath = getMapValueFieldPath(enumField, fieldPath);
|
final Path<Object> mappedFieldPath = getMapValueFieldPath(enumField, fieldPath);
|
||||||
|
|
||||||
|
addPredicateByOperator(node, fieldPath, transformedValues, transformedValue, value, singleList,
|
||||||
|
mappedFieldPath);
|
||||||
|
return Collections.unmodifiableList(singleList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPredicateByOperator(final ComparisonNode node, final Path<Object> fieldPath,
|
||||||
|
final List<Object> transformedValues, final Object transformedValue, final String value,
|
||||||
|
final List<Predicate> singleList, final Path<Object> mappedFieldPath) {
|
||||||
switch (node.getOperator().getSymbol()) {
|
switch (node.getOperator().getSymbol()) {
|
||||||
case "=li=":
|
case "=li=":
|
||||||
singleList.add(cb.like(cb.upper(pathOfString(fieldPath)), transformedValue.toString().toUpperCase()));
|
singleList.add(
|
||||||
|
cb.like(cb.upper(pathOfString(mappedFieldPath)), transformedValue.toString().toUpperCase()));
|
||||||
break;
|
break;
|
||||||
case "==":
|
case "==":
|
||||||
singleList.add(getEqualToPredicate(transformedValue, fieldPath));
|
singleList.add(getEqualToPredicate(transformedValue, mappedFieldPath));
|
||||||
break;
|
break;
|
||||||
case "!=":
|
case "!=":
|
||||||
singleList.add(cb.notEqual(fieldPath, transformedValue));
|
singleList.add(cb.notEqual(mappedFieldPath, transformedValue));
|
||||||
break;
|
break;
|
||||||
case "=gt=":
|
case "=gt=":
|
||||||
singleList.add(cb.greaterThan(pathOfString(fieldPath), value));
|
singleList.add(cb.greaterThan(pathOfString(mappedFieldPath), value));
|
||||||
break;
|
break;
|
||||||
case "=ge=":
|
case "=ge=":
|
||||||
singleList.add(cb.greaterThanOrEqualTo(pathOfString(fieldPath), value));
|
singleList.add(cb.greaterThanOrEqualTo(pathOfString(mappedFieldPath), value));
|
||||||
break;
|
break;
|
||||||
case "=lt=":
|
case "=lt=":
|
||||||
singleList.add(cb.lessThan(pathOfString(fieldPath), value));
|
singleList.add(cb.lessThan(pathOfString(mappedFieldPath), value));
|
||||||
break;
|
break;
|
||||||
case "=le=":
|
case "=le=":
|
||||||
singleList.add(cb.lessThanOrEqualTo(pathOfString(fieldPath), value));
|
singleList.add(cb.lessThanOrEqualTo(pathOfString(mappedFieldPath), value));
|
||||||
break;
|
break;
|
||||||
case "=in=":
|
case "=in=":
|
||||||
singleList.add(fieldPath.in(transformedValues));
|
singleList.add(fieldPath.in(transformedValues));
|
||||||
@@ -424,13 +439,8 @@ public final class RSQLUtility {
|
|||||||
default:
|
default:
|
||||||
LOGGER.info("operator symbol {} is either not supported or not implemented");
|
LOGGER.info("operator symbol {} is either not supported or not implemented");
|
||||||
}
|
}
|
||||||
return Collections.unmodifiableList(singleList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param enumField
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Path<Object> getMapValueFieldPath(final A enumField, final Path<Object> fieldPath) {
|
private Path<Object> getMapValueFieldPath(final A enumField, final Path<Object> fieldPath) {
|
||||||
if (!enumField.isMap() || enumField.getValueFieldName() == null) {
|
if (!enumField.isMap() || enumField.getValueFieldName() == null) {
|
||||||
return fieldPath;
|
return fieldPath;
|
||||||
@@ -446,7 +456,7 @@ public final class RSQLUtility {
|
|||||||
final String[] graph = node.getSelector().split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
|
final String[] graph = node.getSelector().split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
|
||||||
final String keyValue = graph[graph.length - 1];
|
final String keyValue = graph[graph.length - 1];
|
||||||
if (fieldPath instanceof MapJoin) {
|
if (fieldPath instanceof MapJoin) {
|
||||||
return cb.equal(((MapJoin) fieldPath).key(), keyValue);
|
return cb.equal(((MapJoin<?, ?, ?>) fieldPath).key(), keyValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cb.equal(fieldPath.get(enumField.getKeyFieldName()), keyValue);
|
return cb.equal(fieldPath.get(enumField.getKeyFieldName()), keyValue);
|
||||||
@@ -455,7 +465,7 @@ public final class RSQLUtility {
|
|||||||
private Predicate getEqualToPredicate(final Object transformedValue, final Path<Object> fieldPath) {
|
private Predicate getEqualToPredicate(final Object transformedValue, final Path<Object> fieldPath) {
|
||||||
if (transformedValue instanceof String) {
|
if (transformedValue instanceof String) {
|
||||||
final String preFormattedValue = ((String) transformedValue).replace(LIKE_WILDCARD, '%');
|
final String preFormattedValue = ((String) transformedValue).replace(LIKE_WILDCARD, '%');
|
||||||
return cb.like(cb.upper(pathOfString(fieldPath)), preFormattedValue.toString().toUpperCase());
|
return cb.like(cb.upper(pathOfString(fieldPath)), preFormattedValue.toUpperCase());
|
||||||
}
|
}
|
||||||
return cb.equal(fieldPath, transformedValue);
|
return cb.equal(fieldPath, transformedValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.rsql;
|
package org.eclipse.hawkbit.repository.rsql;
|
||||||
|
|
||||||
import static org.fest.assertions.api.Assertions.assertThat;
|
import static org.fest.assertions.api.Assertions.assertThat;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -94,7 +95,12 @@ public class RSQLDistributionSetFieldTest extends AbstractIntegrationTest {
|
|||||||
@Description("Test filter distribution set by complete property")
|
@Description("Test filter distribution set by complete property")
|
||||||
public void testFilterByAttribute() {
|
public void testFilterByAttribute() {
|
||||||
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "==true", 4);
|
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "==true", 4);
|
||||||
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "==noExist*", 0);
|
try {
|
||||||
|
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "==noExist*", 0);
|
||||||
|
fail();
|
||||||
|
} catch (final RSQLParameterSyntaxException e) {
|
||||||
|
// excepted
|
||||||
|
}
|
||||||
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "=in=(true)", 4);
|
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "=in=(true)", 4);
|
||||||
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "=out=(true)", 0);
|
assertRSQLQuery(DistributionSetFields.COMPLETE.name() + "=out=(true)", 0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user