Merge pull request #9 from bsinno/MECS-1438_CREATE_FILTER_OPTIONS_FOR_MAP

ok
This commit is contained in:
Kai Zimmermann
2016-01-26 11:35:53 +01:00
14 changed files with 466 additions and 284 deletions

View File

@@ -205,8 +205,7 @@ public class TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
public Slice<Target> findTargetsAll(@NotNull final TargetFilterQuery targetFilterQuery,
@NotNull final Pageable pageable) {
return findTargetsAll(RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, entityManager),
pageable);
return findTargetsAll(RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class), pageable);
}
/**
@@ -220,7 +219,7 @@ public class TargetManagement {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
public Slice<Target> findTargetsAll(@NotNull final String targetFilterQuery, @NotNull final Pageable pageable) {
return findTargetsAll(RSQLUtility.parse(targetFilterQuery, TargetFields.class, entityManager), pageable);
return findTargetsAll(RSQLUtility.parse(targetFilterQuery, TargetFields.class), pageable);
}
/**
@@ -351,9 +350,9 @@ public class TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
public Page<Target> findTargetByAssignedDistributionSet(@NotNull final Long distributionSetID,
final Specification<Target> spec, @NotNull final Pageable pageReq) {
return targetRepository.findAll((Specification<Target>) (root, query, cb) -> cb.and(
TargetSpecifications.hasAssignedDistributionSet(distributionSetID).toPredicate(root, query, cb),
spec.toPredicate(root, query, cb)), pageReq);
return targetRepository.findAll((Specification<Target>) (root, query, cb) -> cb.and(TargetSpecifications
.hasAssignedDistributionSet(distributionSetID).toPredicate(root, query, cb), spec.toPredicate(root,
query, cb)), pageReq);
}
/**
@@ -390,9 +389,9 @@ public class TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
public Page<Target> findTargetByInstalledDistributionSet(final Long distributionSetId,
final Specification<Target> spec, final Pageable pageable) {
return targetRepository.findAll((Specification<Target>) (root, query, cb) -> cb.and(
TargetSpecifications.hasInstalledDistributionSet(distributionSetId).toPredicate(root, query, cb),
spec.toPredicate(root, query, cb)), pageable);
return targetRepository.findAll((Specification<Target>) (root, query, cb) -> cb.and(TargetSpecifications
.hasInstalledDistributionSet(distributionSetId).toPredicate(root, query, cb), spec.toPredicate(root,
query, cb)), pageable);
}
/**
@@ -487,8 +486,8 @@ public class TargetManagement {
specList.add(TargetSpecifications.hasTargetUpdateStatus(status, fetch));
}
if (installedOrAssignedDistributionSetId != null) {
specList.add(
TargetSpecifications.hasInstalledOrAssignedDistributionSet(installedOrAssignedDistributionSetId));
specList.add(TargetSpecifications
.hasInstalledOrAssignedDistributionSet(installedOrAssignedDistributionSetId));
}
if (!Strings.isNullOrEmpty(searchText)) {
specList.add(TargetSpecifications.likeNameOrDescriptionOrIp(searchText));
@@ -560,8 +559,8 @@ public class TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
public TargetTagAssigmentResult toggleTagAssignment(@NotEmpty final List<Target> targets,
@NotNull final TargetTag tag) {
return toggleTagAssignment(
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()), tag.getName());
return toggleTagAssignment(targets.stream().map(target -> target.getControllerId())
.collect(Collectors.toList()), tag.getName());
}
/**
@@ -584,8 +583,8 @@ public class TargetManagement {
@NotNull final String tagName) {
final TargetTag tag = targetTagRepository.findByNameEquals(tagName);
final List<Target> alreadyAssignedTargets = targetRepository.findByTagNameAndControllerIdIn(tagName, targetIds);
final List<Target> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds));
final List<Target> allTargets = targetRepository.findAll(TargetSpecifications
.byControllerIdWithStatusAndTagsInJoin(targetIds));
// all are already assigned -> unassign
if (alreadyAssignedTargets.size() == allTargets.size()) {
@@ -741,20 +740,19 @@ public class TargetManagement {
// select case expression to retrieve the case value as a column to be
// able to order based on
// this column, installed first,...
final Expression<Object> selectCase = cb.selectCase()
final Expression<Object> selectCase = cb
.selectCase()
.when(cb.equal(targetInfo.get(TargetInfo_.installedDistributionSet).get(DistributionSet_.id),
orderByDistributionId), 1)
.when(cb.equal(targetRoot.get(Target_.assignedDistributionSet).get(DistributionSet_.id),
orderByDistributionId), 2)
.otherwise(100);
orderByDistributionId), 2).otherwise(100);
// multiselect statement order by the select case and controllerId
query.distinct(true);
// build the specifications and then to predicates necessary by the
// given filters
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
buildSpecificationList(filterByStatus, filterBySearchText, filterByDistributionId,
selectTargetWithNoTag, true, filterByTagNames),
targetRoot, query, cb);
selectTargetWithNoTag, true, filterByTagNames), targetRoot, query, cb);
// if we have some predicates then add it to the where clause of the
// multiselect
@@ -828,8 +826,9 @@ public class TargetManagement {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<TargetIdName> query = cb.createQuery(TargetIdName.class);
final Root<Target> targetRoot = query.from(Target.class);
return entityManager.createQuery(query.multiselect(targetRoot.get(Target_.id),
targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name))).getResultList();
return entityManager.createQuery(
query.multiselect(targetRoot.get(Target_.id), targetRoot.get(Target_.controllerId),
targetRoot.get(Target_.name))).getResultList();
}
@@ -871,8 +870,7 @@ public class TargetManagement {
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
buildSpecificationList(filterByStatus, filterBySearchText, filterByDistributionId,
selectTargetWithNoTag, false, filterByTagNames),
targetRoot, multiselect, cb);
selectTargetWithNoTag, false, filterByTagNames), targetRoot, multiselect, cb);
// if we have some predicates then add it to the where clause of the
// multiselect
@@ -905,8 +903,7 @@ public class TargetManagement {
targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name),
targetRoot.get(pageRequest.getSort().iterator().next().getProperty()));
final Specification<Target> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
entityManager);
final Specification<Target> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
final List<Specification<Target>> specList = new ArrayList<>();
specList.add(spec);
@@ -1003,17 +1000,16 @@ public class TargetManagement {
* to be created.
* @return the created {@link Target}s
*
* @throws {@link
* EntityAlreadyExistsException} of one of the given targets
* already exist.
* @throws {@link EntityAlreadyExistsException} of one of the given targets
* already exist.
*/
@Modifying
@Transactional
@NotNull
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
public List<Target> createTargets(@NotNull final List<Target> targets) {
if (targetRepository.countByControllerIdIn(
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) > 0) {
if (targetRepository.countByControllerIdIn(targets.stream().map(target -> target.getControllerId())
.collect(Collectors.toList())) > 0) {
throw new EntityAlreadyExistsException();
}
final List<Target> savedTargets = new ArrayList<>();
@@ -1045,8 +1041,8 @@ public class TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
public List<Target> createTargets(@NotNull final Collection<Target> targets,
@NotNull final TargetUpdateStatus status, final long lastTargetQuery, final URI address) {
if (targetRepository.countByControllerIdIn(
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) > 0) {
if (targetRepository.countByControllerIdIn(targets.stream().map(target -> target.getControllerId())
.collect(Collectors.toList())) > 0) {
throw new EntityAlreadyExistsException();
}
final List<Target> savedTargets = new ArrayList<>();
@@ -1080,8 +1076,7 @@ public class TargetManagement {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
public Long countTargetByTargetFilterQuery(@NotNull final TargetFilterQuery targetFilterQuery) {
final Specification<Target> specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
entityManager);
final Specification<Target> specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
return targetRepository.count(specs);
}
@@ -1094,7 +1089,7 @@ public class TargetManagement {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
public Long countTargetByTargetFilterQuery(@NotNull final String targetFilterQuery) {
final Specification<Target> specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class, entityManager);
final Specification<Target> specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class);
return targetRepository.count(specs);
}

View File

@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository.rsql;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -19,18 +18,13 @@ import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.Attribute.PersistentAttributeType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.PluralAttribute;
import org.eclipse.hawkbit.repository.FieldNameProvider;
import org.eclipse.hawkbit.repository.FieldValueConverter;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.jpa.domain.Specification;
@@ -104,20 +98,18 @@ public final class RSQLUtility {
* if the RSQL syntax is wrong
*/
public static <A extends Enum<A> & FieldNameProvider, T> Specification<T> parse(final String rsql,
final Class<A> fieldNameProvider, final EntityManager entityManager) {
return new RSQLSpecification<>(rsql, fieldNameProvider, entityManager);
final Class<A> fieldNameProvider) {
return new RSQLSpecification<>(rsql, fieldNameProvider);
}
private static final class RSQLSpecification<A extends Enum<A> & FieldNameProvider, T> implements Specification<T> {
private final String rsql;
private final Class<A> enumType;
private final EntityManager entityManager;
private RSQLSpecification(final String rsql, final Class<A> enumType, final EntityManager entityManager) {
private RSQLSpecification(final String rsql, final Class<A> enumType) {
this.rsql = rsql;
this.enumType = enumType;
this.entityManager = entityManager;
}
/*
@@ -141,8 +133,7 @@ public final class RSQLUtility {
throw new RSQLParameterSyntaxException(e);
}
final JpqQueryRSQLVisitor<A, T> jpqQueryRSQLVisitor = new JpqQueryRSQLVisitor<>(root, cb, enumType,
entityManager);
final JpqQueryRSQLVisitor<A, T> jpqQueryRSQLVisitor = new JpqQueryRSQLVisitor<>(root, cb, enumType);
final List<Predicate> accept = rootNode.<List<Predicate>, String> accept(jpqQueryRSQLVisitor);
if (accept != null && !accept.isEmpty()) {
@@ -169,36 +160,14 @@ public final class RSQLUtility {
RSQLVisitor<List<Predicate>, String> {
public static final Character LIKE_WILDCARD = '*';
static {
/**
* Property mapping are done in FieldNameProvider like
* TargetFields,SoftwareModuleFields etc.
*
* In addition to this mapping in PropertyMapper are done if we want
* to drill down on entity .
*
* For example : Drill down on distribution set of target entity are
* done by adding the mappings in PropertyMapper as below.
*
* User can now use assignedds.name and assignedds.version
*
*/
PropertyMapper.addNewMapping(Target.class, "assignedds", "assignedDistributionSet");
PropertyMapper.addNewMapping(DistributionSet.class, "name", "name");
PropertyMapper.addNewMapping(DistributionSet.class, "version", "version");
}
private final Root<T> root;
private final CriteriaBuilder cb;
private final Class<A> enumType;
private final EntityManager entityManager;
private JpqQueryRSQLVisitor(final Root<T> root, final CriteriaBuilder cb, final Class<A> enumType,
final EntityManager entityManager) {
private JpqQueryRSQLVisitor(final Root<T> root, final CriteriaBuilder cb, final Class<A> enumType) {
this.root = root;
this.cb = cb;
this.enumType = enumType;
this.entityManager = entityManager;
}
@Override
@@ -219,134 +188,146 @@ public final class RSQLUtility {
return toSingleList(cb.conjunction());
}
private static <T> boolean isItAssociationType(final String property, final ManagedType<T> classMetadata) {
return classMetadata.getAttribute(property).isAssociation();
private List<Predicate> toSingleList(final Predicate predicate) {
return Collections.singletonList(predicate);
}
private static <T> Class<?> getPropertyType(final String property, final ManagedType<T> classMetadata) {
Class<?> propertyType;
if (classMetadata.getAttribute(property).isCollection()) {
propertyType = ((PluralAttribute) classMetadata.getAttribute(property)).getBindableJavaType();
} else {
propertyType = classMetadata.getAttribute(property).getJavaType();
}
return propertyType;
}
private String getAndValidatePropertyFieldName(final A propertyEnum, final ComparisonNode node) {
String finalProperty = propertyEnum.getFieldName();
final String[] graph = node.getSelector().split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
private static ManagedType<?> getClassMetaData(final String property, final ManagedType classMetadata,
final Metamodel metaModel) {
if (isItAssociationType(property, classMetadata)) {
final Class<?> associationType = getPropertyType(property, classMetadata);
return metaModel.managedType(associationType);
} else {
if (isItEmbeddedType(property, classMetadata)) {
final Class<?> embeddedType = getPropertyType(property, classMetadata);
return metaModel.managedType(embeddedType);
validateMapParamter(propertyEnum, node, graph);
// sub entity need minium 1 dot
if (!propertyEnum.getSubEntityAttributes().isEmpty()) {
if (graph.length < 2) {
throw createRSQLParameterUnsupportedException(node);
}
}
return classMetadata;
}
private static <T> boolean isItEmbeddedType(final String property, final ManagedType<T> classMetadata) {
return classMetadata.getAttribute(property).getPersistentAttributeType() == PersistentAttributeType.EMBEDDED;
}
for (int i = 1; i < graph.length; i++) {
final String propertyField = graph[i];
finalProperty += FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR + propertyField;
private String validatePropertyFieldName(final String propertyFieldName, final boolean isDefinedInEnum,
ManagedType classMetadata, final Metamodel metaModel, final ComparisonNode node) {
String finalProperty = propertyFieldName;
final String[] graph = propertyFieldName.split("\\.");
for (String property : graph) {
if (!isDefinedInEnum && PropertyMapper.getAllowedcolmns().containsKey(classMetadata.getJavaType())) {
if (PropertyMapper.getAllowedcolmns().get(classMetadata.getJavaType()).get(property) != null) {
final String mappedValue = PropertyMapper.getAllowedcolmns().get(classMetadata.getJavaType())
.get(property);
finalProperty = finalProperty.replace(property, mappedValue);
property = mappedValue;
} else {
throw new RSQLParameterUnsupportedFieldException("The given search parameter field {"
+ node.getSelector() + "} does not exist, must be one of the following fields {"
+ getExpectedFieldList() + "}", new Exception());
}
// the key of map is not in the graph
if (propertyEnum.isMap() && graph.length == (i + 1)) {
continue;
}
if (!propertyEnum.containsSubEntityAttribute(propertyField)) {
throw createRSQLParameterUnsupportedException(node);
}
classMetadata = getClassMetaData(property, classMetadata, metaModel);
}
return finalProperty;
}
private Path<Object> getFieldPath(final String finalProperty) {
private void validateMapParamter(final A propertyEnum, final ComparisonNode node, final String[] graph) {
if (!propertyEnum.isMap()) {
return;
}
if (!propertyEnum.getSubEntityAttributes().isEmpty()) {
throw new UnsupportedOperationException("Currently subentity attributes for maps are not supported");
}
// enum.key
final int minAttributeForMap = 2;
if (graph.length != minAttributeForMap) {
throw new RSQLParameterUnsupportedFieldException("The syntax of the given map search parameter field {"
+ node.getSelector() + "} is wrong. Syntax is: fieldname.keyname", new Exception());
}
}
private RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(final ComparisonNode node) {
return new RSQLParameterUnsupportedFieldException("The given search parameter field {" + node.getSelector()
+ "} does not exist, must be one of the following fields {" + getExpectedFieldList() + "}",
new Exception());
}
private Path<Object> getFieldPath(final A enumField, final String finalProperty) {
Path<Object> fieldPath = null;
final String[] split = finalProperty.split("\\.");
final String[] split = finalProperty.split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
if (split.length == 0) {
fieldPath = root.get(split[0]);
} else {
for (final String fieldNameSplit : split) {
// hibernate workaround because cannot get attribute of an
// PluralAttributePath, needs
// an implicit join.
// https://hibernate.atlassian.net/browse/HHH-7892
if (fieldPath == null && root.get(fieldNameSplit) != null
&& Collection.class.isAssignableFrom(root.get(fieldNameSplit).getJavaType())) {
fieldPath = root.join(fieldNameSplit);
} else {
fieldPath = (fieldPath != null) ? fieldPath.get(fieldNameSplit) : root.get(fieldNameSplit);
}
return root.get(split[0]);
}
for (int i = 0; i < split.length; i++) {
final boolean isMapKeyField = enumField.isMap() && i == (split.length - 1);
if (isMapKeyField) {
return fieldPath;
}
final String fieldNameSplit = split[i];
fieldPath = (fieldPath != null) ? fieldPath.get(fieldNameSplit) : root.get(fieldNameSplit);
}
return fieldPath;
}
@Override
public List<Predicate> visit(final ComparisonNode node, final String param) {
final Metamodel metaModel = entityManager.getMetamodel();
final ManagedType<?> classMetadata = metaModel.managedType(root.getJavaType());
String propertyFieldName = null;
Boolean isDefinedInEnum = Boolean.FALSE;
A fieldName = null;
try {
/**
* Get the property mapping from FieldNameProvider .If not
* available check in PropertyMapping.If not found throw
* RSQLParameterUnsupportedFieldException.
*/
fieldName = getFieldIdentifierByName(node);
propertyFieldName = fieldName.getFieldName();
isDefinedInEnum = Boolean.TRUE;
fieldName = getFieldEnumByName(node);
} catch (final IllegalArgumentException e) {
if (PropertyMapper.getAllowedcolmns().containsKey(classMetadata.getJavaType())) {
propertyFieldName = node.getSelector();
} else {
throw new RSQLParameterUnsupportedFieldException("The given search parameter field {"
+ node.getSelector()
+ "} does not exist, must be one of the following fields {"
+ Arrays.stream(enumType.getEnumConstants()).map(v -> v.name().toLowerCase())
.collect(Collectors.toList()) + "}", e);
}
throw new RSQLParameterUnsupportedFieldException("The given search parameter field {"
+ node.getSelector()
+ "} does not exist, must be one of the following fields {"
+ Arrays.stream(enumType.getEnumConstants()).map(v -> v.name().toLowerCase())
.collect(Collectors.toList()) + "}", e);
}
final String finalProperty = validatePropertyFieldName(propertyFieldName, isDefinedInEnum, classMetadata,
metaModel, node);
final String finalProperty = getAndValidatePropertyFieldName(fieldName, node);
final List<String> values = node.getArguments();
final List<Object> transformedValue = new ArrayList<>();
final Path<Object> fieldPath = getFieldPath(finalProperty);
final Path<Object> fieldPath = getFieldPath(fieldName, finalProperty);
for (final String value : values) {
transformedValue.add(convertValueIfNecessary(node, fieldName, value, fieldPath));
}
return mapToPredicate(node, fieldPath, node.getArguments(), transformedValue);
return mapToPredicate(node, fieldPath, node.getArguments(), transformedValue, fieldName);
}
private List<String> getExpectedFieldList() {
final List<String> expectedFieldList = Arrays.stream(enumType.getEnumConstants())
.map(v -> v.name().toLowerCase()).collect(Collectors.toList());
expectedFieldList.add("assignedds.name");
expectedFieldList.add("assignedds.version");
.filter(enumField -> enumField.getSubEntityAttributes().isEmpty()).map(enumField -> {
final String enumFieldName = enumField.name().toLowerCase();
if (enumField.isMap()) {
return enumFieldName + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR + "keyName";
}
return enumFieldName;
}).collect(Collectors.toList());
final List<String> expectedSubFieldList = Arrays
.stream(enumType.getEnumConstants())
.filter(enumField -> !enumField.getSubEntityAttributes().isEmpty())
.flatMap(
enumField -> {
final List<String> subEntity = enumField
.getSubEntityAttributes()
.stream()
.map(fieldName -> enumField.name().toLowerCase()
+ FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR + fieldName)
.collect(Collectors.toList());
return subEntity.stream();
}).collect(Collectors.toList());
expectedFieldList.addAll(expectedSubFieldList);
return expectedFieldList;
}
private A getFieldIdentifierByName(final ComparisonNode node) {
final String enumName = node.getSelector().toUpperCase();
private A getFieldEnumByName(final ComparisonNode node) {
String enumName = node.getSelector();
final String[] graph = enumName.split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
if (graph.length != 0) {
enumName = graph[0];
}
LOGGER.debug("get fieldidentifier by name {} of enum type {}", enumName, enumType);
return Enum.valueOf(enumType, enumName);
return Enum.valueOf(enumType, enumName.toUpperCase());
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@@ -400,58 +381,86 @@ public final class RSQLUtility {
}
}
private List<Predicate> mapToPredicate(final ComparisonNode node, final Path<Object> fieldPath,
final List<String> values, final List<Object> transformedValues) {
private List<Predicate> mapToPredicate(final ComparisonNode node, Path<Object> fieldPath,
final List<String> values, final List<Object> transformedValues, final A enumField) {
// only 'equal' and 'notEqual' can handle transformed value like
// enums. The JPA API
// cannot handle object types for greaterThan etc methods.
final Object transformedValue = transformedValues.get(0);
final String value = values.get(0);
final List<Predicate> singleList;
final List<Predicate> singleList = new ArrayList<>();
final Predicate mapPredicate = mapToMapPredicate(node, fieldPath, enumField);
if (mapPredicate != null) {
singleList.add(mapPredicate);
}
fieldPath = getMapValueFieldPath(enumField, fieldPath);
switch (node.getOperator().getSymbol()) {
case "=li=":
singleList = toSingleList(cb.like(cb.upper(pathOfString(fieldPath)), transformedValue.toString()
.toUpperCase()));
singleList.add(cb.like(cb.upper(pathOfString(fieldPath)), transformedValue.toString().toUpperCase()));
break;
case "==":
singleList = getEqualToPredicate(transformedValue, fieldPath);
singleList.add(getEqualToPredicate(transformedValue, fieldPath));
break;
case "!=":
singleList = toSingleList(cb.notEqual(fieldPath, transformedValue));
singleList.add(cb.notEqual(fieldPath, transformedValue));
break;
case "=gt=":
singleList = toSingleList(cb.greaterThan(pathOfString(fieldPath), value));
singleList.add(cb.greaterThan(pathOfString(fieldPath), value));
break;
case "=ge=":
singleList = toSingleList(cb.greaterThanOrEqualTo(pathOfString(fieldPath), value));
singleList.add(cb.greaterThanOrEqualTo(pathOfString(fieldPath), value));
break;
case "=lt=":
singleList = toSingleList(cb.lessThan(pathOfString(fieldPath), value));
singleList.add(cb.lessThan(pathOfString(fieldPath), value));
break;
case "=le=":
singleList = toSingleList(cb.lessThanOrEqualTo(pathOfString(fieldPath), value));
singleList.add(cb.lessThanOrEqualTo(pathOfString(fieldPath), value));
break;
case "=in=":
singleList = toSingleList(fieldPath.in(transformedValues));
singleList.add(fieldPath.in(transformedValues));
break;
case "=out=":
singleList = toSingleList(cb.not(fieldPath.in(transformedValues)));
singleList.add(cb.not(fieldPath.in(transformedValues)));
break;
default:
LOGGER.info("operator symbol {} is either not supported or not implemented");
singleList = Collections.emptyList();
}
return singleList;
return Collections.unmodifiableList(singleList);
}
private List<Predicate> getEqualToPredicate(final Object transformedValue, final Path<Object> fieldPath) {
/**
* @param enumField
* @return
*/
private Path<Object> getMapValueFieldPath(final A enumField, final Path<Object> fieldPath) {
if (!enumField.isMap() || enumField.getValueFieldName() == null) {
return fieldPath;
}
return fieldPath.get(enumField.getValueFieldName());
}
private Predicate mapToMapPredicate(final ComparisonNode node, final Path<Object> fieldPath, final A enumField) {
if (!enumField.isMap()) {
return null;
}
final String[] graph = node.getSelector().split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
final String keyValue = graph[graph.length - 1];
if (fieldPath instanceof MapJoin) {
return cb.equal(((MapJoin) fieldPath).key(), keyValue);
}
return cb.equal(fieldPath.get(enumField.getKeyFieldName()), keyValue);
}
private Predicate getEqualToPredicate(final Object transformedValue, final Path<Object> fieldPath) {
if (transformedValue instanceof String) {
final String preFormattedValue = ((String) transformedValue).replace(LIKE_WILDCARD, '%');
return toSingleList(cb.like(cb.upper(pathOfString(fieldPath)), preFormattedValue.toString()
.toUpperCase()));
} else {
return toSingleList(cb.equal(fieldPath, transformedValue));
return cb.like(cb.upper(pathOfString(fieldPath)), preFormattedValue.toString().toUpperCase());
}
return cb.equal(fieldPath, transformedValue);
}
@SuppressWarnings("unchecked")
@@ -473,8 +482,5 @@ public final class RSQLUtility {
return childs;
}
private static List<Predicate> toSingleList(final Predicate p) {
return Collections.singletonList(p);
}
}
}