This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new 647177e CAMEL-15199: RestDefinition relies on Class.getCanonicalName instead of Class.getName for in/out types 647177e is described below commit 647177ee65627fac7cdd41ca917185f30c81632a Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Wed Jun 17 00:57:04 2020 +0200 CAMEL-15199: RestDefinition relies on Class.getCanonicalName instead of Class.getName for in/out types --- .../jaxb/JaxbRestBindingJaxbDataFormatFactory.java | 53 ++++++++---- .../apache/camel/component/rest/RestProducer.java | 4 +- ...RestUndertowHttpPostJsonNestedPojoListTest.java | 95 ++++++++++++++++++++++ .../spi/RestBindingJaxbDataFormatFactory.java | 3 +- .../org/apache/camel/model/rest/delete.json | 4 +- .../resources/org/apache/camel/model/rest/get.json | 4 +- .../org/apache/camel/model/rest/head.json | 4 +- .../org/apache/camel/model/rest/patch.json | 4 +- .../org/apache/camel/model/rest/post.json | 4 +- .../resources/org/apache/camel/model/rest/put.json | 4 +- .../org/apache/camel/model/rest/restBinding.json | 4 +- .../org/apache/camel/model/rest/verb.json | 4 +- .../camel/model/rest/RestBindingDefinition.java | 38 ++++++++- .../apache/camel/model/rest/RestDefinition.java | 35 +++++++- .../apache/camel/model/rest/VerbDefinition.java | 40 ++++++++- .../camel/reifier/rest/RestBindingReifier.java | 42 +++++++--- 16 files changed, 287 insertions(+), 55 deletions(-) diff --git a/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbRestBindingJaxbDataFormatFactory.java b/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbRestBindingJaxbDataFormatFactory.java index 4ec05a0..aeab749 100644 --- a/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbRestBindingJaxbDataFormatFactory.java +++ b/components/camel-jaxb/src/main/java/org/apache/camel/converter/jaxb/JaxbRestBindingJaxbDataFormatFactory.java @@ -27,49 +27,72 @@ import org.apache.camel.spi.RestBindingJaxbDataFormatFactory; import org.apache.camel.spi.RestConfiguration; import org.apache.camel.spi.annotations.JdkService; import org.apache.camel.support.PropertyBindingSupport; +import org.apache.camel.util.StringHelper; /** * JAXB based {@link RestBindingJaxbDataFormatFactory}. */ @JdkService(RestBindingJaxbDataFormatFactory.FACTORY) public class JaxbRestBindingJaxbDataFormatFactory implements RestBindingJaxbDataFormatFactory { - @Override - public void setupJaxb(CamelContext camelContext, RestConfiguration config, String type, String outType, DataFormat jaxb, DataFormat outJaxb) throws Exception { + public void setupJaxb(CamelContext camelContext, RestConfiguration config, + String type, Class<?> typeClass, String outType, Class<?> outTypeClass, + DataFormat jaxb, DataFormat outJaxb) throws Exception { // lookup configurer PropertyConfigurer configurer = camelContext.adapt(ExtendedCamelContext.class).getConfigurerResolver().resolvePropertyConfigurer("jaxb-dataformat-configurer", camelContext); if (configurer == null) { throw new IllegalStateException("Cannot find configurer for dataformat: jaxb"); } + // + // IN + // + PropertyBindingSupport.Builder builder = PropertyBindingSupport.build() .withCamelContext(camelContext) .withConfigurer(configurer) .withTarget(jaxb); - if (type != null) { - String typeName = type.endsWith("[]") ? type.substring(0, type.length() - 2) : type; + + String typeName = null; + if (typeClass != null) { + typeName = typeClass.isArray() ? typeClass.getComponentType().getName() : typeClass.getName(); + } else if (type != null) { + typeName = type.endsWith("[]") ? type.substring(0, type.length() - 2) : type; + } + if (typeName != null) { builder.withProperty("contextPath", typeName); builder.withProperty("contextPathIsClassName", "true"); } + setAdditionalConfiguration(config, "xml.in.", builder); builder.bind(); - builder = PropertyBindingSupport.build() + // + // OUT + // + + PropertyBindingSupport.Builder outBuilder = PropertyBindingSupport.build() .withCamelContext(camelContext) .withConfigurer(configurer) .withTarget(outJaxb); - if (outType != null) { - String typeName = outType.endsWith("[]") ? outType.substring(0, outType.length() - 2) : outType; - builder.withProperty("contextPath", typeName); - builder.withProperty("contextPathIsClassName", "true"); - } else if (type != null) { + + String outTypeName = null; + if (outTypeClass != null) { + outTypeName = outTypeClass.isArray() ? outTypeClass.getComponentType().getName() : outTypeClass.getName(); + } else if (outType != null) { + outTypeName = outType.endsWith("[]") ? outType.substring(0, outType.length() - 2) : outType; + } else if (typeName != null) { // fallback and use the context from the input - String typeName = type.endsWith("[]") ? type.substring(0, type.length() - 2) : type; - builder.withProperty("contextPath", typeName); - builder.withProperty("contextPathIsClassName", "true"); + outTypeName = typeName; } - setAdditionalConfiguration(config, "xml.out.", builder); - builder.bind(); + + if (outTypeName != null) { + outBuilder.withProperty("contextPath", outTypeName); + outBuilder.withProperty("contextPathIsClassName", "true"); + } + + setAdditionalConfiguration(config, "xml.out.", outBuilder); + outBuilder.bind(); } private void setAdditionalConfiguration(RestConfiguration config, String prefix, PropertyBindingSupport.Builder builder) throws Exception { diff --git a/components/camel-rest/src/main/java/org/apache/camel/component/rest/RestProducer.java b/components/camel-rest/src/main/java/org/apache/camel/component/rest/RestProducer.java index 1336e66..1ae664a 100644 --- a/components/camel-rest/src/main/java/org/apache/camel/component/rest/RestProducer.java +++ b/components/camel-rest/src/main/java/org/apache/camel/component/rest/RestProducer.java @@ -206,7 +206,7 @@ public class RestProducer extends DefaultAsyncProducer { // method String method = getEndpoint().getMethod(); if (method != null) { - // the method should be in upper case + // the method should be in upper case String upper = method.toUpperCase(Locale.US); inMessage.setHeader(Exchange.HTTP_METHOD, upper); } @@ -357,7 +357,7 @@ public class RestProducer extends DefaultAsyncProducer { if (jaxb != null) { // to setup JAXB we need to use camel-jaxb camelContext.adapt(ExtendedCamelContext.class).getRestBindingJaxbDataFormatFactory() - .setupJaxb(camelContext, configuration, type, outType, jaxb, outJaxb); + .setupJaxb(camelContext, configuration, type, null, outType, null, jaxb, outJaxb); } return new RestProducerBindingProcessor(producer, camelContext, json, jaxb, outJson, outJaxb, mode, skip, outType); diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpPostJsonNestedPojoListTest.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpPostJsonNestedPojoListTest.java new file mode 100644 index 0000000..e6658c1 --- /dev/null +++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowHttpPostJsonNestedPojoListTest.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.undertow.rest; + +import java.util.List; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.component.undertow.BaseUndertowTest; +import org.apache.camel.model.rest.RestBindingMode; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class RestUndertowHttpPostJsonNestedPojoListTest extends BaseUndertowTest { + + @Test + public void testPostPojoList() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:input"); + mock.expectedMessageCount(1); + + String body = "[ {\"id\": 123, \"name\": \"Donald Duck\"}, {\"id\": 456, \"name\": \"John Doe\"} ]"; + template.sendBody("undertow:http://localhost:{{port}}/users/new", body); + + assertMockEndpointsSatisfied(); + + List<?> list = mock.getReceivedExchanges().get(0).getIn().getBody(List.class); + assertNotNull(list); + assertEquals(2, list.size()); + + MyUserPojo user = (MyUserPojo) list.get(0); + assertEquals(123, user.getId()); + assertEquals("Donald Duck", user.getName()); + user = (MyUserPojo) list.get(1); + assertEquals(456, user.getId()); + assertEquals("John Doe", user.getName()); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + // configure to use undertow on localhost with the given port + // and enable auto binding mode + restConfiguration() + .component("undertow") + .host("localhost") + .port(getPort()) + .bindingMode(RestBindingMode.auto); + + // use the rest DSL to define the rest services + rest("/users/") + .post("new").type(MyUserPojo[].class) + .to("mock:input"); + } + }; + } + + public static class MyUserPojo { + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/RestBindingJaxbDataFormatFactory.java b/core/camel-api/src/main/java/org/apache/camel/spi/RestBindingJaxbDataFormatFactory.java index 74e91fd..7472585 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/RestBindingJaxbDataFormatFactory.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/RestBindingJaxbDataFormatFactory.java @@ -32,6 +32,7 @@ public interface RestBindingJaxbDataFormatFactory { * Setup XML data format */ void setupJaxb(CamelContext camelContext, RestConfiguration config, - String type, String outType, DataFormat jaxb, DataFormat outJaxb) throws Exception; + String type, Class<?> typeClass, String outType, Class<?> outTypeClass, + DataFormat jaxb, DataFormat outJaxb) throws Exception; } diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/delete.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/delete.json index 3801557..76eb409 100644 --- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/delete.json +++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/delete.json @@ -19,8 +19,8 @@ "skipBindingOnErrorCode": { "kind": "attribute", "displayName": "Skip Binding On Error Code", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise will do. This option will override what may be configured on a parent level" }, "clientRequestValidation": { "kind": "attribute", "displayName": "Client Request Validation", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable validation of the client request to check whether the Content-Type and Accept headers from the client is supported by the Rest-DSL configuration of its consumes\/produces settings. This can be turned on, to enable this check. In case of validation error [...] "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable CORS headers in the HTTP response. This option will override what may be configured on a parent level The default value is false." }, - "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, - "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, + "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, + "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, "toOrRoute": { "kind": "element", "displayName": "To Or Route", "required": true, "type": "object", "javaType": "org.apache.camel.model.OptionalIdentifiedDefinition<java.lang.Object>", "oneOf": [ "route", "to", "toD" ], "deprecated": false, "secret": false, "description": "To route from this REST service to a Camel endpoint, or an inlined route" }, "routeId": { "kind": "attribute", "displayName": "Route Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The route id this rest-dsl is using (read-only)" }, "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to include or exclude the VerbDefinition in API documentation. The default value is true." }, diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/get.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/get.json index e974ab9..a9ed1ba 100644 --- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/get.json +++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/get.json @@ -19,8 +19,8 @@ "skipBindingOnErrorCode": { "kind": "attribute", "displayName": "Skip Binding On Error Code", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise will do. This option will override what may be configured on a parent level" }, "clientRequestValidation": { "kind": "attribute", "displayName": "Client Request Validation", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable validation of the client request to check whether the Content-Type and Accept headers from the client is supported by the Rest-DSL configuration of its consumes\/produces settings. This can be turned on, to enable this check. In case of validation error [...] "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable CORS headers in the HTTP response. This option will override what may be configured on a parent level The default value is false." }, - "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, - "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, + "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, + "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, "toOrRoute": { "kind": "element", "displayName": "To Or Route", "required": true, "type": "object", "javaType": "org.apache.camel.model.OptionalIdentifiedDefinition<java.lang.Object>", "oneOf": [ "route", "to", "toD" ], "deprecated": false, "secret": false, "description": "To route from this REST service to a Camel endpoint, or an inlined route" }, "routeId": { "kind": "attribute", "displayName": "Route Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The route id this rest-dsl is using (read-only)" }, "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to include or exclude the VerbDefinition in API documentation. The default value is true." }, diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/head.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/head.json index eebe7de..9853f1b 100644 --- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/head.json +++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/head.json @@ -19,8 +19,8 @@ "skipBindingOnErrorCode": { "kind": "attribute", "displayName": "Skip Binding On Error Code", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise will do. This option will override what may be configured on a parent level" }, "clientRequestValidation": { "kind": "attribute", "displayName": "Client Request Validation", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable validation of the client request to check whether the Content-Type and Accept headers from the client is supported by the Rest-DSL configuration of its consumes\/produces settings. This can be turned on, to enable this check. In case of validation error [...] "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable CORS headers in the HTTP response. This option will override what may be configured on a parent level The default value is false." }, - "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, - "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, + "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, + "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, "toOrRoute": { "kind": "element", "displayName": "To Or Route", "required": true, "type": "object", "javaType": "org.apache.camel.model.OptionalIdentifiedDefinition<java.lang.Object>", "oneOf": [ "route", "to", "toD" ], "deprecated": false, "secret": false, "description": "To route from this REST service to a Camel endpoint, or an inlined route" }, "routeId": { "kind": "attribute", "displayName": "Route Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The route id this rest-dsl is using (read-only)" }, "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to include or exclude the VerbDefinition in API documentation. The default value is true." }, diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/patch.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/patch.json index 3273011..d96350d 100644 --- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/patch.json +++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/patch.json @@ -19,8 +19,8 @@ "skipBindingOnErrorCode": { "kind": "attribute", "displayName": "Skip Binding On Error Code", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise will do. This option will override what may be configured on a parent level" }, "clientRequestValidation": { "kind": "attribute", "displayName": "Client Request Validation", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable validation of the client request to check whether the Content-Type and Accept headers from the client is supported by the Rest-DSL configuration of its consumes\/produces settings. This can be turned on, to enable this check. In case of validation error [...] "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable CORS headers in the HTTP response. This option will override what may be configured on a parent level The default value is false." }, - "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, - "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, + "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, + "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, "toOrRoute": { "kind": "element", "displayName": "To Or Route", "required": true, "type": "object", "javaType": "org.apache.camel.model.OptionalIdentifiedDefinition<java.lang.Object>", "oneOf": [ "route", "to", "toD" ], "deprecated": false, "secret": false, "description": "To route from this REST service to a Camel endpoint, or an inlined route" }, "routeId": { "kind": "attribute", "displayName": "Route Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The route id this rest-dsl is using (read-only)" }, "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to include or exclude the VerbDefinition in API documentation. The default value is true." }, diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/post.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/post.json index 08119b5..597345d 100644 --- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/post.json +++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/post.json @@ -19,8 +19,8 @@ "skipBindingOnErrorCode": { "kind": "attribute", "displayName": "Skip Binding On Error Code", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise will do. This option will override what may be configured on a parent level" }, "clientRequestValidation": { "kind": "attribute", "displayName": "Client Request Validation", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable validation of the client request to check whether the Content-Type and Accept headers from the client is supported by the Rest-DSL configuration of its consumes\/produces settings. This can be turned on, to enable this check. In case of validation error [...] "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable CORS headers in the HTTP response. This option will override what may be configured on a parent level The default value is false." }, - "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, - "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, + "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, + "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, "toOrRoute": { "kind": "element", "displayName": "To Or Route", "required": true, "type": "object", "javaType": "org.apache.camel.model.OptionalIdentifiedDefinition<java.lang.Object>", "oneOf": [ "route", "to", "toD" ], "deprecated": false, "secret": false, "description": "To route from this REST service to a Camel endpoint, or an inlined route" }, "routeId": { "kind": "attribute", "displayName": "Route Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The route id this rest-dsl is using (read-only)" }, "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to include or exclude the VerbDefinition in API documentation. The default value is true." }, diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/put.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/put.json index 15d370b..61b105d 100644 --- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/put.json +++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/put.json @@ -19,8 +19,8 @@ "skipBindingOnErrorCode": { "kind": "attribute", "displayName": "Skip Binding On Error Code", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise will do. This option will override what may be configured on a parent level" }, "clientRequestValidation": { "kind": "attribute", "displayName": "Client Request Validation", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable validation of the client request to check whether the Content-Type and Accept headers from the client is supported by the Rest-DSL configuration of its consumes\/produces settings. This can be turned on, to enable this check. In case of validation error [...] "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable CORS headers in the HTTP response. This option will override what may be configured on a parent level The default value is false." }, - "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, - "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, + "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, + "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, "toOrRoute": { "kind": "element", "displayName": "To Or Route", "required": true, "type": "object", "javaType": "org.apache.camel.model.OptionalIdentifiedDefinition<java.lang.Object>", "oneOf": [ "route", "to", "toD" ], "deprecated": false, "secret": false, "description": "To route from this REST service to a Camel endpoint, or an inlined route" }, "routeId": { "kind": "attribute", "displayName": "Route Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The route id this rest-dsl is using (read-only)" }, "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to include or exclude the VerbDefinition in API documentation. The default value is true." }, diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/restBinding.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/restBinding.json index 72cd2f4..18b414f 100644 --- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/restBinding.json +++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/restBinding.json @@ -14,8 +14,8 @@ "consumes": { "kind": "attribute", "displayName": "Consumes", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "To define the content type what the REST service consumes (accept as input), such as application\/xml or application\/json" }, "produces": { "kind": "attribute", "displayName": "Produces", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "To define the content type what the REST service produces (uses for output), such as application\/xml or application\/json" }, "bindingMode": { "kind": "attribute", "displayName": "Binding Mode", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "defaultValue": "off", "description": "Sets the binding mode to use. The default value is off" }, - "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, - "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, + "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, + "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, "skipBindingOnErrorCode": { "kind": "attribute", "displayName": "Skip Binding On Error Code", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise will do." }, "clientRequestValidation": { "kind": "attribute", "displayName": "Client Request Validation", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable validation of the client request to check whether the Content-Type and Accept headers from the client is supported by the Rest-DSL configuration of its consumes\/produces settings. This can be turned on, to enable this check. In case of validation error [...] "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable CORS headers in the HTTP response. The default value is false." }, diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/verb.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/verb.json index 0515aea..fa4f8ae 100644 --- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/verb.json +++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/rest/verb.json @@ -19,8 +19,8 @@ "skipBindingOnErrorCode": { "kind": "attribute", "displayName": "Skip Binding On Error Code", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to skip binding on output if there is a custom HTTP error code header. This allows to build custom error messages that do not bind to json \/ xml etc, as success messages otherwise will do. This option will override what may be configured on a parent level" }, "clientRequestValidation": { "kind": "attribute", "displayName": "Client Request Validation", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable validation of the client request to check whether the Content-Type and Accept headers from the client is supported by the Rest-DSL configuration of its consumes\/produces settings. This can be turned on, to enable this check. In case of validation error [...] "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable CORS headers in the HTTP response. This option will override what may be configured on a parent level The default value is false." }, - "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, - "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The canonical name of the class of the input data. Append a to the end of the canonical name if you want the input to be an array type." }, + "type": { "kind": "attribute", "displayName": "Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from input to POJO for the incoming data This option will override what may be configured on a parent level. The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, + "outType": { "kind": "attribute", "displayName": "Out Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the class name to use for binding from POJO to output for the outgoing data This option will override what may be configured on a parent level The name of the class of the input data. Append a to the end of the name if you want the input to be an array type." }, "toOrRoute": { "kind": "element", "displayName": "To Or Route", "required": true, "type": "object", "javaType": "org.apache.camel.model.OptionalIdentifiedDefinition<java.lang.Object>", "oneOf": [ "route", "to", "toD" ], "deprecated": false, "secret": false, "description": "To route from this REST service to a Camel endpoint, or an inlined route" }, "routeId": { "kind": "attribute", "displayName": "Route Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The route id this rest-dsl is using (read-only)" }, "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to include or exclude the VerbDefinition in API documentation. The default value is true." }, diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/RestBindingDefinition.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/RestBindingDefinition.java index 8c7ffc0..1db0bb5 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/RestBindingDefinition.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/RestBindingDefinition.java @@ -63,9 +63,15 @@ public class RestBindingDefinition extends OptionalIdentifiedDefinition<RestBind @XmlAttribute private String type; + @XmlTransient + private Class<?> typeClass; + @XmlAttribute private String outType; + @XmlTransient + private Class<?> outTypeClass; + @XmlAttribute private String skipBindingOnErrorCode; @@ -202,13 +208,25 @@ public class RestBindingDefinition extends OptionalIdentifiedDefinition<RestBind * Sets the class name to use for binding from input to POJO for the * incoming data * <p/> - * The canonical name of the class of the input data. Append a [] to the end - * of the canonical name if you want the input to be an array type. + * The name of the class of the input data. Append a [] to the end + * of the name if you want the input to be an array type. */ public void setType(String type) { this.type = type; } + public Class<?> getTypeClass() { + return typeClass; + } + + /** + * Sets the class to use for binding from input to POJO for the + * incoming data + */ + public void setTypeClass(Class<?> typeClass) { + this.typeClass = typeClass; + } + public String getOutType() { return outType; } @@ -217,13 +235,25 @@ public class RestBindingDefinition extends OptionalIdentifiedDefinition<RestBind * Sets the class name to use for binding from POJO to output for the * outgoing data * <p/> - * The canonical name of the class of the input data. Append a [] to the end - * of the canonical name if you want the input to be an array type. + * The name of the class of the input data. Append a [] to the end + * of the name if you want the input to be an array type. */ public void setOutType(String outType) { this.outType = outType; } + public Class<?> getOutTypeClass() { + return outTypeClass; + } + + /** + * Sets the class name to use for binding from POJO to output for the + * outgoing data + */ + public void setOutTypeClass(Class<?> outTypeClass) { + this.outTypeClass = outTypeClass; + } + public String getSkipBindingOnErrorCode() { return skipBindingOnErrorCode; } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/RestDefinition.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/RestDefinition.java index 2b4b98e..fcb6aaa 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/RestDefinition.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/RestDefinition.java @@ -460,7 +460,7 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition> } VerbDefinition verb = getVerbs().get(getVerbs().size() - 1); - verb.setType(classType.getCanonicalName()); + verb.setType(asTypeName(classType)); return this; } @@ -471,7 +471,7 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition> } VerbDefinition verb = getVerbs().get(getVerbs().size() - 1); - verb.setOutType(classType.getCanonicalName()); + verb.setOutType(asTypeName(classType)); return this; } @@ -697,6 +697,33 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition> } } + protected String asTypeName(Class<?> classType) { + // Workaround for https://issues.apache.org/jira/browse/CAMEL-15199 + // + // The VerbDefinition::setType and VerbDefinition::setOutType require + // the class to be expressed as canonical with an optional [] to mark + // the type is an array but this i wrong as the canonical name can not + // be dynamically be loaded by the classloader thus this workaround + // that for nested classes generates a class name that does not respect + // any JLS convention. + // + // TODO: this probably need to be revisited + + String type; + + if (!classType.isPrimitive()) { + if (classType.isArray()) { + type = StringHelper.between(classType.getName(), "[L", ";") + "[]"; + } else { + type = classType.getName(); + } + } else { + type = classType.getCanonicalName(); + } + + return type; + } + /** * Transforms the rest api configuration into a * {@link org.apache.camel.model.RouteDefinition} which Camel routing engine @@ -763,7 +790,9 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition> RestBindingDefinition binding = new RestBindingDefinition(); binding.setComponent(component); binding.setType(verb.getType()); + binding.setTypeClass(verb.getTypeClass()); binding.setOutType(verb.getOutType()); + binding.setOutTypeClass(verb.getOutTypeClass()); // verb takes precedence over configuration on rest if (verb.getConsumes() != null) { binding.setConsumes(verb.getConsumes()); @@ -798,7 +827,7 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition> for (RestOperationParamDefinition param : verb.getParams()) { // register all the default values for the query and header parameters RestParamType type = param.getType(); - if ((RestParamType.query == type || RestParamType.header == type) + if ((RestParamType.query == type || RestParamType.header == type) && ObjectHelper.isNotEmpty(param.getDefaultValue())) { binding.addDefaultValue(param.getName(), param.getDefaultValue()); } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/VerbDefinition.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/VerbDefinition.java index 065ac5e..71b2775 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/VerbDefinition.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/rest/VerbDefinition.java @@ -79,9 +79,15 @@ public class VerbDefinition extends OptionalIdentifiedDefinition<VerbDefinition> @XmlAttribute private String type; + @XmlTransient + private Class<?> typeClass; + @XmlAttribute private String outType; + @XmlTransient + private Class<?> outTypeClass; + // used by XML DSL to either select a <to>, <toD>, or <route> // so we need to use the common type OptionalIdentifiedDefinition // must select one of them, and hence why they are all set to required = @@ -271,13 +277,26 @@ public class VerbDefinition extends OptionalIdentifiedDefinition<VerbDefinition> * incoming data This option will override what may be configured on a * parent level. * <p/> - * The canonical name of the class of the input data. Append a [] to the end - * of the canonical name if you want the input to be an array type. + * The name of the class of the input data. Append a [] to the end + * of the name if you want the input to be an array type. */ public void setType(String type) { this.type = type; } + public Class<?> getTypeClass() { + return typeClass; + } + + /** + * Sets the class to use for binding from input to POJO for the + * incoming data This option will override what may be configured on a + * parent level. + */ + public void setTypeClass(Class<?> typeClass) { + this.typeClass = typeClass; + } + public String getOutType() { return outType; } @@ -287,13 +306,26 @@ public class VerbDefinition extends OptionalIdentifiedDefinition<VerbDefinition> * outgoing data This option will override what may be configured on a * parent level * <p/> - * The canonical name of the class of the input data. Append a [] to the end - * of the canonical name if you want the input to be an array type. + * The name of the class of the input data. Append a [] to the end + * of the name if you want the input to be an array type. */ public void setOutType(String outType) { this.outType = outType; } + public Class<?> getOutTypeClass() { + return outTypeClass; + } + + /** + * Sets the class to use for binding from POJO to output for the + * outgoing data This option will override what may be configured on a + * parent level. + */ + public void setOutTypeClass(Class<?> outTypeClass) { + this.outTypeClass = outTypeClass; + } + public String getRouteId() { return routeId; } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java index 233cc50..27eb682 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java @@ -91,7 +91,11 @@ public class RestBindingReifier extends AbstractReifier { outJson = camelContext.resolveDataFormat(name); if (json != null) { - setupJson(config, parseString(definition.getType()), parseString(definition.getOutType()), json, outJson); + setupJson( + config, + parseString(definition.getType()), definition.getTypeClass(), + parseString(definition.getOutType()), definition.getOutTypeClass(), + json, outJson); } } @@ -121,8 +125,11 @@ public class RestBindingReifier extends AbstractReifier { if (jaxb != null) { // to setup JAXB we need to use camel-jaxb - camelContext.adapt(ExtendedCamelContext.class).getRestBindingJaxbDataFormatFactory() - .setupJaxb(camelContext, config, parseString(definition.getType()), parseString(definition.getOutType()), jaxb, outJaxb); + camelContext.adapt(ExtendedCamelContext.class).getRestBindingJaxbDataFormatFactory().setupJaxb( + camelContext, config, + parseString(definition.getType()), definition.getTypeClass(), + parseString(definition.getOutType()), definition.getOutTypeClass(), + jaxb, outJaxb); } } @@ -133,27 +140,42 @@ public class RestBindingReifier extends AbstractReifier { definition.getRequiredQueryParameters(), definition.getRequiredHeaders()); } - protected void setupJson(RestConfiguration config, String type, String outType, DataFormat json, DataFormat outJson) throws Exception { + protected void setupJson(RestConfiguration config, String type, Class<?> typeClass, String outType, Class<?> outTypeClass, DataFormat json, DataFormat outJson) throws Exception { Class<?> clazz = null; - if (type != null) { - String typeName = type.endsWith("[]") ? type.substring(0, type.length() - 2) : type; + boolean useList = false; + + if (typeClass != null) { + useList = typeClass.isArray(); + clazz = useList ? typeClass.getComponentType() : typeClass; + } else if (type != null) { + useList = type.endsWith("[]"); + String typeName = useList ? type.substring(0, type.length() - 2) : type; clazz = camelContext.getClassResolver().resolveMandatoryClass(typeName); } if (clazz != null) { camelContext.adapt(ExtendedCamelContext.class).getBeanIntrospection().setProperty(camelContext, json, "unmarshalType", clazz); - camelContext.adapt(ExtendedCamelContext.class).getBeanIntrospection().setProperty(camelContext, json, "useList", type.endsWith("[]")); + camelContext.adapt(ExtendedCamelContext.class).getBeanIntrospection().setProperty(camelContext, json, "useList", useList); } + setAdditionalConfiguration(config, json, "json.in."); Class<?> outClazz = null; - if (outType != null) { - String typeName = outType.endsWith("[]") ? outType.substring(0, outType.length() - 2) : outType; + boolean outUseList = false; + + if (outTypeClass != null) { + outUseList = outTypeClass.isArray(); + outClazz = outUseList ? outTypeClass.getComponentType() : outTypeClass; + } else if (outType != null) { + outUseList = outType.endsWith("[]"); + String typeName = outUseList ? outType.substring(0, outType.length() - 2) : outType; outClazz = camelContext.getClassResolver().resolveMandatoryClass(typeName); } + if (outClazz != null) { camelContext.adapt(ExtendedCamelContext.class).getBeanIntrospection().setProperty(camelContext, outJson, "unmarshalType", outClazz); - camelContext.adapt(ExtendedCamelContext.class).getBeanIntrospection().setProperty(camelContext, outJson, "useList", outType.endsWith("[]")); + camelContext.adapt(ExtendedCamelContext.class).getBeanIntrospection().setProperty(camelContext, outJson, "useList", outUseList); } + setAdditionalConfiguration(config, outJson, "json.out."); }