INT-4538: Fix Splitter for ArrayNode.size()

JIRA: https://jira.spring.io/browse/INT-4538

* Add support for Jackson `TreeNode.size()` in the `AbstractMessageSplitter`
* Add overloaded `Transformers.toJson(ObjectToJsonTransformer.ResultType)`
* Modify test to verify Jackson `ArrayNode` use-case with the splitter
and aggregator

**Cherry-pick to 5.0.x**
This commit is contained in:
Artem Bilan
2018-10-05 15:25:27 -04:00
committed by Gary Russell
parent c4d6cf2b50
commit 716494c7fb
4 changed files with 49 additions and 10 deletions

View File

@@ -117,6 +117,17 @@ public abstract class Transformers {
return toJson(jsonObjectMapper, null, contentType);
}
/**
* Factory for the {@link ObjectToJsonTransformer} based on the provided {@link ObjectToJsonTransformer.ResultType}.
* @param resultType the {@link ObjectToJsonTransformer.ResultType} to use.
* Defaults to {@link ObjectToJsonTransformer.ResultType#STRING}.
* @return the ObjectToJsonTransformer
* @since 5.0.9
*/
public static ObjectToJsonTransformer toJson(ObjectToJsonTransformer.ResultType resultType) {
return toJson(null, resultType, null);
}
public static ObjectToJsonTransformer toJson(ObjectToJsonTransformer.ResultType resultType, String contentType) {
return toJson(null, resultType, contentType);
}

View File

@@ -31,9 +31,11 @@ import org.reactivestreams.Publisher;
import org.springframework.integration.channel.ReactiveStreamsSubscribableChannel;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
import org.springframework.integration.support.json.JacksonPresent;
import org.springframework.integration.util.FunctionIterator;
import org.springframework.messaging.Message;
import com.fasterxml.jackson.core.TreeNode;
import reactor.core.publisher.Flux;
/**
@@ -163,12 +165,21 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess
/**
* Obtain a size of the provided {@link Iterable}. Default implementation returns
* {@link Collection#size()} if the iterable is a collection, or {@code 0} otherwise.
* If iterable is a Jackson {@code TreeNode}, then its size is used.
* @param iterable the {@link Iterable} to obtain the size
* @return the size of the {@link Iterable}
* @since 5.0
*/
protected int obtainSizeIfPossible(Iterable<?> iterable) {
return iterable instanceof Collection ? ((Collection<?>) iterable).size() : 0;
if (iterable instanceof Collection) {
return ((Collection<?>) iterable).size();
}
else if (JacksonPresent.isJackson2Present() && JacksonNodeHelper.isNode(iterable)) {
return JacksonNodeHelper.nodeSize(iterable);
}
else {
return 0;
}
}
/**
@@ -266,4 +277,18 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess
*/
protected abstract Object splitMessage(Message<?> message);
private static class JacksonNodeHelper {
private static boolean isNode(Object object) {
return object instanceof TreeNode;
}
@SuppressWarnings("unchecked")
private static int nodeSize(Object node) {
return ((TreeNode) node).size();
}
}
}