This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 11c4244 CAMEL-17101: Split EIP should support splitting a java.util.Map into a Set<Map.Entry> - so it works out of the box, and what you would assume Camel can do. Fixed some other components that was using the faulty behavioiur of createIterable. 11c4244 is described below commit 11c42447f875f430f39761d3878626a781869d17 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed Oct 20 20:48:30 2021 +0200 CAMEL-17101: Split EIP should support splitting a java.util.Map into a Set<Map.Entry> - so it works out of the box, and what you would assume Camel can do. Fixed some other components that was using the faulty behavioiur of createIterable. --- .../apache/camel/dataformat/beanio/BeanIODataFormat.java | 7 ++++++- .../camel/dataformat/bindy/csv/BindyCsvDataFormat.java | 6 ++++++ .../bindy/fixed/BindyFixedLengthDataFormat.java | 6 ++++++ .../dataformat/bindy/kvp/BindyKeyValuePairDataFormat.java | 8 +++++--- .../org/apache/camel/dataformat/csv/CsvMarshaller.java | 13 +++++++++---- .../CsvMarshalHeaderWithCustomMarshallFactoryTest.java | 11 ++++++++--- .../org/apache/camel/component/elsql/ElsqlProducer.java | 7 ++++++- .../camel/jsonpath/JsonPathSplitWriteAsStringMapTest.java | 15 +++++++-------- 8 files changed, 53 insertions(+), 20 deletions(-) diff --git a/components/camel-beanio/src/main/java/org/apache/camel/dataformat/beanio/BeanIODataFormat.java b/components/camel-beanio/src/main/java/org/apache/camel/dataformat/beanio/BeanIODataFormat.java index d501147..1ff1892 100644 --- a/components/camel-beanio/src/main/java/org/apache/camel/dataformat/beanio/BeanIODataFormat.java +++ b/components/camel-beanio/src/main/java/org/apache/camel/dataformat/beanio/BeanIODataFormat.java @@ -25,6 +25,7 @@ import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Properties; import org.apache.camel.CamelContext; @@ -143,7 +144,11 @@ public class BeanIODataFormat extends ServiceSupport implements DataFormat, Data @SuppressWarnings("unchecked") private List<Object> getModels(Exchange exchange, Object body) { List<Object> models; - if ((models = exchange.getContext().getTypeConverter().convertTo(List.class, body)) == null) { + + if (body instanceof Map && isUnmarshalSingleObject()) { + models = new ArrayList<>(); + models.add(body); + } else if ((models = exchange.getContext().getTypeConverter().convertTo(List.class, body)) == null) { models = new ArrayList<>(); for (Object model : ObjectHelper.createIterable(body)) { models.add(model); diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/csv/BindyCsvDataFormat.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/csv/BindyCsvDataFormat.java index 055d147..93c1681 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/csv/BindyCsvDataFormat.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/csv/BindyCsvDataFormat.java @@ -23,6 +23,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -90,6 +91,11 @@ public class BindyCsvDataFormat extends BindyAbstractDataFormat { // the body is not a prepared list of map that bindy expects so help a // bit here and create one for us + if (body instanceof Map) { + // the body is already a map, and we do not want to iterate each element in the map, + // but keep the body as a map, so wrap as iterator + body = Collections.singleton(body).iterator(); + } for (Object model : ObjectHelper.createIterable(body)) { if (model instanceof Map) { models.add((Map<String, Object>) model); diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java index 5152f34..192754f 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/fixed/BindyFixedLengthDataFormat.java @@ -20,6 +20,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -80,6 +81,11 @@ public class BindyFixedLengthDataFormat extends BindyAbstractDataFormat { // the body is not a prepared list so help a bit here and create one for us if (!isPreparedList(body)) { models = new ArrayList<>(); + if (body instanceof Map) { + // the body is already a map, and we do not want to iterate each element in the map, + // but keep the body as a map, so wrap as iterator + body = Collections.singleton(body).iterator(); + } for (Object model : ObjectHelper.createIterable(body)) { String name = model.getClass().getName(); Map<String, Object> row = new HashMap<>(); diff --git a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/kvp/BindyKeyValuePairDataFormat.java b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/kvp/BindyKeyValuePairDataFormat.java index 2cb40d7..429f798 100644 --- a/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/kvp/BindyKeyValuePairDataFormat.java +++ b/components/camel-bindy/src/main/java/org/apache/camel/dataformat/bindy/kvp/BindyKeyValuePairDataFormat.java @@ -74,17 +74,19 @@ public class BindyKeyValuePairDataFormat extends BindyAbstractDataFormat { // the body may not be a prepared list of map that bindy expects so help // a bit here and create one if needed + if (body instanceof Map) { + // the body is already a map, and we do not want to iterate each element in the map, + // but keep the body as a map, so wrap as iterator + body = Collections.singleton(body).iterator(); + } for (Object model : ObjectHelper.createIterable(body)) { - Map<String, Object> row; if (model instanceof Map) { row = (Map<String, Object>) model; } else { row = Collections.singletonMap(model.getClass().getName(), model); } - String result = factory.unbind(getCamelContext(), row); - outputStream.write(converter.convertTo(byte[].class, exchange, result)); outputStream.write(crlf); } diff --git a/components/camel-csv/src/main/java/org/apache/camel/dataformat/csv/CsvMarshaller.java b/components/camel-csv/src/main/java/org/apache/camel/dataformat/csv/CsvMarshaller.java index 4a974ad..77e1d9f 100644 --- a/components/camel-csv/src/main/java/org/apache/camel/dataformat/csv/CsvMarshaller.java +++ b/components/camel-csv/src/main/java/org/apache/camel/dataformat/csv/CsvMarshaller.java @@ -80,10 +80,15 @@ public abstract class CsvMarshaller { throws NoTypeConversionAvailableException, IOException { CSVPrinter printer = createPrinter(exchange, outputStream); try { - Iterator it = ObjectHelper.createIterator(object); - while (it.hasNext()) { - Object child = it.next(); - printer.printRecord(getRecordValues(exchange, child)); + if (object instanceof Map) { + Map map = (Map) object; + printer.printRecord(getMapRecordValues(map)); + } else { + Iterator it = ObjectHelper.createIterator(object); + while (it.hasNext()) { + Object child = it.next(); + printer.printRecord(getRecordValues(exchange, child)); + } } } finally { IOHelper.close(printer); diff --git a/components/camel-csv/src/test/java/org/apache/camel/dataformat/csv/CsvMarshalHeaderWithCustomMarshallFactoryTest.java b/components/camel-csv/src/test/java/org/apache/camel/dataformat/csv/CsvMarshalHeaderWithCustomMarshallFactoryTest.java index baddf7c..00ef106 100644 --- a/components/camel-csv/src/test/java/org/apache/camel/dataformat/csv/CsvMarshalHeaderWithCustomMarshallFactoryTest.java +++ b/components/camel-csv/src/test/java/org/apache/camel/dataformat/csv/CsvMarshalHeaderWithCustomMarshallFactoryTest.java @@ -132,10 +132,15 @@ public class CsvMarshalHeaderWithCustomMarshallFactoryTest extends CamelTestSupp @Override @SuppressWarnings("unchecked") public void marshal(Exchange exchange, Object object, OutputStream outputStream) throws IOException { - Iterator<Map<String, String>> it = (Iterator<Map<String, String>>) ObjectHelper.createIterator(object); synchronized (printer) { - while (it.hasNext()) { - printer.printRecord(getMapRecordValues(it.next())); + if (object instanceof Map) { + Map map = (Map) object; + printer.printRecord(getMapRecordValues(map)); + } else { + Iterator<Map<String, String>> it = (Iterator<Map<String, String>>) ObjectHelper.createIterator(object); + while (it.hasNext()) { + printer.printRecord(getMapRecordValues(it.next())); + } } // Access the 'Appendable' StringBuilder stringBuilder = (StringBuilder) printer.getOut(); diff --git a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlProducer.java b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlProducer.java index ea2c7b7..9901a3b 100644 --- a/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlProducer.java +++ b/components/camel-elsql/src/main/java/org/apache/camel/component/elsql/ElsqlProducer.java @@ -20,8 +20,10 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.sql.DataSource; @@ -109,7 +111,10 @@ public class ElsqlProducer extends DefaultProducer { final String sqlForDefaultPreparedStamentStrategy = sql.replace(":", ":?"); final String preparedQuery = sqlPrepareStatementStrategy.prepareQuery( sqlForDefaultPreparedStamentStrategy, getEndpoint().isAllowNamedParameters(), exchange); - final Iterator<?> iterator = exchange.getIn().getBody(Iterator.class); + // if the body is a map then it's the key/values for a statement, so do not iterate each map entry. + Object body = exchange.getIn().getBody(); + final Iterator<?> iterator = body instanceof Map + ? Collections.singleton(body).iterator() : exchange.getIn().getBody(Iterator.class); while (iterator != null && iterator.hasNext()) { final Object value = iterator.next(); final Iterator<?> i = sqlPrepareStatementStrategy.createPopulateIterator( diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathSplitWriteAsStringMapTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathSplitWriteAsStringMapTest.java index c5be405..399ab14 100644 --- a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathSplitWriteAsStringMapTest.java +++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathSplitWriteAsStringMapTest.java @@ -45,20 +45,19 @@ public class JsonPathSplitWriteAsStringMapTest extends CamelTestSupport { @Test public void testSplitToJSon() throws Exception { MockEndpoint mock = getMockEndpoint("mock:line"); - // we only get 1 map (because we split via: $.content) but each entry is converted to a json string - mock.expectedMessageCount(1); + mock.expectedMessageCount(2); template.sendBody("direct:start", new File("src/test/resources/content-map.json")); assertMockEndpointsSatisfied(); - Map map = mock.getReceivedExchanges().get(0).getIn().getBody(Map.class); + Map.Entry<?, ?> row = mock.getReceivedExchanges().get(0).getIn().getBody(Map.Entry.class); + assertEquals("foo", row.getKey()); + assertEquals("{\"action\":\"CU\",\"id\":123,\"modifiedTime\":\"2015-07-28T11:40:09.520+02:00\"}", row.getValue()); - String foo = (String) map.get("foo"); - assertEquals("{\"action\":\"CU\",\"id\":123,\"modifiedTime\":\"2015-07-28T11:40:09.520+02:00\"}", foo); - - String bar = (String) map.get("bar"); - assertEquals("{\"action\":\"CU\",\"id\":456,\"modifiedTime\":\"2015-07-28T11:42:29.510+02:00\"}", bar); + row = mock.getReceivedExchanges().get(1).getIn().getBody(Map.Entry.class); + assertEquals("bar", row.getKey()); + assertEquals("{\"action\":\"CU\",\"id\":456,\"modifiedTime\":\"2015-07-28T11:42:29.510+02:00\"}", row.getValue()); } }