From f0066e059ee154eb47f558effad940c93bff1e2f Mon Sep 17 00:00:00 2001 From: Hicham Barhoumi <hicham.barhoumi@archiveco.fr> Date: Tue, 28 Jul 2020 12:06:22 +0200 Subject: [PATCH] [FENIX-66] add elemMatch support for criteria --- .../commons/api/domain/CriterionOperator.java | 3 +- .../commons/mongo/utils/MongoUtils.java | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/domain/CriterionOperator.java b/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/domain/CriterionOperator.java index dade63f3..0afca983 100644 --- a/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/domain/CriterionOperator.java +++ b/commons/commons-api/src/main/java/fr/gouv/vitamui/commons/api/domain/CriterionOperator.java @@ -49,5 +49,6 @@ public enum CriterionOperator { CONTAINS, CONTAINSIGNORECASE, BETWEEN, - STARTWITH; + STARTWITH, + ELEMMATCH } diff --git a/commons/commons-mongo/src/main/java/fr/gouv/vitamui/commons/mongo/utils/MongoUtils.java b/commons/commons-mongo/src/main/java/fr/gouv/vitamui/commons/mongo/utils/MongoUtils.java index 4b6f344e..740963ba 100644 --- a/commons/commons-mongo/src/main/java/fr/gouv/vitamui/commons/mongo/utils/MongoUtils.java +++ b/commons/commons-mongo/src/main/java/fr/gouv/vitamui/commons/mongo/utils/MongoUtils.java @@ -39,6 +39,7 @@ package fr.gouv.vitamui.commons.mongo.utils; import java.lang.reflect.Type; import java.time.Duration; import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -46,6 +47,9 @@ import java.util.Optional; import java.util.regex.Pattern; import java.util.stream.Collectors; +import fr.gouv.vitamui.commons.api.domain.QueryDto; +import fr.gouv.vitamui.commons.api.domain.QueryOperator; +import fr.gouv.vitamui.commons.utils.JsonUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.CriteriaDefinition; @@ -185,6 +189,8 @@ public final class MongoUtils { mapValue.put(BETWEEN_OPERATOR_KEY_START, convertValue(parametrizedClazz, mapValue.get(BETWEEN_OPERATOR_KEY_START))); mapValue.put(BETWEEN_OPEARTOR_KEY_END, convertValue(parametrizedClazz, mapValue.get(BETWEEN_OPEARTOR_KEY_END))); return mapValue; + case ELEMMATCH: + return convertValue(QueryDto.class, value); default : return convertValue(parametrizedClazz, value); } @@ -209,6 +215,14 @@ public final class MongoUtils { return Boolean.parseBoolean(value.toString()); } else if (VitamUIUtils.canBeCastByClass(value, List.class)) { return value; + } else if (clazz.equals(QueryDto.class)) { + try { + // we convert the linked hash map to json to re-convert it properly to query dto + return QueryDto.fromJson(JsonUtils.toJson(value)); + } + catch (Exception e) { + throw new InvalidFormatException(e.getMessage(), e); + } } return CastUtils.castValue(value, clazz); @@ -275,12 +289,36 @@ public final class MongoUtils { final Criteria endCriteria = Criteria.where(key).lte(mapVal.get(BETWEEN_OPEARTOR_KEY_END)); criteria = buildAndOperator(startCriteria, endCriteria); break; + case ELEMMATCH : + criteria = Criteria.where(key).elemMatch(queryDTOToCriterion((QueryDto)val)); + break; default : throw new IllegalArgumentException("Operator " + operator + " is not supported"); } return criteria; } + public static Criteria queryDTOToCriterion(QueryDto queryDto) { + Collection<CriteriaDefinition> criteria = new ArrayList<>(); + queryDto.getCriterionList().forEach(criterion -> { + criteria.add(MongoUtils.getCriteria(criterion.getKey(), criterion.getValue(), criterion.getOperator())); + }); + + // if the criteria contains subQueries, a recursive call is made for each subQuery + queryDto.getSubQueries().forEach(queryDtoItem -> { + criteria.add(queryDTOToCriterion(queryDtoItem)); + }); + + final Criteria commonCustomCriteria = new Criteria(); + if (queryDto.getQueryOperator() == QueryOperator.AND) { + commonCustomCriteria.andOperator(criteria.stream().map(c -> (Criteria) c).toArray(Criteria[]::new)); + } else if (queryDto.getQueryOperator() == QueryOperator.OR) { + commonCustomCriteria.orOperator(criteria.stream().map(c -> (Criteria) c).toArray(Criteria[]::new)); + } + return commonCustomCriteria; + } + + public static Type getTypeOfField(final Class<?> entityClass, final String fieldName) { try { return ReflectionUtils.getTypeOfField(entityClass, fieldName); -- GitLab