|
@@ -0,0 +1,633 @@
|
|
|
+package com.persagy.dmp.report.common.criteria;
|
|
|
+
|
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
|
+import com.fasterxml.jackson.databind.node.*;
|
|
|
+import com.persagy.common.criteria.CriteriaExpressionParser;
|
|
|
+import com.persagy.common.date.DateUtils;
|
|
|
+import com.persagy.common.web.PagedResponse;
|
|
|
+import com.querydsl.core.Tuple;
|
|
|
+import com.querydsl.core.types.Expression;
|
|
|
+import com.querydsl.core.types.OrderSpecifier;
|
|
|
+import com.querydsl.core.types.dsl.*;
|
|
|
+import com.querydsl.jpa.impl.JPAQuery;
|
|
|
+import com.querydsl.jpa.impl.JPAQueryFactory;
|
|
|
+
|
|
|
+import java.lang.reflect.Field;
|
|
|
+import java.text.ParseException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author: fengyanjie
|
|
|
+ * @date: 2020-11-19
|
|
|
+ * @verison: 1.0
|
|
|
+ */
|
|
|
+public class CriteriaUtils {
|
|
|
+
|
|
|
+ private static final Integer DEFAULT_SIZE = 50;
|
|
|
+
|
|
|
+ private JPAQueryFactory queryFactory;
|
|
|
+
|
|
|
+ public CriteriaUtils(JPAQueryFactory queryFactory) {
|
|
|
+ this.queryFactory = queryFactory;
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T, Q extends EntityPathBase<T>> List<BooleanExpression> parseNode(Q q, ObjectNode object) {
|
|
|
+ List<BooleanExpression> exps = new LinkedList<>();
|
|
|
+ if (object == null || object.isEmpty()) {
|
|
|
+ return exps;
|
|
|
+ }
|
|
|
+
|
|
|
+ Field[] fields = q.getClass().getFields();
|
|
|
+ for (Field field : fields) {
|
|
|
+ Class<?> type = field.getType();
|
|
|
+ if (type != NumberPath.class && type != DateTimePath.class && type != StringPath.class) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String name = field.getName();
|
|
|
+ if (!object.has(name)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ JsonNode jsonNode = object.get(name);
|
|
|
+ try {
|
|
|
+ if (type == NumberPath.class) {
|
|
|
+ NumberPath path = (NumberPath) field.get(q);
|
|
|
+ exps.addAll(parse(path, jsonNode));
|
|
|
+ }
|
|
|
+ if (type == DateTimePath.class) {
|
|
|
+ DateTimePath path = (DateTimePath) field.get(q);
|
|
|
+ exps.addAll(parse(path, jsonNode));
|
|
|
+ }
|
|
|
+ if (type == StringPath.class) {
|
|
|
+ StringPath path = (StringPath) field.get(q);
|
|
|
+ exps.addAll(parse(path, jsonNode));
|
|
|
+ }
|
|
|
+ // Boolean Enum
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return exps;
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T, Q extends EntityPathBase<T>> List<BooleanExpression> parseNode(Q q, CriteriaExpressionParser parser, ObjectNode objectNode) {
|
|
|
+ List<BooleanExpression> expressions = new LinkedList<>();
|
|
|
+ if (objectNode == null || objectNode.isEmpty()) {
|
|
|
+ return expressions;
|
|
|
+ }
|
|
|
+ List<BooleanExpression> exps = parseNode(q, objectNode);
|
|
|
+ if (exps != null && exps.size() > 0) {
|
|
|
+ expressions.addAll(exps);
|
|
|
+ }
|
|
|
+ if (parser != null) {
|
|
|
+ List<BooleanExpression> parseExps = parser.parse(objectNode);
|
|
|
+ if (parseExps != null && parseExps.size() > 0) {
|
|
|
+ expressions.addAll(parseExps);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return expressions;
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T, Q extends EntityPathBase<T>> PagedResponse<T> query(Q q, CriteriaExpressionParser parser, JacksonCriteria request) {
|
|
|
+ PagedResponse<T> resp = new PagedResponse<>();
|
|
|
+
|
|
|
+ // 解析查询条件
|
|
|
+ ObjectNode criteria = request.getCriteria();
|
|
|
+ List<BooleanExpression> expressions = parseNode(q, parser, criteria);
|
|
|
+
|
|
|
+ // 处理or
|
|
|
+ JsonNode or = criteria.get("$or");
|
|
|
+ if (or != null && or.getNodeType() == JsonNodeType.ARRAY) {
|
|
|
+ ArrayNode arr = (ArrayNode) or;
|
|
|
+
|
|
|
+ BooleanExpression orExp = null;
|
|
|
+ for (JsonNode jsonNode : arr) {
|
|
|
+ if (jsonNode.getNodeType() != JsonNodeType.OBJECT) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<BooleanExpression> subExpressions = parseNode(q, parser, (ObjectNode) jsonNode);
|
|
|
+ if (orExp == null) {
|
|
|
+ orExp = and(subExpressions);
|
|
|
+ } else {
|
|
|
+ orExp = orExp.or(and(subExpressions));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (orExp != null) {
|
|
|
+ expressions.add(orExp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ JPAQuery<T> query = queryFactory.selectFrom(q).where(expressions.toArray(new BooleanExpression[0]));
|
|
|
+
|
|
|
+ // 统计总数
|
|
|
+ if (!request.isWithoutCount()) {
|
|
|
+ long count = query.fetchCount();
|
|
|
+ resp.setCount(count);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (request.isOnlyCount()) {
|
|
|
+ return resp;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 排序
|
|
|
+ OrderSpecifier[] specifiers = parseOrders(q, request);
|
|
|
+ if (specifiers != null) {
|
|
|
+ query = query.orderBy(specifiers);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分页
|
|
|
+ Integer page = request.getPage();
|
|
|
+ Integer size = request.getSize();
|
|
|
+ if (page != null) {
|
|
|
+ if (size == null) {
|
|
|
+ size = DEFAULT_SIZE; // 默认每页50
|
|
|
+ }
|
|
|
+ int offset = (page - 1) * size;
|
|
|
+ if (offset < 0) {
|
|
|
+ offset = 0;
|
|
|
+ }
|
|
|
+ query = query.offset(offset).limit(size);
|
|
|
+ }
|
|
|
+ List<T> data = query.fetch();
|
|
|
+ resp.setData(data);
|
|
|
+ return resp;
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T, Q extends EntityPathBase<T>> PagedResponse<Tuple> groupbyQuery(Q q, CriteriaExpressionParser parser, JacksonCriteria request) {
|
|
|
+ PagedResponse<Tuple> resp = new PagedResponse<>();
|
|
|
+
|
|
|
+ // 解析查询条件
|
|
|
+ ObjectNode criteria = request.getCriteria();
|
|
|
+ List<BooleanExpression> expressions = parseNode(q, parser, criteria);
|
|
|
+
|
|
|
+ // 处理or
|
|
|
+ JsonNode or = criteria.get("$or");
|
|
|
+ if (or != null && or.getNodeType() == JsonNodeType.ARRAY) {
|
|
|
+ ArrayNode arr = (ArrayNode) or;
|
|
|
+
|
|
|
+ BooleanExpression orExp = null;
|
|
|
+ for (JsonNode jsonNode : arr) {
|
|
|
+ if (jsonNode.getNodeType() != JsonNodeType.OBJECT) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<BooleanExpression> subExpressions = parseNode(q, parser, (ObjectNode) jsonNode);
|
|
|
+ if (orExp == null) {
|
|
|
+ orExp = and(subExpressions);
|
|
|
+ } else {
|
|
|
+ orExp = orExp.or(and(subExpressions));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (orExp != null) {
|
|
|
+ expressions.add(orExp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Expression[] groupby = parseGroupby(q, request);
|
|
|
+ List<Expression> ex = new LinkedList<>();
|
|
|
+ Field[] fields = q.getClass().getFields();
|
|
|
+
|
|
|
+ if(null != request.getCalculatedColumns()){
|
|
|
+ //计算列
|
|
|
+ for (JacksonCriteria.Calculated calculatedColumn : request.getCalculatedColumns()) {
|
|
|
+ for (Field field : fields) {
|
|
|
+ String name = field.getName();
|
|
|
+ Class<?> type = field.getType();
|
|
|
+ if (calculatedColumn.getColumn().equals(name) && type == NumberPath.class) {
|
|
|
+ NumberPath path = null;
|
|
|
+ try {
|
|
|
+ path = (NumberPath) field.get(q);
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ switch (calculatedColumn.getFunction()) {
|
|
|
+ case SUM:
|
|
|
+ ex.add(path.sum());
|
|
|
+ break;
|
|
|
+ case AVG:
|
|
|
+ ex.add(path.avg());
|
|
|
+ break;
|
|
|
+ case MAX:
|
|
|
+ ex.add(path.max());
|
|
|
+ break;
|
|
|
+ case MIN:
|
|
|
+ ex.add(path.min());
|
|
|
+ break;
|
|
|
+ case COUNT:
|
|
|
+ ex.add(path.count());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //分组
|
|
|
+ for (String column : request.getGroupbyColumns()) {
|
|
|
+ for (Field field : fields) {
|
|
|
+ String name = field.getName();
|
|
|
+ Class<?> type = field.getType();
|
|
|
+ if (column.equals(name)) {
|
|
|
+ try {
|
|
|
+ if (type == NumberPath.class) {
|
|
|
+ NumberPath path = (NumberPath) field.get(q);
|
|
|
+ ex.add(path);
|
|
|
+ }
|
|
|
+ if (type == DateTimePath.class) {
|
|
|
+ DateTimePath path = (DateTimePath) field.get(q);
|
|
|
+ ex.add(path);
|
|
|
+ }
|
|
|
+ if (type == StringPath.class) {
|
|
|
+ StringPath path = (StringPath) field.get(q);
|
|
|
+ ex.add(path);
|
|
|
+ }
|
|
|
+ if (type == EnumPath.class) {
|
|
|
+ EnumPath path = (EnumPath) field.get(q);
|
|
|
+ ex.add(path);
|
|
|
+ }
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ JPAQuery<Tuple> query = queryFactory.select(ex.toArray(new Expression[0])).from(q).where(expressions.toArray(new BooleanExpression[0]));
|
|
|
+ query = query.groupBy(groupby);
|
|
|
+
|
|
|
+ // 统计总数 todo
|
|
|
+ if (!request.isWithoutCount()) {
|
|
|
+ JPAQuery<Long> count = queryFactory.select(q.count()).from(q).where(expressions.toArray(new BooleanExpression[0])).groupBy(groupby);
|
|
|
+ resp.setCount((long) count.fetch().size());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (request.isOnlyCount()) {
|
|
|
+ return resp;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 排序
|
|
|
+ OrderSpecifier[] specifiers = parseOrders(q, request);
|
|
|
+ if (specifiers != null) {
|
|
|
+ query = query.orderBy(specifiers);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分页
|
|
|
+ Integer page = request.getPage();
|
|
|
+ Integer size = request.getSize();
|
|
|
+ if (page != null) {
|
|
|
+ if (size == null) {
|
|
|
+ size = DEFAULT_SIZE; // 默认每页50
|
|
|
+ }
|
|
|
+ int offset = (page - 1) * size;
|
|
|
+ if (offset < 0) {
|
|
|
+ offset = 0;
|
|
|
+ }
|
|
|
+ query = query.offset(offset).limit(size);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Tuple> data = query.fetch();
|
|
|
+ resp.setData(data);
|
|
|
+ return resp;
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T, Q extends EntityPathBase<T>> OrderSpecifier[] parseOrders(Q q, JacksonCriteria criteria) {
|
|
|
+ List<JacksonCriteria.Order> orders = criteria.getOrders();
|
|
|
+ if (orders == null || orders.size() == 0) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<OrderSpecifier> specifiers = new LinkedList<>();
|
|
|
+ Field[] fields = q.getClass().getFields();
|
|
|
+ for (JacksonCriteria.Order order : orders) {
|
|
|
+ String column = order.getColumn();
|
|
|
+ try {
|
|
|
+ for (Field field : fields) {
|
|
|
+ String name = field.getName();
|
|
|
+ if (!column.equals(name)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Class<?> type = field.getType();
|
|
|
+ if (type == NumberPath.class) {
|
|
|
+ NumberPath o = (NumberPath) field.get(q);
|
|
|
+ specifiers.add(order.isAsc() ? o.asc() : o.desc());
|
|
|
+ }
|
|
|
+ if (type == DateTimePath.class) {
|
|
|
+ DateTimePath o = (DateTimePath) field.get(q);
|
|
|
+ specifiers.add(order.isAsc() ? o.asc() : o.desc());
|
|
|
+ }
|
|
|
+ if (type == StringPath.class) {
|
|
|
+ StringPath o = (StringPath) field.get(q);
|
|
|
+ specifiers.add(order.isAsc() ? o.asc() : o.desc());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (specifiers.size() == 0) {
|
|
|
+ return null;
|
|
|
+ } else {
|
|
|
+ return specifiers.toArray(new OrderSpecifier[0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T, Q extends EntityPathBase<T>> Expression[] parseGroupby(Q q, JacksonCriteria criteria) {
|
|
|
+ Set<String> groupbyColumns = criteria.getGroupbyColumns();
|
|
|
+ if (groupbyColumns == null || groupbyColumns.size() == 0) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<Expression> expressions = new LinkedList<>();
|
|
|
+ Field[] fields = q.getClass().getFields();
|
|
|
+ for (String column : groupbyColumns) {
|
|
|
+ try {
|
|
|
+ for (Field field : fields) {
|
|
|
+ String name = field.getName();
|
|
|
+ if (!column.equals(name)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Class<?> type = field.getType();
|
|
|
+ if (type == NumberPath.class) {
|
|
|
+ NumberPath path = (NumberPath) field.get(q);
|
|
|
+ expressions.add(path);
|
|
|
+ }
|
|
|
+ if (type == DateTimePath.class) {
|
|
|
+ DateTimePath path = (DateTimePath) field.get(q);
|
|
|
+ expressions.add(path);
|
|
|
+ }
|
|
|
+ if (type == StringPath.class) {
|
|
|
+ StringPath path = (StringPath) field.get(q);
|
|
|
+ expressions.add(path);
|
|
|
+ }
|
|
|
+ if (type == EnumPath.class) {
|
|
|
+ EnumPath path = (EnumPath) field.get(q);
|
|
|
+ expressions.add(path);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return expressions.toArray(new Expression[0]);
|
|
|
+ }
|
|
|
+
|
|
|
+ private BooleanExpression and(List<BooleanExpression> exps) {
|
|
|
+ if (exps == null || exps.size() == 0) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ BooleanExpression result = exps.get(0);
|
|
|
+ for (int i = 1; i < exps.size(); i++) {
|
|
|
+ result = result.and(exps.get(i));
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static List<BooleanExpression> parse(NumberExpression path, JsonNode node) {
|
|
|
+ return parse(path, node, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<BooleanExpression> parse(NumberExpression path, JsonNode node, Integer defaultValue) {
|
|
|
+ List<BooleanExpression> result = new LinkedList<>();
|
|
|
+ if (node == null) {
|
|
|
+ if (defaultValue != null) {
|
|
|
+ result.add(path.eq(defaultValue));
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ JsonNodeType nodeType = node.getNodeType();
|
|
|
+ if (nodeType == JsonNodeType.STRING) {
|
|
|
+ result.add(path.eq(parseNumber(node)));
|
|
|
+ } else if (nodeType == JsonNodeType.NUMBER) {
|
|
|
+ result.add(path.eq(parseNumber(node)));
|
|
|
+ } else if (nodeType == JsonNodeType.ARRAY) {
|
|
|
+ ArrayNode arr = (ArrayNode) node;
|
|
|
+ result.add(path.in(parseNumberArr(arr)));
|
|
|
+ } else if (nodeType == JsonNodeType.OBJECT) {
|
|
|
+ if (node.has("$gt")) {
|
|
|
+ result.add(path.gt(parseNumber(node.get("$gt"))));
|
|
|
+ }
|
|
|
+ if (node.has("$gte")) {
|
|
|
+ result.add(path.goe(parseNumber(node.get("$gte"))));
|
|
|
+ }
|
|
|
+ if (node.has("$lt")) {
|
|
|
+ result.add(path.lt(parseNumber(node.get("$lt"))));
|
|
|
+ }
|
|
|
+ if (node.has("$lte")) {
|
|
|
+ result.add(path.loe(parseNumber(node.get("$lte"))));
|
|
|
+ }
|
|
|
+ if (node.has("$in")) {
|
|
|
+ ArrayNode arr = (ArrayNode) node.get("$in");
|
|
|
+ result.add(path.in(parseNumberArr(arr)));
|
|
|
+ }
|
|
|
+ if (node.has("$ne")) {
|
|
|
+ result.add(path.ne(parseNumber(node.get("$ne"))));
|
|
|
+ }
|
|
|
+ if (node.has("$null")) {
|
|
|
+ Boolean isNull = Boolean.valueOf(node.get("$null").asText());
|
|
|
+ if (isNull) {
|
|
|
+ result.add(path.isNull());
|
|
|
+ } else {
|
|
|
+ result.add(path.isNotNull());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Number parseNumber(JsonNode node) {
|
|
|
+ if (node instanceof IntNode) {
|
|
|
+ return node.asInt();
|
|
|
+ } else if (node instanceof LongNode) {
|
|
|
+ return node.asLong();
|
|
|
+ } else if (node instanceof DoubleNode) {
|
|
|
+ return node.doubleValue();
|
|
|
+ } else if (node instanceof TextNode) {
|
|
|
+ String n = node.asText();
|
|
|
+ if (n.indexOf(".") > -1) {
|
|
|
+ return node.asDouble();
|
|
|
+ } else {
|
|
|
+ return node.asLong();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<Number> parseNumberArr(ArrayNode arr) {
|
|
|
+ List<Number> values = new ArrayList<>(arr.size());
|
|
|
+ Iterator<JsonNode> elements = arr.elements();
|
|
|
+ while (elements.hasNext()) {
|
|
|
+ values.add(parseNumber(elements.next()));
|
|
|
+ }
|
|
|
+ return values;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<BooleanExpression> parse(StringExpression path, JsonNode node) {
|
|
|
+ return parse(path, node, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<BooleanExpression> parse(StringExpression path, JsonNode node, String defaultValue) {
|
|
|
+ List<BooleanExpression> result = new LinkedList<>();
|
|
|
+ if (node == null) {
|
|
|
+ if (defaultValue != null) {
|
|
|
+ result.add(path.eq(defaultValue));
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ JsonNodeType nodeType = node.getNodeType();
|
|
|
+ if (nodeType == JsonNodeType.STRING) {
|
|
|
+ result.add(path.eq(node.asText()));
|
|
|
+ } else if (nodeType == JsonNodeType.ARRAY) {
|
|
|
+ ArrayNode arr = (ArrayNode) node;
|
|
|
+ result.add(path.in(parseStringArr(arr)));
|
|
|
+ } else if (nodeType == JsonNodeType.OBJECT) {
|
|
|
+ if (node.has("$gt")) {
|
|
|
+ result.add(path.gt(node.get("$gt").asText()));
|
|
|
+ }
|
|
|
+ if (node.has("$gte")) {
|
|
|
+ result.add(path.goe(node.get("$gte").asText()));
|
|
|
+ }
|
|
|
+ if (node.has("$lt")) {
|
|
|
+ result.add(path.lt(node.get("$lt").asText()));
|
|
|
+ }
|
|
|
+ if (node.has("$lte")) {
|
|
|
+ result.add(path.loe(node.get("$lte").asText()));
|
|
|
+ }
|
|
|
+ if (node.has("$in")) {
|
|
|
+ ArrayNode arr = (ArrayNode) node.get("$in");
|
|
|
+ result.add(path.in(parseStringArr(arr)));
|
|
|
+ }
|
|
|
+ if (node.has("$ne")) {
|
|
|
+ result.add(path.ne(node.get("$ne").asText()));
|
|
|
+ }
|
|
|
+ if (node.has("$like")) {
|
|
|
+ result.add(path.like(node.get("$like").asText()));
|
|
|
+ }
|
|
|
+ if (node.has("$notLike")) {
|
|
|
+ result.add(path.notLike(node.get("$notLike").asText()));
|
|
|
+ }
|
|
|
+ if (node.has("$null")) {
|
|
|
+ Boolean isNull = Boolean.valueOf(node.get("$null").asText());
|
|
|
+ if (isNull) {
|
|
|
+ result.add(path.isNull());
|
|
|
+ } else {
|
|
|
+ result.add(path.isNotNull());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> parseStringArr(ArrayNode arr) {
|
|
|
+ List<String> values = new ArrayList<>(arr.size());
|
|
|
+ Iterator<JsonNode> elements = arr.elements();
|
|
|
+ while (elements.hasNext()) {
|
|
|
+ values.add(elements.next().asText());
|
|
|
+ }
|
|
|
+ return values;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<BooleanExpression> parse(DateTimeExpression path, JsonNode node) {
|
|
|
+ return parse(path, node, (Date) null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param path
|
|
|
+ * @param node
|
|
|
+ * @param time yyyyMMddHHmmss
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static List<BooleanExpression> parse(DateTimeExpression path, JsonNode node, String time) {
|
|
|
+ if (time != null) {
|
|
|
+ return parse(path, node, DateUtils.parse(time));
|
|
|
+ } else {
|
|
|
+ return parse(path, node, (Date) null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<BooleanExpression> parse(DateTimeExpression path, JsonNode node, Date time) {
|
|
|
+ List<BooleanExpression> result = new LinkedList<>();
|
|
|
+ if (node == null) {
|
|
|
+ if (time != null) {
|
|
|
+ result.add(path.eq(time));
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ SimpleDateFormat format = new SimpleDateFormat(DateUtils.PATTERN_yyyyMMddHHmmss);
|
|
|
+ JsonNodeType nodeType = node.getNodeType();
|
|
|
+ if (nodeType == JsonNodeType.STRING) {
|
|
|
+ try {
|
|
|
+ result.add(path.eq(format.parse(node.asText())));
|
|
|
+ } catch (ParseException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ } else if (nodeType == JsonNodeType.OBJECT) {
|
|
|
+ if (node.has("$gt")) {
|
|
|
+ result.add(path.gt(parse(format, node, "$gt")));
|
|
|
+ }
|
|
|
+ if (node.has("$gte")) {
|
|
|
+ result.add(path.goe(parse(format, node, "$gte")));
|
|
|
+ }
|
|
|
+ if (node.has("$lt")) {
|
|
|
+ result.add(path.lt(parse(format, node, "$lt")));
|
|
|
+ }
|
|
|
+ if (node.has("$lte")) {
|
|
|
+ result.add(path.loe(parse(format, node, "$lte")));
|
|
|
+ }
|
|
|
+ if (node.has("$null")) {
|
|
|
+ Boolean isNull = Boolean.valueOf(node.get("$null").asText());
|
|
|
+ if (isNull) {
|
|
|
+ result.add(path.isNull());
|
|
|
+ } else {
|
|
|
+ result.add(path.isNotNull());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Date parse(SimpleDateFormat format, JsonNode node, String name) {
|
|
|
+ try {
|
|
|
+ return format.parse(node.get(name).asText());
|
|
|
+ } catch (ParseException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T extends Enum> List<BooleanExpression> parse(EnumExpression path, JsonNode node, Class<T> clazz) {
|
|
|
+ return parse(path, node, clazz, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static <T extends Enum> List<BooleanExpression> parse(EnumExpression path, JsonNode node, Class<T> clazz, T defaultValue) {
|
|
|
+ List<BooleanExpression> result = new LinkedList<>();
|
|
|
+ if (node == null) {
|
|
|
+ if (defaultValue != null) {
|
|
|
+ result.add(path.eq(defaultValue));
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ JsonNodeType nodeType = node.getNodeType();
|
|
|
+ if (nodeType == JsonNodeType.STRING) {
|
|
|
+ result.add(path.eq(T.valueOf(clazz, node.asText())));
|
|
|
+ } else if (nodeType == JsonNodeType.ARRAY) {
|
|
|
+ ArrayNode arr = (ArrayNode) node;
|
|
|
+ result.add(path.in(parseEnumArr(arr, clazz)));
|
|
|
+ } else if (nodeType == JsonNodeType.OBJECT) {
|
|
|
+ ArrayNode arr = (ArrayNode) node.get("$in");
|
|
|
+ if (arr != null) {
|
|
|
+ result.add(path.in(parseEnumArr(arr, clazz)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static <T extends Enum> List parseEnumArr(ArrayNode arr, Class<T> clazz) {
|
|
|
+ List<Enum> values = new ArrayList<>(arr.size());
|
|
|
+ Iterator<JsonNode> elements = arr.elements();
|
|
|
+ while (elements.hasNext()) {
|
|
|
+ Enum anEnum = T.valueOf(clazz, elements.next().asText());
|
|
|
+ values.add(anEnum);
|
|
|
+ }
|
|
|
+ return values;
|
|
|
+ }
|
|
|
+}
|