Peer review

This commit is contained in:
René Pfeuffer
2018-06-07 10:04:28 +02:00
parent 62711700f9
commit e92616c6eb
9 changed files with 73 additions and 68 deletions

View File

@@ -9,6 +9,7 @@ import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -35,7 +36,7 @@ public class FieldContainerResponseFilter implements ContainerResponseFilter {
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
Optional<JsonNode> entity = getJsonEntity(responseContext);
if (entity.isPresent()) {
List<String> fields = extractFieldsFrom(requestContext);
Collection<String> fields = extractFieldsFrom(requestContext);
if (!fields.isEmpty()) {
JsonFilters.filterByFields(entity.get(), fields);
}
@@ -54,7 +55,7 @@ public class FieldContainerResponseFilter implements ContainerResponseFilter {
return entity instanceof JsonNode;
}
private List<String> extractFieldsFrom(ContainerRequestContext requestContext) {
private Collection<String> extractFieldsFrom(ContainerRequestContext requestContext) {
return getFieldParameterFrom(requestContext)
.orElse(emptyList())
.stream()
@@ -62,9 +63,9 @@ public class FieldContainerResponseFilter implements ContainerResponseFilter {
.collect(Collectors.toList());
}
private Optional<List<String>> getFieldParameterFrom(ContainerRequestContext requestContext) {
private Optional<Collection<String>> getFieldParameterFrom(ContainerRequestContext requestContext) {
MultivaluedMap<String, String> queryParameters = requestContext.getUriInfo().getQueryParameters();
List<String> fieldParameters = queryParameters.get(PARAMETER_FIELDS);
Collection<String> fieldParameters = queryParameters.get(PARAMETER_FIELDS);
return ofNullable(fieldParameters);
}
}

View File

@@ -5,66 +5,72 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Maps;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import static java.util.Arrays.stream;
public final class JsonFilters {
private JsonFilters() {
}
public static void filterByFields(JsonNode root, Iterable<String> fields) {
filterNode(createJsonFilterNode(fields), root);
public static void filterByFields(JsonNode root, Collection<String> filterExpressions) {
createJsonFilterNode(filterExpressions).filterNode(root);
}
private static JsonFilterNode createJsonFilterNode(Iterable<String> fields) {
private static JsonFilterNode createJsonFilterNode(Collection<String> filterExpressions) {
JsonFilterNode rootFilterNode = new JsonFilterNode();
for (String field : fields) {
appendFilterNode(rootFilterNode, field);
}
filterExpressions.stream()
.map(JsonFilterNode::expressionPartIterator)
.forEach(rootFilterNode::appendFilterExpression);
return rootFilterNode;
}
private static void appendFilterNode(JsonFilterNode rootFilterNode, String field) {
JsonFilterNode filterNode = rootFilterNode;
for (String part : field.split("\\.")) {
filterNode = filterNode.addOrGet(part);
}
}
private static void filterNode(JsonFilterNode filter, JsonNode node) {
if (node.isObject()) {
filterObjectNode(filter, (ObjectNode) node);
} else if (node.isArray()) {
filterArrayNode(filter, (ArrayNode) node);
}
}
private static void filterObjectNode(JsonFilterNode filter, ObjectNode objectNode) {
Iterator<Map.Entry<String,JsonNode>> entryIterator = objectNode.fields();
while (entryIterator.hasNext()) {
Map.Entry<String,JsonNode> entry = entryIterator.next();
JsonFilterNode childFilter = filter.get(entry.getKey());
if (childFilter == null) {
entryIterator.remove();
} else if (!childFilter.isLeaf()) {
filterNode(childFilter, entry.getValue());
}
}
}
private static void filterArrayNode(JsonFilterNode filter, ArrayNode arrayNode) {
for (int i=0; i<arrayNode.size(); i++) {
filterNode(filter, arrayNode.get(i));
}
}
private static class JsonFilterNode {
private final Map<String,JsonFilterNode> children = Maps.newHashMap();
JsonFilterNode addOrGet(String name) {
private static Iterator<String> expressionPartIterator(String filterExpression) {
return stream(filterExpression.split("\\.")).iterator();
}
private void appendFilterExpression(Iterator<String> fields) {
if (fields.hasNext()) {
addOrGet(fields.next()).appendFilterExpression(fields);
}
}
private void filterNode(JsonNode node) {
if (!isLeaf()) {
if (node.isObject()) {
filterObjectNode((ObjectNode) node);
} else if (node.isArray()) {
filterArrayNode((ArrayNode) node);
}
}
}
private void filterObjectNode(ObjectNode objectNode) {
Iterator<Map.Entry<String,JsonNode>> entryIterator = objectNode.fields();
while (entryIterator.hasNext()) {
Map.Entry<String,JsonNode> entry = entryIterator.next();
JsonFilterNode childFilter = get(entry.getKey());
if (childFilter == null) {
entryIterator.remove();
} else {
childFilter.filterNode(entry.getValue());
}
}
}
private void filterArrayNode(ArrayNode arrayNode) {
arrayNode.forEach(this::filterNode);
}
private JsonFilterNode addOrGet(String name) {
JsonFilterNode child = children.get(name);
if (child == null) {
child = new JsonFilterNode();

View File

@@ -48,9 +48,7 @@ public class JsonMarshallingResponseFilter implements ContainerResponseFilter {
node
);
for (JsonEnricher enricher : enrichers) {
enricher.enrich(context);
}
enrichers.forEach(enricher -> enricher.enrich(context));
}
private JsonNode getJsonEntity(ContainerResponseContext responseContext) {