![JAR search and dependency download from the Maven repository](/logo.png)
com.bq.oss.lib.queries.parser.JacksonQueryParser Maven / Gradle / Ivy
package com.bq.oss.lib.queries.parser;
import com.bq.oss.lib.queries.*;
import com.bq.oss.lib.queries.exception.MalformedJsonQueryException;
import com.bq.oss.lib.queries.request.QueryLiteral;
import com.bq.oss.lib.queries.request.QueryNode;
import com.bq.oss.lib.queries.request.QueryOperator;
import com.bq.oss.lib.queries.request.ResourceQuery;
import com.fasterxml.jackson.databind.JsonNode;
import org.joda.time.format.ISODateTimeFormat;
import java.time.Duration;
import java.time.Period;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAmount;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JacksonQueryParser implements QueryParser {
private static final String OPERATOR_START = "$";
private static final Pattern ISO_DATE_PATTERN = Pattern.compile("^ISODate[(](.*?)[)]$");
private static final Pattern PERIOD_PATTERN = Pattern.compile("^Period[(](.*?)[)]$");
private final CustomJsonParser jsonParser;
public JacksonQueryParser(CustomJsonParser jsonParser) {
this.jsonParser = jsonParser;
}
@Override
public ResourceQuery parse(String queryString) throws MalformedJsonQueryException {
JsonNode nodes = jsonParser.readValueAsTree(queryString);
return getParseQueriesFromTree(nodes);
}
private ResourceQuery getParseQueriesFromTree(JsonNode nodes) throws MalformedJsonQueryException {
ResourceQuery resourceQuery = new ResourceQuery();
for (JsonNode node : nodes) {
if (node.isObject()) {
resourceQuery.addQueryNode(getQueryNodeFromJsonNode(node));
} else {
throw new MalformedJsonQueryException("Unexpected array");
}
}
return resourceQuery;
}
private QueryNode getQueryNodeFromJsonNode(JsonNode node) throws MalformedJsonQueryException {
Iterator fieldNames = node.fieldNames();
if (fieldNames.hasNext()) {
String key = fieldNames.next();
if (fieldNames.hasNext()) {
throw new MalformedJsonQueryException("Wrong number of fields (Expected one)");
}
if (key.startsWith(OPERATOR_START)) {
return getQueryNode(getOperator(key), node.get(key));
} else {
return getQueryNode(QueryOperator.$EQ, node);
}
} else {
throw new MalformedJsonQueryException("Empty object");
}
}
private QueryOperator getOperator(String key) throws MalformedJsonQueryException {
try {
return QueryOperator.valueOf(key.toUpperCase());
} catch (IllegalArgumentException e) {
throw new MalformedJsonQueryException("Unknown operator " + key);
}
}
private QueryNodeImpl getQueryNode(QueryOperator operator, JsonNode nodeField) throws MalformedJsonQueryException {
if (nodeField.fieldNames().hasNext()) {
String field = nodeField.fieldNames().next();
QueryLiteral> value = generateQueryLiteral(nodeField.get(field), operator);
return new QueryNodeImpl(operator, field, value);
} else {
throw new MalformedJsonQueryException("Empty filter");
}
}
private QueryLiteral> generateQueryLiteral(JsonNode nodeField, QueryOperator operator) throws MalformedJsonQueryException {
if (nodeField.isObject()) {
throw new MalformedJsonQueryException("Unsupported operation. No operator supports Object type");
} else if (nodeField.isArray()) {
if (!operator.isArrayOperator()) {
throw new MalformedJsonQueryException(
"Unsupported operation. Only $ALL, $IN, $NIN and $ELEM_MATCH support operations with non primitive types.");
}
if (operator == QueryOperator.$ELEM_MATCH) {
return generateResourceQueryQueryLiteral(nodeField);
} else {
return generateArrayQueryLiteral(nodeField);
}
} else if (operator.isArrayOperator()) {
throw new MalformedJsonQueryException(
"Unsopported operation. Only $EQ, $GT, $GTE, $LT, $LTE, $NE and $LIKE support operations with primitives.");
}
return generatePrimitiveQueryLiteral(nodeField);
}
private QueryLiteral> generateResourceQueryQueryLiteral(JsonNode nodeField) throws MalformedJsonQueryException {
QueryLiteral literal = new ResourceQueryQueryLiteral();
literal.setLiteral(getParseQueriesFromTree(nodeField));
return literal;
}
@SuppressWarnings("rawtypes")
private QueryLiteral> generateArrayQueryLiteral(JsonNode nodeField) throws MalformedJsonQueryException {
List list = new ArrayList<>();
for (JsonNode aNodeField : nodeField) {
list.add(generatePrimitiveQueryLiteral(aNodeField));
}
QueryLiteral> literal = new ListQueryLiteral();
literal.setLiteral(list);
return literal;
}
@SuppressWarnings("unchecked")
private QueryLiteral> generatePrimitiveQueryLiteral(JsonNode nodeField) throws MalformedJsonQueryException {
QueryLiteral> literal;
if (nodeField.isDouble()) {
literal = new DoubleQueryLiteral();
((QueryLiteral) literal).setLiteral(nodeField.asDouble());
} else if (nodeField.canConvertToLong()) {
literal = new LongQueryLiteral();
((QueryLiteral) literal).setLiteral(nodeField.asLong());
} else if (nodeField.isBoolean()) {
literal = new BooleanQueryLiteral();
((QueryLiteral) literal).setLiteral(nodeField.asBoolean());
} else if (nodeField.isTextual()) {
String valueString = nodeField.textValue();
Matcher isoDateMatcher = ISO_DATE_PATTERN.matcher(valueString);
if (isoDateMatcher.find()) {
try {
literal = new DateQueryLiteral();
((QueryLiteral) literal).setLiteral(ISODateTimeFormat.dateTimeNoMillis().parseDateTime(isoDateMatcher.group(1))
.toDate());
} catch (IllegalArgumentException e) {
throw new MalformedJsonQueryException("Wrong date format", e);
}
} else {
literal = new StringQueryLiteral();
Matcher isoPeriodMatcher = PERIOD_PATTERN.matcher(valueString);
if (isoPeriodMatcher.find()) {
TemporalAmount temporalAmount;
try {
temporalAmount = Period.parse(isoPeriodMatcher.group(1));
} catch (DateTimeParseException ignored) {
temporalAmount = Duration.parse(isoPeriodMatcher.group(1));
}
((QueryLiteral) literal).setLiteral(temporalAmount.toString());
} else {
((QueryLiteral) literal).setLiteral(valueString);
}
}
} else {
throw new MalformedJsonQueryException("Unsupported type");
}
return literal;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy