Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.turkraft.springfilter.boot;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.turkraft.springfilter.helper.FieldTypeResolver;
import com.turkraft.springfilter.helper.JsonNodeHelper;
import com.turkraft.springfilter.transformer.TransformerUtils;
import com.turkraft.springfilter.parser.node.FilterNode;
import com.turkraft.springfilter.transformer.FilterJsonNodeTransformer;
import com.turkraft.springfilter.transformer.processor.factory.FilterNodeProcessorFactories;
Expand Down Expand Up @@ -33,18 +35,21 @@ public class FilterJsonNodeArgumentResolver implements HandlerMethodArgumentReso

protected final FieldTypeResolver fieldTypeResolver;

protected final TransformerUtils transformerUtils;

public FilterJsonNodeArgumentResolver(
ConversionService conversionService, ObjectMapper objectMapper,
FilterNodeArgumentResolverHelper filterNodeArgumentResolverHelper,
JsonNodeHelper jsonNodeHelper,
FilterNodeProcessorFactories filterNodeProcessorFactories,
FieldTypeResolver fieldTypeResolver) {
ConversionService conversionService, ObjectMapper objectMapper,
FilterNodeArgumentResolverHelper filterNodeArgumentResolverHelper,
JsonNodeHelper jsonNodeHelper,
FilterNodeProcessorFactories filterNodeProcessorFactories,
FieldTypeResolver fieldTypeResolver, TransformerUtils transformerUtils) {
this.conversionService = conversionService;
this.objectMapper = objectMapper;
this.filterNodeArgumentResolverHelper = filterNodeArgumentResolverHelper;
this.jsonNodeHelper = jsonNodeHelper;
this.filterNodeProcessorFactories = filterNodeProcessorFactories;
this.fieldTypeResolver = fieldTypeResolver;
this.transformerUtils = transformerUtils;
}

@Override
Expand Down Expand Up @@ -102,8 +107,12 @@ public Object resolveArgument(MethodParameter methodParameter,
conversionService, objectMapper, filterNodeProcessorFactories, fieldTypeResolver,
methodParameter.getParameterAnnotation(Filter.class).entityClass());

JsonNode transform = filterJsonNodeTransformer.transform(result.get());
transform = transformerUtils.simplify(filterJsonNodeTransformer,transform);


ObjectNode jsonResult = jsonNodeHelper.wrapWithMongoExpression(
filterJsonNodeTransformer.transform(result.get()));
transform);

if (methodParameter.getParameterType().isAssignableFrom(ObjectNode.class)) {
return jsonResult;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.turkraft.springfilter.helper.FieldTypeResolver;
import com.turkraft.springfilter.helper.JsonNodeHelper;
import com.turkraft.springfilter.transformer.TransformerUtils;
import com.turkraft.springfilter.transformer.processor.factory.FilterNodeProcessorFactories;
import java.util.List;
import org.springframework.beans.factory.annotation.Qualifier;
Expand All @@ -27,27 +28,31 @@ public class FilterJsonNodeArgumentResolverConfigurer implements WebMvcConfigure

protected final FieldTypeResolver fieldTypeResolver;

protected final TransformerUtils transformerUtils;

public FilterJsonNodeArgumentResolverConfigurer(
@Lazy @Qualifier("sfConversionService") ConversionService conversionService,
@Lazy ObjectMapper objectMapper,
@Lazy FilterNodeArgumentResolverHelper filterNodeArgumentResolverHelper,
@Lazy JsonNodeHelper jsonNodeHelper,
@Lazy FilterNodeProcessorFactories filterNodeProcessorFactories,
FieldTypeResolver fieldTypeResolver) {
FieldTypeResolver fieldTypeResolver,
TransformerUtils transformerUtils) {
this.conversionService = conversionService;
this.objectMapper = objectMapper;
this.filterNodeArgumentResolverHelper = filterNodeArgumentResolverHelper;
this.jsonNodeHelper = jsonNodeHelper;
this.filterNodeProcessorFactories = filterNodeProcessorFactories;
this.fieldTypeResolver = fieldTypeResolver;
this.transformerUtils = transformerUtils;
}

@Override
public void addArgumentResolvers(
List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new FilterJsonNodeArgumentResolver(conversionService, objectMapper,
filterNodeArgumentResolverHelper, jsonNodeHelper,
filterNodeProcessorFactories, fieldTypeResolver));
filterNodeProcessorFactories, fieldTypeResolver, transformerUtils));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.turkraft.springfilter.converter;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.turkraft.springfilter.converter.StringCustomDateConverter.CustomDate;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Service;

import java.io.Serializable;

@Service
public class StringCustomDateConverter implements Converter<String, CustomDate> {

@Override
public CustomDate convert(String source) {
return new CustomDate(source);
}

public static class CustomDate implements Serializable {

@JsonProperty("$date")
private String value;

public CustomDate(String id) {
this.value = id;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public interface FieldTypeResolver {

Field getField(Class<?> klass, String path);

boolean isIterable(Class<?> klass, String path);
}
Original file line number Diff line number Diff line change
@@ -1,68 +1,89 @@
package com.turkraft.springfilter.helper;

import com.turkraft.springfilter.converter.StringCustomDateConverter;
import com.turkraft.springfilter.converter.StringCustomObjectIdConverter.CustomObjectId;
import com.turkraft.springfilter.converter.StringCustomUUIDConverter.CustomUUID;
import org.springframework.data.annotation.Id;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.UUID;
import org.springframework.data.annotation.Id;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

@Service
class FieldTypeResolverImpl implements FieldTypeResolver {

@Override
public Class<?> resolve(Class<?> klass, String path) {
return normalize(getField(klass, path));
}
@Override
public Class<?> resolve(Class<?> klass, String path) {
return normalize(getField(klass, path));
}

@Override
public Field getField(Class<?> klass, final String path) {
@Override
public Field getField(Class<?> klass, final String path) {

String[] fieldNames = path.split("\\.");
String[] fieldNames = path.split("\\.");

Field lastField = null;
Field lastField = null;

for (String fieldName : fieldNames) {
for (String fieldName : fieldNames) {

lastField = ReflectionUtils.findField(klass, fieldName);
lastField = ReflectionUtils.findField(klass, fieldName);

if (lastField != null) {
klass = normalize(lastField);
} else {
throw new IllegalArgumentException("Could not find field '" + fieldName + "' in " + klass);
}
if (lastField != null) {
klass = normalize(lastField);
} else {
throw new IllegalArgumentException("Could not find field '" + fieldName + "' in " + klass);
}

}
}

return lastField;
return lastField;

}
}

private Class<?> normalize(Field field) {
private Class<?> normalize(Field field) {

if (field.isAnnotationPresent(Id.class) && field.getType().equals(String.class)) {
return CustomObjectId.class;
}

if (field.getType().equals(UUID.class)) {
return CustomUUID.class;
}
if (field.getType().equals(LocalDateTime.class)
|| field.getType().equals(ZonedDateTime.class)
|| field.getType().equals(LocalDate.class)
|| field.getType().equals(java.util.Date.class)
|| field.getType().equals(Instant.class)) {
return StringCustomDateConverter.CustomDate.class;
}

if (Collection.class.isAssignableFrom(field.getType())) {
return getFirstTypeParameterOf(field);
} else if (field.getType().isArray()) {
return field.getType().getComponentType();
} else {
return field.getType();
}

if (field.isAnnotationPresent(Id.class) && field.getType().equals(String.class)) {
return CustomObjectId.class;
}

if (field.getType().equals(UUID.class)) {
return CustomUUID.class;
public boolean isIterable(Class<?> klass, String path) {
return isIterable(getField(klass, path));
}

if (Collection.class.isAssignableFrom(field.getType())) {
return getFirstTypeParameterOf(field);
} else if (field.getType().isArray()) {
return field.getType().getComponentType();
} else {
return field.getType();
private boolean isIterable(Field field) {
return Collection.class.isAssignableFrom(field.getType()) || field.getType().isArray();
}

}

private Class<?> getFirstTypeParameterOf(Field field) {
return (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
}
private Class<?> getFirstTypeParameterOf(Field field) {
return (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@
import com.turkraft.springfilter.parser.node.FieldNode;
import com.turkraft.springfilter.parser.node.InfixOperationNode;
import com.turkraft.springfilter.transformer.FilterJsonNodeTransformer;
import com.turkraft.springfilter.transformer.TransformerUtils;
import org.springframework.stereotype.Service;

@Service
public class JsonNodeHelperImpl implements JsonNodeHelper {

protected final ObjectMapper objectMapper;

protected final TransformerUtils transformerUtils;
protected final FieldTypeResolver fieldTypeResolver;

public JsonNodeHelperImpl(ObjectMapper objectMapper,
FieldTypeResolver fieldTypeResolver) {
FieldTypeResolver fieldTypeResolver,
TransformerUtils transformerUtils) {
this.objectMapper = objectMapper;
this.fieldTypeResolver = fieldTypeResolver;
this.transformerUtils = transformerUtils;
}

@Override
Expand All @@ -28,7 +31,7 @@ public ObjectNode wrapWithMongoExpression(JsonNode node) {

@Override
public JsonNode transform(FilterJsonNodeTransformer transformer, InfixOperationNode source,
String mongoOperator) {
String mongoOperator) {

if (source.getLeft() instanceof FieldNode fieldNode) {
transformer.registerTargetType(source.getRight(),
Expand All @@ -42,19 +45,20 @@ public JsonNode transform(FilterJsonNodeTransformer transformer, InfixOperationN

if (transformer.getRegisteredTargetType(source.getLeft()) != null) {
transformer.registerTargetType(source.getRight(),
transformer.getRegisteredTargetType(source.getLeft()));
transformer.getRegisteredTargetType(source.getLeft()));
} else if (transformer.getRegisteredTargetType(source.getRight()) != null) {
transformer.registerTargetType(source.getLeft(),
transformer.getRegisteredTargetType(source.getRight()));
transformer.getRegisteredTargetType(source.getRight()));
}

JsonNode rightResult = transformer.transform(source.getRight());

return transformer.getObjectMapper().createObjectNode().set(mongoOperator,
transformer.getObjectMapper().createArrayNode()
.add(leftResult)
.add(rightResult));
JsonNode result = transformer.getObjectMapper().createObjectNode().set(mongoOperator,
transformer.getObjectMapper().createArrayNode()
.add(leftResult)
.add(rightResult));

return transformerUtils.wrapArrays(transformer, result, source, mongoOperator);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public Class<JsonNode> getTargetType() {

@Override
public JsonNode transformField(FieldNode node) {
if(node.getName().contains("$this")) {
return objectMapper.createObjectNode().textNode("$" +node.getName());
}
Field field = fieldTypeResolver.getField(getEntityType(), node.getName());
if (field.isAnnotationPresent(Id.class)) {
return objectMapper.createObjectNode().textNode("$_id");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.turkraft.springfilter.transformer;

import com.fasterxml.jackson.databind.JsonNode;
import com.turkraft.springfilter.parser.node.InfixOperationNode;

public interface TransformerUtils {
JsonNode wrapArrays(FilterJsonNodeTransformer transformer, JsonNode node, InfixOperationNode source);

JsonNode wrapArraysRegex(FilterJsonNodeTransformer transformer, JsonNode node, InfixOperationNode source);

JsonNode wrapArrays(FilterJsonNodeTransformer transformer, JsonNode node, InfixOperationNode source, String mongoOperator);

JsonNode simplify(FilterJsonNodeTransformer transformer, JsonNode node);
}
Loading