This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch gs in repository https://gitbox.apache.org/repos/asf/camel.git
commit 2d2d0b061473a948c0fed27604c20b8a4558b180 Author: Claus Ibsen <[email protected]> AuthorDate: Fri Mar 6 16:44:29 2026 +0100 CAMEL-23001: camel-groovy - Add groovyJson data format --- .../apache/camel/catalog/components/aws2-ec2.json | 2 +- .../apache/camel/catalog/dataformats.properties | 1 + .../camel/catalog/dataformats/groovyJson.json | 22 ++ .../org/apache/camel/catalog/models.properties | 1 + .../catalog/models/dataFormatTransformer.json | 2 +- .../apache/camel/catalog/models/dataFormats.json | 2 +- .../apache/camel/catalog/models/groovyJSon.json | 19 ++ .../org/apache/camel/catalog/models/marshal.json | 2 +- .../org/apache/camel/catalog/models/unmarshal.json | 2 +- .../apache/camel/catalog/schemas/camel-spring.xsd | 13 + .../apache/camel/catalog/schemas/camel-xml-io.xsd | 13 + components/camel-groovy/pom.xml | 5 + .../json/GroovyJSonlDataFormatConfigurer.java | 63 ++++ .../org/apache/camel/groovy/json/groovyJson.json | 22 ++ .../apache/camel/configurer/groovyJson-dataformat | 2 + .../org/apache/camel/dataformat.properties | 2 +- .../org/apache/camel/dataformat/groovyJson | 2 + .../src/main/docs/groovyJson-dataformat.adoc | 106 +++++++ .../src/main/docs/groovyXml-dataformat.adoc | 5 +- .../camel/groovy/json/GroovyJSonlDataFormat.java | 82 +++++ .../apache/camel/groovy/json/NodeToJsonHelper.java | 98 ++++++ .../camel/groovy/xml/GroovyXmlDataFormat.java | 2 +- .../groovy/json/GroovyJSonDataFormatTest.java | 338 +++++++++++++++++++++ .../apache/camel/model/dataformat/dataFormats.json | 2 +- .../apache/camel/model/dataformat/groovyJSon.json | 19 ++ .../META-INF/org/apache/camel/model/marshal.json | 2 +- .../model/transformer/dataFormatTransformer.json | 2 +- .../META-INF/org/apache/camel/model/unmarshal.json | 2 +- .../services/org/apache/camel/model.properties | 1 + .../org/apache/camel/model/dataformat/jaxb.index | 1 + .../camel/builder/DataFormatBuilderFactory.java | 8 + .../org/apache/camel/builder/DataFormatClause.java | 9 + .../org/apache/camel/model/MarshalDefinition.java | 2 + .../apache/camel/model/UnmarshalDefinition.java | 2 + .../model/dataformat/DataFormatsDefinition.java | 1 + .../model/dataformat/GroovyJSonDataFormat.java | 118 +++++++ .../model/dataformat/GroovyXmlDataFormat.java | 2 +- .../DataFormatTransformerDefinition.java | 2 + .../reifier/dataformat/DataFormatReifier.java | 2 + .../dataformat/GroovyJSonDataFormatReifier.java | 36 +++ .../org/apache/camel/main/dataformats.properties | 1 + .../java/org/apache/camel/xml/in/ModelParser.java | 7 + .../java/org/apache/camel/xml/out/ModelWriter.java | 13 + .../org/apache/camel/yaml/out/ModelWriter.java | 13 + .../dataformats/examples/json/groovyJson.json | 1 + docs/components/modules/dataformats/nav.adoc | 1 + .../dataformats/pages/groovyJson-dataformat.adoc | 1 + .../dsl/yaml/deserializers/ModelDeserializers.java | 75 +++++ .../deserializers/ModelDeserializersResolver.java | 2 + .../generated/resources/schema/camelYamlDsl.json | 55 ++++ 50 files changed, 1171 insertions(+), 15 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-ec2.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-ec2.json index df0e53e90c0d..c009f6131c3b 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-ec2.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/aws2-ec2.json @@ -49,7 +49,7 @@ }, "headers": { "CamelAwsEC2ImageId": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "An image ID of the AWS marketplace", "constantName": "org.apache.camel.component.aws2.ec2.AWS2EC2Constants#IMAGE_ID" }, - "CamelAwsEC2InstanceType": { "index": 1, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "software.amazon.awssdk.services.ec2.model.InstanceType", "enum": [ "a1.medium", "a1.large", "a1.xlarge", "a1.2xlarge", "a1.4xlarge", "a1.metal", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "c5.large", "c5.xlarge", "c5.2xlarge", [...] + "CamelAwsEC2InstanceType": { "index": 1, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "software.amazon.awssdk.services.ec2.model.InstanceType", "enum": [ "a1.medium", "a1.large", "a1.xlarge", "a1.2xlarge", "a1.4xlarge", "a1.metal", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "c5.large", "c5.xlarge", "c5.2xlarge", [...] "CamelAwsEC2Operation": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The operation we want to perform", "constantName": "org.apache.camel.component.aws2.ec2.AWS2EC2Constants#OPERATION" }, "CamelAwsEC2InstanceMinCount": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The minimum number of instances we want to run.", "constantName": "org.apache.camel.component.aws2.ec2.AWS2EC2Constants#INSTANCE_MIN_COUNT" }, "CamelAwsEC2InstanceMaxCount": { "index": 4, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The maximum number of instances we want to run.", "constantName": "org.apache.camel.component.aws2.ec2.AWS2EC2Constants#INSTANCE_MAX_COUNT" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats.properties index ba3381db70dd..1b8b6f52b65b 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats.properties +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats.properties @@ -17,6 +17,7 @@ fhirXml flatpack fory grok +groovyJson groovyXml gson gzipDeflater diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/groovyJson.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/groovyJson.json new file mode 100644 index 000000000000..855cd0eb1297 --- /dev/null +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/groovyJson.json @@ -0,0 +1,22 @@ +{ + "dataformat": { + "kind": "dataformat", + "name": "groovyJson", + "title": "Groovy JSon", + "description": "Transform between JSon and java.util.Map or java.util.List objects.", + "deprecated": false, + "firstVersion": "4.19.0", + "label": "dataformat,transformation,json", + "javaType": "org.apache.camel.groovy.json.GroovyJSonlDataFormat", + "supportLevel": "Preview", + "groupId": "org.apache.camel", + "artifactId": "camel-groovy", + "version": "4.19.0-SNAPSHOT", + "modelName": "groovyJson", + "modelJavaType": "org.apache.camel.model.dataformat.GroovyJSonDataFormat" + }, + "properties": { + "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }, + "prettyPrint": { "index": 1, "kind": "attribute", "displayName": "Pretty Print", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "To pretty printing output nicely formatted. Is by default true." } + } +} diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties index 4f8ad8b3caeb..b1e2082ed026 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties @@ -58,6 +58,7 @@ globalOption globalOptions grok groovy +groovyJSon groovyXml gzipDeflater head diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormatTransformer.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormatTransformer.json index 7d8367e89550..4c637534d422 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormatTransformer.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormatTransformer.json @@ -12,7 +12,7 @@ "output": false }, "properties": { - "dataFormatType": { "index": 0, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", "parque [...] + "dataFormatType": { "index": 0, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...] "scheme": { "index": 1, "kind": "attribute", "displayName": "Scheme", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Set a scheme name supported by the transformer. If you specify 'csv', the transformer will be picked up for all of 'csv' from\/to Java transformation. Note that the scheme matching is performed only when no exactly matched transformer exists." }, "name": { "index": 2, "kind": "attribute", "displayName": "Name", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Set the transformer name under which the transformer gets referenced when specifying the input\/output data type on routes. If you specify a transformer name that matches a data type scheme like 'csv' the transformer will be picked up for all of 'csv:' from\/t [...] "fromType": { "index": 3, "kind": "attribute", "displayName": "From Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Set the 'from' data type name. If you specify 'xml:XYZ', the transformer will be picked up if source type is 'xml:XYZ'. If you specify just 'xml', the transformer matches with all of 'xml' source type like 'xml:ABC' or 'xml:DEF'." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormats.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormats.json index ad5bb7bbe94b..9450e439b965 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormats.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/dataFormats.json @@ -12,6 +12,6 @@ "output": false }, "properties": { - "dataFormats": { "index": 0, "kind": "element", "displayName": "Data Formats", "group": "common", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.DataFormatDefinition>", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", [...] + "dataFormats": { "index": 0, "kind": "element", "displayName": "Data Formats", "group": "common", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.DataFormatDefinition>", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "m [...] } } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/groovyJSon.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/groovyJSon.json new file mode 100644 index 000000000000..3cd013b55775 --- /dev/null +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/groovyJSon.json @@ -0,0 +1,19 @@ +{ + "model": { + "kind": "model", + "name": "groovyJson", + "title": "Groovy JSon", + "description": "Transform between JSon and java.util.Map or java.util.List objects.", + "deprecated": false, + "firstVersion": "4.19.0", + "label": "dataformat,transformation,json", + "javaType": "org.apache.camel.model.dataformat.GroovyJSonDataFormat", + "abstract": false, + "input": false, + "output": false + }, + "properties": { + "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }, + "prettyPrint": { "index": 1, "kind": "attribute", "displayName": "Pretty Print", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "To pretty printing output nicely formatted. Is by default true." } + } +} diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/marshal.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/marshal.json index bcd99af51a31..aaa962a99230 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/marshal.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/marshal.json @@ -16,7 +16,7 @@ "note": { "index": 1, "kind": "attribute", "displayName": "Note", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the note of this node" }, "description": { "index": 2, "kind": "attribute", "displayName": "Description", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }, "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables this EIP from the route." }, - "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", "ocsf", [...] + "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...] "variableSend": { "index": 5, "kind": "attribute", "displayName": "Variable Send", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable as the source for the message body to send. This makes it handy to use variables for user data and to easily control what data to use for sending and receiving. Important: When using send variable then the message body is tak [...] "variableReceive": { "index": 6, "kind": "attribute", "displayName": "Variable Receive", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable to store the received message body (only body, not headers). This makes it handy to use variables for user data and to easily control what data to use for sending and receiving. Important: When using receive variable th [...] } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/unmarshal.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/unmarshal.json index c8ab481d6647..4b1e5972c828 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/unmarshal.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/unmarshal.json @@ -16,7 +16,7 @@ "note": { "index": 1, "kind": "attribute", "displayName": "Note", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the note of this node" }, "description": { "index": 2, "kind": "attribute", "displayName": "Description", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }, "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables this EIP from the route." }, - "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", "ocsf", [...] + "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...] "variableSend": { "index": 5, "kind": "attribute", "displayName": "Variable Send", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable as the source for the message body to send. This makes it handy to use variables for user data and to easily control what data to use for sending and receiving. Important: When using send variable then the message body is tak [...] "variableReceive": { "index": 6, "kind": "attribute", "displayName": "Variable Receive", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable to store the received message body (only body, not headers). This makes it handy to use variables for user data and to easily control what data to use for sending and receiving. Important: When using receive variable th [...] "allowNullBody": { "index": 7, "kind": "attribute", "displayName": "Allow Null Body", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Indicates whether null is allowed as value of a body to unmarshall." } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd index 6dafecd05b9d..fc56771c4396 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd @@ -611,6 +611,7 @@ Evaluates a Groovy script. </xs:documentation> </xs:annotation> </xs:element> + <xs:element name="groovyJson" type="tns:groovyJSonDataFormat"/> <xs:element name="groovyXml" type="tns:groovyXmlDataFormat"> <xs:annotation> <xs:documentation xml:lang="en"> @@ -7423,6 +7424,7 @@ messages, or any custom logic needed before the looping executes. <xs:element ref="tns:flatpack"/> <xs:element ref="tns:fory"/> <xs:element ref="tns:grok"/> + <xs:element ref="tns:groovyJson"/> <xs:element ref="tns:groovyXml"/> <xs:element ref="tns:gzipDeflater"/> <xs:element ref="tns:hl7"/> @@ -8831,6 +8833,14 @@ Whether to capture named expressions only or not (i.e. %{IP:ip} but not ${IP}). </xs:extension> </xs:complexContent> </xs:complexType> + <xs:complexType name="groovyJSonDataFormat"> + <xs:complexContent> + <xs:extension base="tns:dataFormat"> + <xs:sequence/> + <xs:attribute name="prettyPrint" type="xs:string"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> <xs:complexType name="groovyXmlDataFormat"> <xs:complexContent> <xs:extension base="tns:dataFormat"> @@ -14898,6 +14908,7 @@ To type used as a target data type in the transformation. <xs:element ref="tns:flatpack"/> <xs:element ref="tns:fory"/> <xs:element ref="tns:grok"/> + <xs:element ref="tns:groovyJson"/> <xs:element ref="tns:groovyXml"/> <xs:element ref="tns:gzipDeflater"/> <xs:element ref="tns:hl7"/> @@ -16329,6 +16340,7 @@ Sets the example. <xs:element ref="tns:flatpack"/> <xs:element ref="tns:fory"/> <xs:element ref="tns:grok"/> + <xs:element ref="tns:groovyJson"/> <xs:element ref="tns:groovyXml"/> <xs:element ref="tns:gzipDeflater"/> <xs:element ref="tns:hl7"/> @@ -17232,6 +17244,7 @@ Set the 'to' data type name. If you specify 'json:XYZ', the transformer will be <xs:element ref="tns:flatpack"/> <xs:element ref="tns:fory"/> <xs:element ref="tns:grok"/> + <xs:element ref="tns:groovyJson"/> <xs:element ref="tns:groovyXml"/> <xs:element ref="tns:gzipDeflater"/> <xs:element ref="tns:hl7"/> diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd index 54904046f298..04513b6000ad 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd @@ -566,6 +566,7 @@ Evaluates a Groovy script. </xs:documentation> </xs:annotation> </xs:element> + <xs:element name="groovyJson" type="tns:groovyJSonDataFormat"/> <xs:element name="groovyXml" type="tns:groovyXmlDataFormat"> <xs:annotation> <xs:documentation xml:lang="en"> @@ -6096,6 +6097,7 @@ messages, or any custom logic needed before the looping executes. <xs:element ref="tns:flatpack"/> <xs:element ref="tns:fory"/> <xs:element ref="tns:grok"/> + <xs:element ref="tns:groovyJson"/> <xs:element ref="tns:groovyXml"/> <xs:element ref="tns:gzipDeflater"/> <xs:element ref="tns:hl7"/> @@ -7504,6 +7506,14 @@ Whether to capture named expressions only or not (i.e. %{IP:ip} but not ${IP}). </xs:extension> </xs:complexContent> </xs:complexType> + <xs:complexType name="groovyJSonDataFormat"> + <xs:complexContent> + <xs:extension base="tns:dataFormat"> + <xs:sequence/> + <xs:attribute name="prettyPrint" type="xs:string"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> <xs:complexType name="groovyXmlDataFormat"> <xs:complexContent> <xs:extension base="tns:dataFormat"> @@ -13592,6 +13602,7 @@ To type used as a target data type in the transformation. <xs:element ref="tns:flatpack"/> <xs:element ref="tns:fory"/> <xs:element ref="tns:grok"/> + <xs:element ref="tns:groovyJson"/> <xs:element ref="tns:groovyXml"/> <xs:element ref="tns:gzipDeflater"/> <xs:element ref="tns:hl7"/> @@ -15023,6 +15034,7 @@ Sets the example. <xs:element ref="tns:flatpack"/> <xs:element ref="tns:fory"/> <xs:element ref="tns:grok"/> + <xs:element ref="tns:groovyJson"/> <xs:element ref="tns:groovyXml"/> <xs:element ref="tns:gzipDeflater"/> <xs:element ref="tns:hl7"/> @@ -15926,6 +15938,7 @@ Set the 'to' data type name. If you specify 'json:XYZ', the transformer will be <xs:element ref="tns:flatpack"/> <xs:element ref="tns:fory"/> <xs:element ref="tns:grok"/> + <xs:element ref="tns:groovyJson"/> <xs:element ref="tns:groovyXml"/> <xs:element ref="tns:gzipDeflater"/> <xs:element ref="tns:hl7"/> diff --git a/components/camel-groovy/pom.xml b/components/camel-groovy/pom.xml index 5771b2f1aabb..b6529e666ed2 100644 --- a/components/camel-groovy/pom.xml +++ b/components/camel-groovy/pom.xml @@ -50,6 +50,11 @@ <artifactId>groovy</artifactId> <version>${groovy-version}</version> </dependency> + <dependency> + <groupId>org.apache.groovy</groupId> + <artifactId>groovy-json</artifactId> + <version>${groovy-version}</version> + </dependency> <dependency> <groupId>org.apache.groovy</groupId> <artifactId>groovy-xml</artifactId> diff --git a/components/camel-groovy/src/generated/java/org/apache/camel/groovy/json/GroovyJSonlDataFormatConfigurer.java b/components/camel-groovy/src/generated/java/org/apache/camel/groovy/json/GroovyJSonlDataFormatConfigurer.java new file mode 100644 index 000000000000..dbb913c1fa36 --- /dev/null +++ b/components/camel-groovy/src/generated/java/org/apache/camel/groovy/json/GroovyJSonlDataFormatConfigurer.java @@ -0,0 +1,63 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.groovy.json; + +import javax.annotation.processing.Generated; +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.ExtendedPropertyConfigurerGetter; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.spi.ConfigurerStrategy; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.util.CaseInsensitiveMap; +import org.apache.camel.support.component.PropertyConfigurerSupport; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +@Generated("org.apache.camel.maven.packaging.PackageDataFormatMojo") +@SuppressWarnings("unchecked") +public class GroovyJSonlDataFormatConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, ExtendedPropertyConfigurerGetter { + + private static final Map<String, Object> ALL_OPTIONS; + static { + Map<String, Object> map = new CaseInsensitiveMap(); + map.put("PrettyPrint", boolean.class); + ALL_OPTIONS = map; + } + + @Override + public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { + GroovyJSonlDataFormat target = (GroovyJSonlDataFormat) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "prettyprint": + case "prettyPrint": target.setPrettyPrint(property(camelContext, boolean.class, value)); return true; + default: return false; + } + } + + @Override + public Map<String, Object> getAllOptions(Object target) { + return ALL_OPTIONS; + } + + @Override + public Class<?> getOptionType(String name, boolean ignoreCase) { + switch (ignoreCase ? name.toLowerCase() : name) { + case "prettyprint": + case "prettyPrint": return boolean.class; + default: return null; + } + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + GroovyJSonlDataFormat target = (GroovyJSonlDataFormat) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "prettyprint": + case "prettyPrint": return target.isPrettyPrint(); + default: return null; + } + } +} + diff --git a/components/camel-groovy/src/generated/resources/META-INF/org/apache/camel/groovy/json/groovyJson.json b/components/camel-groovy/src/generated/resources/META-INF/org/apache/camel/groovy/json/groovyJson.json new file mode 100644 index 000000000000..855cd0eb1297 --- /dev/null +++ b/components/camel-groovy/src/generated/resources/META-INF/org/apache/camel/groovy/json/groovyJson.json @@ -0,0 +1,22 @@ +{ + "dataformat": { + "kind": "dataformat", + "name": "groovyJson", + "title": "Groovy JSon", + "description": "Transform between JSon and java.util.Map or java.util.List objects.", + "deprecated": false, + "firstVersion": "4.19.0", + "label": "dataformat,transformation,json", + "javaType": "org.apache.camel.groovy.json.GroovyJSonlDataFormat", + "supportLevel": "Preview", + "groupId": "org.apache.camel", + "artifactId": "camel-groovy", + "version": "4.19.0-SNAPSHOT", + "modelName": "groovyJson", + "modelJavaType": "org.apache.camel.model.dataformat.GroovyJSonDataFormat" + }, + "properties": { + "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }, + "prettyPrint": { "index": 1, "kind": "attribute", "displayName": "Pretty Print", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "To pretty printing output nicely formatted. Is by default true." } + } +} diff --git a/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/configurer/groovyJson-dataformat b/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/configurer/groovyJson-dataformat new file mode 100644 index 000000000000..ffe79273d606 --- /dev/null +++ b/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/configurer/groovyJson-dataformat @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.groovy.json.GroovyJSonlDataFormatConfigurer diff --git a/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties b/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties index 768821ee4f0e..ae7c25de11fe 100644 --- a/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties +++ b/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties @@ -1,5 +1,5 @@ # Generated by camel build tools - do NOT edit this file! -dataFormats=groovyXml +dataFormats=groovyJson groovyXml groupId=org.apache.camel artifactId=camel-groovy version=4.19.0-SNAPSHOT diff --git a/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/dataformat/groovyJson b/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/dataformat/groovyJson new file mode 100644 index 000000000000..f1e4f749de66 --- /dev/null +++ b/components/camel-groovy/src/generated/resources/META-INF/services/org/apache/camel/dataformat/groovyJson @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.groovy.json.GroovyJSonlDataFormat diff --git a/components/camel-groovy/src/main/docs/groovyJson-dataformat.adoc b/components/camel-groovy/src/main/docs/groovyJson-dataformat.adoc new file mode 100644 index 000000000000..4d7de8aac7be --- /dev/null +++ b/components/camel-groovy/src/main/docs/groovyJson-dataformat.adoc @@ -0,0 +1,106 @@ += Groovy JSon DataFormat +:doctitle: Groovy JSon +:shortname: groovyJson +:artifactid: camel-groovy +:description: Transform between JSon and java.util.Map or java.util.List objects. +:since: 4.19 +:supportlevel: Preview +:tabs-sync-option: +//Manually maintained attributes +:camel-spring-boot-name: groovy + +*Since Camel {since}* + +The Groovy JSon data format is a basic data format to transform JSon to Map objects, +and back to JSon; using the Groovy JSon builder and slurper. + +This is convenient when working with JSon and using Groovy for data manipulation. + +This data format is limited in functionality but intended to be easier to use. +There are none or only a few options to configure. + +== Groovy XML Options + +// dataformat options: START +include::partial$dataformat-options.adoc[] +// dataformat options: END + +== Supported Java types + +This data format supports marshalling from the following Java type to JSon: + +- Groovy XML Node object (`groovy.util.Node`) (such as message body is from Groovy XML) +- Jackson Node object (`com.fasterxml.jackson.databind.JsonNode`) +- Camel JSonObject (`org.apache.camel.util.json.JsonObject`) +- Java Map object ('java.util.Map') +- Java List object ('java.util.List') + +And unmarshalling from JSon to (`java.util.Map`) / (`java.util.List`) object. + +== Examples + +For example to transform from JSon to `java.util.Map`: + +[source,yaml] +---- +- route: + description: From timer to json + from: + uri: timer + parameters: + repeatCount: "1" + timerName: tick + steps: + - setBody: + expression: + constant: + expression: |- + { + "library": { + "book": [ + { + "title": "No Title", + "author": "F. Scott Fitzgerald", + "year": "1925", + "genre": "Classic", + "id": "bk101" + }, + { + "title": "1984", + "author": "George Orwell", + "year": "1949", + "genre": "Dystopian", + "id": "bk102" + } + ] + } + } + - unmarshal: + groovyJson: {} + - log: + message: "${body}" +---- + +This will transform the JSon into a `java.util.Map` object which can be manipulated using Java and Groovy code. + +To convert back to JSon you just use the opposite direction with _marshal_. + +== Dependencies + +To use the data format in your camel routes, you need to add +a dependency on *camel-groovy* which implements this data format. + +If you use maven, you could just add the following to your pom.xml, +substituting the version number for the latest & greatest release (see +the download page for the latest versions). + +[source,xml] +---------------------------------------- +<dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-groovy</artifactId> + <version>x.x.x</version> +</dependency> +---------------------------------------- + +include::spring-boot:partial$starter.adoc[] diff --git a/components/camel-groovy/src/main/docs/groovyXml-dataformat.adoc b/components/camel-groovy/src/main/docs/groovyXml-dataformat.adoc index 0f324009ef7d..62a604f598f4 100644 --- a/components/camel-groovy/src/main/docs/groovyXml-dataformat.adoc +++ b/components/camel-groovy/src/main/docs/groovyXml-dataformat.adoc @@ -27,7 +27,7 @@ include::partial$dataformat-options.adoc[] This data format supports marshalling from the following Java type to XML: -- Groovy Node object (`groovy.util.Node`) +- Groovy XML Node object (`groovy.util.Node`) - Jackson Node object (`com.fasterxml.jackson.databind.JsonNode`) - Camel JSonObject (`org.apache.camel.util.json.JsonObject`) - Java Map object ('java.util.Map') @@ -67,8 +67,7 @@ For example to transform from XML to Groovy Node: </book> </library> - unmarshal: - groovyXml: - {} + groovyXml: {} - log: message: "${body}" ---- diff --git a/components/camel-groovy/src/main/java/org/apache/camel/groovy/json/GroovyJSonlDataFormat.java b/components/camel-groovy/src/main/java/org/apache/camel/groovy/json/GroovyJSonlDataFormat.java new file mode 100644 index 000000000000..28a211bb90c6 --- /dev/null +++ b/components/camel-groovy/src/main/java/org/apache/camel/groovy/json/GroovyJSonlDataFormat.java @@ -0,0 +1,82 @@ +/* + * 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.groovy.json; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +import groovy.json.JsonOutput; +import groovy.json.JsonSlurper; +import groovy.util.Node; +import org.apache.camel.Exchange; +import org.apache.camel.spi.DataFormat; +import org.apache.camel.spi.DataFormatName; +import org.apache.camel.spi.annotations.Dataformat; +import org.apache.camel.support.service.ServiceSupport; + +@Dataformat("groovyJson") +public class GroovyJSonlDataFormat extends ServiceSupport implements DataFormat, DataFormatName { + + private boolean prettyPrint = true; + + public boolean isPrettyPrint() { + return prettyPrint; + } + + public void setPrettyPrint(boolean prettyPrint) { + this.prettyPrint = prettyPrint; + } + + @Override + public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception { + if (graph instanceof Node n) { + graph = NodeToJsonHelper.nodeToJson(n); + } + if (graph instanceof Map map) { + serialize(map, stream); + } else { + // optional jackson support (TODO: jackson3) + if (graph.getClass().getName().startsWith("com.fasterxml.jackson.databind")) { + var map = exchange.getContext().getTypeConverter().convertTo(Map.class, exchange, graph); + serialize(map, stream); + } else { + byte[] arr = exchange.getContext().getTypeConverter().mandatoryConvertTo(byte[].class, exchange, graph); + stream.write(arr); + } + } + } + + @Override + public Object unmarshal(Exchange exchange, InputStream stream) throws Exception { + JsonSlurper parser = new JsonSlurper(); + return parser.parse(stream); + } + + @Override + public String getDataFormatName() { + return "groovyJson"; + } + + private void serialize(Map map, OutputStream stream) throws IOException { + String out = JsonOutput.toJson(map); + out = prettyPrint ? JsonOutput.prettyPrint(out) : JsonOutput.toJson(out); + stream.write(out.getBytes()); + } + +} diff --git a/components/camel-groovy/src/main/java/org/apache/camel/groovy/json/NodeToJsonHelper.java b/components/camel-groovy/src/main/java/org/apache/camel/groovy/json/NodeToJsonHelper.java new file mode 100644 index 000000000000..b88353b78a9b --- /dev/null +++ b/components/camel-groovy/src/main/java/org/apache/camel/groovy/json/NodeToJsonHelper.java @@ -0,0 +1,98 @@ +/* + * 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.groovy.json; + +import java.util.List; + +import groovy.util.Node; +import groovy.util.NodeList; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; + +class NodeToJsonHelper { + + public static JsonObject nodeToJson(Node rootNode) { + JsonObject jo = nodeToJsonObject(rootNode); + + JsonObject root = new JsonObject(); + root.put(rootNode.name().toString(), jo); + return root; + } + + private static JsonObject nodeToJsonObject(Node node) { + JsonObject result = new JsonObject(); + + // Add attributes + node.attributes().forEach((key, value) -> { + result.put(key.toString(), value); + }); + + // Process children + List<Node> children = node.children(); + if (!children.isEmpty()) { + if (children.size() == 1) { + var val = node.value(); + if (val instanceof NodeList nl) { + // flatten + val = nl.get(0); + } + result.put(node.name().toString(), val); + return result; + } + // Group children by name + children.stream() + .collect(java.util.stream.Collectors.groupingBy( + Node::name, + java.util.LinkedHashMap::new, + java.util.stream.Collectors.toList())) + .forEach((name, nodes) -> { + if (nodes.size() == 1) { + Node child = nodes.get(0); + Object value = convertChild(child); + if (value instanceof JsonObject jo) { + value = jo.get(name.toString()); + } + result.put(name.toString(), value); + } else { + JsonArray array = new JsonArray(); + nodes.forEach(child -> array.add(convertChild(child))); + result.put(name.toString(), array); + } + }); + } else { + // Leaf node with text content + String text = node.text(); + if (text != null && !text.trim().isEmpty()) { + JsonObject jo = new JsonObject(); + jo.put("#text", text.trim()); // or just return text + return jo; + } + } + + return result; + } + + private static Object convertChild(Node child) { + if (child.children().isEmpty()) { + String text = child.text(); + return text != null && !text.trim().isEmpty() ? text.trim() : null; + } else { + return nodeToJsonObject(child); + } + } + +} diff --git a/components/camel-groovy/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java b/components/camel-groovy/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java index fe98d5818280..75e53de2bf1a 100644 --- a/components/camel-groovy/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java +++ b/components/camel-groovy/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java @@ -64,7 +64,7 @@ public class GroovyXmlDataFormat extends ServiceSupport implements DataFormat, D } else if (graph instanceof Map map) { serialize(exchange, map, stream); } else { - // optional jackson support + // optional jackson support (TODO: jackson3) if (graph.getClass().getName().startsWith("com.fasterxml.jackson.databind")) { var map = exchange.getContext().getTypeConverter().convertTo(Map.class, exchange, graph); serialize(exchange, map, stream); diff --git a/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovyJSonDataFormatTest.java b/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovyJSonDataFormatTest.java new file mode 100644 index 000000000000..fb4f697fefec --- /dev/null +++ b/components/camel-groovy/src/test/java/org/apache/camel/groovy/json/GroovyJSonDataFormatTest.java @@ -0,0 +1,338 @@ +/* + * 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.groovy.json; + +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import groovy.json.JsonSlurper; +import groovy.util.Node; +import groovy.xml.XmlParser; +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit6.CamelTestSupport; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class GroovyJSonDataFormatTest extends CamelTestSupport { + + private static final String BOOKS + = """ + { + "library": { + "book": [ + { + "title": "No Title", + "author": "F. Scott Fitzgerald", + "year": "1925", + "genre": "Classic", + "id": "bk101" + }, + { + "title": "1984", + "author": "George Orwell", + "year": "1949", + "genre": "Dystopian", + "id": "bk102" + } + ] + } + } + """; + + private static final String BOOKS_XML + = """ + <library> + <book id="bk101"> + <title>No Title</title> + <author>F. Scott Fitzgerald</author> + <year>1925</year> + <genre>Classic</genre> + </book> + <book id="bk102"> + <title>1984</title> + <author>George Orwell</author> + <year>1949</year> + <genre>Dystopian</genre> + </book> + </library> + """; + + private static final String BOOKS_ID_TOP + = """ + { + "library": { + "book": [ + { + "id": "bk101", + "title": "No Title", + "author": "F. Scott Fitzgerald", + "year": "1925", + "genre": "Classic" + }, + { + "id": "bk102", + "title": "1984", + "author": "George Orwell", + "year": "1949", + "genre": "Dystopian" + } + ] + } + } + """; + + private static final String BOOKS_NOT_PRETTY + = """ + "{\\"library\\":{\\"book\\":[{\\"title\\":\\"No Title\\",\\"author\\":\\"F. Scott Fitzgerald\\",\\"year\\":\\"1925\\",\\"genre\\":\\"Classic\\",\\"id\\":\\"bk101\\"},{\\"title\\":\\"1984\\",\\"author\\":\\"George Orwell\\",\\"year\\":\\"1949\\",\\"genre\\":\\"Dystopian\\",\\"id\\":\\"bk102\\"}]}}" + """; + + private static final String COUNTRIES + = """ + { + "countries": [ + { + "country": "Norway" + }, + { + "country": "Denmark" + }, + { + "country": "Sweden" + }, + { + "country": "Germany" + }, + { + "country": "Finland" + } + ] + } + """; + + private static final String JACKSON_COUNTRIES = """ + { + "countries": [ + { + "country": "Norway" + }, + { + "country": "Denmark" + }, + { + "country": "Sweden" + }, + { + "country": "Germany" + }, + { + "country": "Finland" + } + ] + } + """; + + @Test + public void testUnmarshal() throws Exception { + getMockEndpoint("mock:unmarshal").expectedMessageCount(1); + + Object out = template.requestBody("direct:unmarshal", BOOKS); + Assertions.assertNotNull(out); + Assertions.assertInstanceOf(Map.class, out); + + Map n = (Map) out; + n = (Map) n.get("library"); + List books = (List) n.get("book"); + Assertions.assertEquals(2, books.size()); + Map b1 = (Map) books.get(0); + Assertions.assertEquals("bk101", b1.get("id")); + Map b2 = (Map) books.get(1); + Assertions.assertEquals("bk102", b2.get("id")); + + MockEndpoint.assertIsSatisfied(context); + } + + @Test + public void testMarshal() throws Exception { + getMockEndpoint("mock:marshal").expectedMessageCount(1); + + JsonSlurper parser = new JsonSlurper(); + Map n = (Map) parser.parseText(BOOKS); + + Object out = template.requestBody("direct:marshal", n); + Assertions.assertNotNull(out); + Assertions.assertInstanceOf(byte[].class, out); + + String json = context.getTypeConverter().convertTo(String.class, out); + Assertions.assertEquals(BOOKS, json + "\n"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Test + public void testMarshalNotPretty() throws Exception { + getMockEndpoint("mock:marshal").expectedMessageCount(1); + + JsonSlurper parser = new JsonSlurper(); + Map n = (Map) parser.parseText(BOOKS); + + Object out = template.requestBody("direct:marshal-not-pretty", n); + Assertions.assertNotNull(out); + Assertions.assertInstanceOf(byte[].class, out); + + String json = context.getTypeConverter().convertTo(String.class, out); + Assertions.assertEquals(BOOKS_NOT_PRETTY, json + "\n"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Test + public void testMarshalCamelJSon() throws Exception { + getMockEndpoint("mock:marshal").expectedMessageCount(1); + + JsonObject root = new JsonObject(); + JsonArray arr = new JsonArray(); + JsonObject b1 = new JsonObject(); + b1.put("title", "No Title"); + b1.put("author", "F. Scott Fitzgerald"); + b1.put("year", "1925"); + b1.put("genre", "Classic"); + b1.put("id", "bk101"); + + JsonObject b2 = new JsonObject(); + b2.put("title", "1984"); + b2.put("author", "George Orwell"); + b2.put("year", "1949"); + b2.put("genre", "Dystopian"); + b2.put("id", "bk102"); + + arr.add(b1); + arr.add(b2); + JsonObject books = new JsonObject(); + books.put("book", arr); + root.put("library", books); + + Object out = template.requestBody("direct:marshal", root); + Assertions.assertNotNull(out); + Assertions.assertInstanceOf(byte[].class, out); + + String json = context.getTypeConverter().convertTo(String.class, out); + Assertions.assertEquals(BOOKS, json + "\n"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Test + public void testMarshalGroovyNode() throws Exception { + getMockEndpoint("mock:marshal").expectedMessageCount(1); + + XmlParser parser = new XmlParser(); + Node root = parser.parseText(BOOKS_XML); + + Object out = template.requestBody("direct:marshal", root); + Assertions.assertNotNull(out); + Assertions.assertInstanceOf(byte[].class, out); + + String json = context.getTypeConverter().convertTo(String.class, out); + Assertions.assertEquals(BOOKS_ID_TOP, json + "\n"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Test + public void testMarshalJacksonJSon() throws Exception { + getMockEndpoint("mock:marshal").expectedMessageCount(1); + + ObjectMapper om = new JsonMapper(); + JsonNode root = om.readTree(BOOKS); + + Object out = template.requestBody("direct:marshal", root); + Assertions.assertNotNull(out); + Assertions.assertInstanceOf(byte[].class, out); + + String json = context.getTypeConverter().convertTo(String.class, out); + Assertions.assertEquals(BOOKS, json + "\n"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Test + public void testUnmarshalArray() throws Exception { + getMockEndpoint("mock:unmarshal").expectedMessageCount(1); + + Object out = template.requestBody("direct:unmarshal", COUNTRIES); + Assertions.assertNotNull(out); + Assertions.assertInstanceOf(Map.class, out); + + Map n = (Map) out; + List list = (List) n.get("countries"); + Assertions.assertEquals(5, list.size()); + Assertions.assertEquals("{country=Norway}", list.get(0).toString()); + Assertions.assertEquals("{country=Denmark}", list.get(1).toString()); + Assertions.assertEquals("{country=Sweden}", list.get(2).toString()); + Assertions.assertEquals("{country=Germany}", list.get(3).toString()); + Assertions.assertEquals("{country=Finland}", list.get(4).toString()); + + MockEndpoint.assertIsSatisfied(context); + } + + @Test + public void testMarshalArrayJacksonJSon() throws Exception { + getMockEndpoint("mock:marshal").expectedMessageCount(1); + + ObjectMapper om = new JsonMapper(); + JsonNode root = om.readTree(COUNTRIES); + + Object out = template.requestBody("direct:marshal", root); + Assertions.assertNotNull(out); + Assertions.assertInstanceOf(byte[].class, out); + + String json = context.getTypeConverter().convertTo(String.class, out); + Assertions.assertEquals(JACKSON_COUNTRIES, json + "\n"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:marshal").streamCache(false) + .marshal().groovyJson() + .to("mock:marshal"); + + from("direct:unmarshal") + .unmarshal().groovyJson() + .to("mock:unmarshal"); + + dataFormat().groovyJson().prettyPrint(false).end(); + + from("direct:marshal-not-pretty").streamCache(false) + .marshal(dataFormat().groovyJson().prettyPrint(false).end()) + .to("mock:marshal"); + + } + }; + } +} diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/dataFormats.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/dataFormats.json index ad5bb7bbe94b..9450e439b965 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/dataFormats.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/dataFormats.json @@ -12,6 +12,6 @@ "output": false }, "properties": { - "dataFormats": { "index": 0, "kind": "element", "displayName": "Data Formats", "group": "common", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.DataFormatDefinition>", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", [...] + "dataFormats": { "index": 0, "kind": "element", "displayName": "Data Formats", "group": "common", "required": true, "type": "array", "javaType": "java.util.List<org.apache.camel.model.DataFormatDefinition>", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "m [...] } } diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/groovyJSon.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/groovyJSon.json new file mode 100644 index 000000000000..3cd013b55775 --- /dev/null +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/dataformat/groovyJSon.json @@ -0,0 +1,19 @@ +{ + "model": { + "kind": "model", + "name": "groovyJson", + "title": "Groovy JSon", + "description": "Transform between JSon and java.util.Map or java.util.List objects.", + "deprecated": false, + "firstVersion": "4.19.0", + "label": "dataformat,transformation,json", + "javaType": "org.apache.camel.model.dataformat.GroovyJSonDataFormat", + "abstract": false, + "input": false, + "output": false + }, + "properties": { + "id": { "index": 0, "kind": "attribute", "displayName": "Id", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }, + "prettyPrint": { "index": 1, "kind": "attribute", "displayName": "Pretty Print", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "To pretty printing output nicely formatted. Is by default true." } + } +} diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/marshal.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/marshal.json index bcd99af51a31..aaa962a99230 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/marshal.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/marshal.json @@ -16,7 +16,7 @@ "note": { "index": 1, "kind": "attribute", "displayName": "Note", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the note of this node" }, "description": { "index": 2, "kind": "attribute", "displayName": "Description", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }, "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables this EIP from the route." }, - "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", "ocsf", [...] + "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...] "variableSend": { "index": 5, "kind": "attribute", "displayName": "Variable Send", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable as the source for the message body to send. This makes it handy to use variables for user data and to easily control what data to use for sending and receiving. Important: When using send variable then the message body is tak [...] "variableReceive": { "index": 6, "kind": "attribute", "displayName": "Variable Receive", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable to store the received message body (only body, not headers). This makes it handy to use variables for user data and to easily control what data to use for sending and receiving. Important: When using receive variable th [...] } diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/transformer/dataFormatTransformer.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/transformer/dataFormatTransformer.json index 7d8367e89550..4c637534d422 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/transformer/dataFormatTransformer.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/transformer/dataFormatTransformer.json @@ -12,7 +12,7 @@ "output": false }, "properties": { - "dataFormatType": { "index": 0, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", "parque [...] + "dataFormatType": { "index": 0, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...] "scheme": { "index": 1, "kind": "attribute", "displayName": "Scheme", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Set a scheme name supported by the transformer. If you specify 'csv', the transformer will be picked up for all of 'csv' from\/to Java transformation. Note that the scheme matching is performed only when no exactly matched transformer exists." }, "name": { "index": 2, "kind": "attribute", "displayName": "Name", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Set the transformer name under which the transformer gets referenced when specifying the input\/output data type on routes. If you specify a transformer name that matches a data type scheme like 'csv' the transformer will be picked up for all of 'csv:' from\/t [...] "fromType": { "index": 3, "kind": "attribute", "displayName": "From Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Set the 'from' data type name. If you specify 'xml:XYZ', the transformer will be picked up if source type is 'xml:XYZ'. If you specify just 'xml', the transformer matches with all of 'xml' source type like 'xml:ABC' or 'xml:DEF'." }, diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/unmarshal.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/unmarshal.json index c8ab481d6647..4b1e5972c828 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/unmarshal.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/unmarshal.json @@ -16,7 +16,7 @@ "note": { "index": 1, "kind": "attribute", "displayName": "Note", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the note of this node" }, "description": { "index": 2, "kind": "attribute", "displayName": "Description", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }, "disabled": { "index": 3, "kind": "attribute", "displayName": "Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables this EIP from the route." }, - "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMultipart", "ocsf", [...] + "dataFormatType": { "index": 4, "kind": "element", "displayName": "Data Format Type", "group": "common", "required": true, "type": "object", "javaType": "org.apache.camel.model.DataFormatDefinition", "oneOf": [ "asn1", "avro", "barcode", "base64", "beanio", "bindy", "cbor", "crypto", "csv", "custom", "dfdl", "fhirJson", "fhirXml", "flatpack", "fory", "grok", "groovyJson", "groovyXml", "gzipDeflater", "hl7", "ical", "iso8583", "jacksonXml", "jaxb", "json", "jsonApi", "lzf", "mimeMulti [...] "variableSend": { "index": 5, "kind": "attribute", "displayName": "Variable Send", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable as the source for the message body to send. This makes it handy to use variables for user data and to easily control what data to use for sending and receiving. Important: When using send variable then the message body is tak [...] "variableReceive": { "index": 6, "kind": "attribute", "displayName": "Variable Receive", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a variable to store the received message body (only body, not headers). This makes it handy to use variables for user data and to easily control what data to use for sending and receiving. Important: When using receive variable th [...] "allowNullBody": { "index": 7, "kind": "attribute", "displayName": "Allow Null Body", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Indicates whether null is allowed as value of a body to unmarshall." } diff --git a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties index 34be514a8bef..9b05516a0d7b 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties +++ b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties @@ -59,6 +59,7 @@ globalOption globalOptions grok groovy +groovyJSon groovyXml gzipDeflater head diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/dataformat/jaxb.index b/core/camel-core-model/src/generated/resources/org/apache/camel/model/dataformat/jaxb.index index 62daa4f8cf51..70e177bf1ccb 100644 --- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/dataformat/jaxb.index +++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/dataformat/jaxb.index @@ -18,6 +18,7 @@ FhirXmlDataFormat FlatpackDataFormat ForyDataFormat GrokDataFormat +GroovyJSonDataFormat GroovyXmlDataFormat GzipDeflaterDataFormat HL7DataFormat diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatBuilderFactory.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatBuilderFactory.java index 5442232f5493..9ec7ed0dd856 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatBuilderFactory.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatBuilderFactory.java @@ -32,6 +32,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat; import org.apache.camel.model.dataformat.FlatpackDataFormat; import org.apache.camel.model.dataformat.ForyDataFormat; import org.apache.camel.model.dataformat.GrokDataFormat; +import org.apache.camel.model.dataformat.GroovyJSonDataFormat; import org.apache.camel.model.dataformat.GroovyXmlDataFormat; import org.apache.camel.model.dataformat.GzipDeflaterDataFormat; import org.apache.camel.model.dataformat.HL7DataFormat; @@ -180,6 +181,13 @@ public final class DataFormatBuilderFactory { return new GrokDataFormat.Builder(); } + /** + * Uses the Groovy JSon format + */ + public GroovyJSonDataFormat.Builder groovyJson() { + return new GroovyJSonDataFormat.Builder(); + } + /** * Uses the Groovy XML format */ diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java index 195ade328830..bb43ccfd07f5 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java @@ -37,6 +37,7 @@ import org.apache.camel.model.dataformat.FhirJsonDataFormat; import org.apache.camel.model.dataformat.FhirXmlDataFormat; import org.apache.camel.model.dataformat.ForyDataFormat; import org.apache.camel.model.dataformat.GrokDataFormat; +import org.apache.camel.model.dataformat.GroovyJSonDataFormat; import org.apache.camel.model.dataformat.GroovyXmlDataFormat; import org.apache.camel.model.dataformat.GzipDeflaterDataFormat; import org.apache.camel.model.dataformat.HL7DataFormat; @@ -340,6 +341,14 @@ public class DataFormatClause<T extends ProcessorDefinition<?>> { return dataFormat(grokDataFormat); } + /** + * Uses the Groovy JSon data format + */ + public T groovyJson() { + GroovyJSonDataFormat df = new GroovyJSonDataFormat(); + return dataFormat(df); + } + /** * Uses the Groovy XML data format */ diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/MarshalDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/MarshalDefinition.java index 41ae107fec40..2c6300f7349b 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/MarshalDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/MarshalDefinition.java @@ -39,6 +39,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat; import org.apache.camel.model.dataformat.FlatpackDataFormat; import org.apache.camel.model.dataformat.ForyDataFormat; import org.apache.camel.model.dataformat.GrokDataFormat; +import org.apache.camel.model.dataformat.GroovyJSonDataFormat; import org.apache.camel.model.dataformat.GroovyXmlDataFormat; import org.apache.camel.model.dataformat.GzipDeflaterDataFormat; import org.apache.camel.model.dataformat.HL7DataFormat; @@ -97,6 +98,7 @@ public class MarshalDefinition extends NoOutputDefinition<MarshalDefinition> imp @XmlElement(name = "flatpack", type = FlatpackDataFormat.class), @XmlElement(name = "fory", type = ForyDataFormat.class), @XmlElement(name = "grok", type = GrokDataFormat.class), + @XmlElement(name = "groovyJson", type = GroovyJSonDataFormat.class), @XmlElement(name = "groovyXml", type = GroovyXmlDataFormat.class), @XmlElement(name = "gzipDeflater", type = GzipDeflaterDataFormat.class), @XmlElement(name = "hl7", type = HL7DataFormat.class), diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/UnmarshalDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/UnmarshalDefinition.java index f40c8fafcd32..61cb2c3124dc 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/UnmarshalDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/UnmarshalDefinition.java @@ -39,6 +39,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat; import org.apache.camel.model.dataformat.FlatpackDataFormat; import org.apache.camel.model.dataformat.ForyDataFormat; import org.apache.camel.model.dataformat.GrokDataFormat; +import org.apache.camel.model.dataformat.GroovyJSonDataFormat; import org.apache.camel.model.dataformat.GroovyXmlDataFormat; import org.apache.camel.model.dataformat.GzipDeflaterDataFormat; import org.apache.camel.model.dataformat.HL7DataFormat; @@ -97,6 +98,7 @@ public class UnmarshalDefinition extends NoOutputDefinition<UnmarshalDefinition> @XmlElement(name = "flatpack", type = FlatpackDataFormat.class), @XmlElement(name = "fory", type = ForyDataFormat.class), @XmlElement(name = "grok", type = GrokDataFormat.class), + @XmlElement(name = "groovyJson", type = GroovyJSonDataFormat.class), @XmlElement(name = "groovyXml", type = GroovyXmlDataFormat.class), @XmlElement(name = "gzipDeflater", type = GzipDeflaterDataFormat.class), @XmlElement(name = "hl7", type = HL7DataFormat.class), diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java index 57581cf8e896..9ef703329455 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/DataFormatsDefinition.java @@ -60,6 +60,7 @@ public class DataFormatsDefinition implements CopyableDefinition<DataFormatsDefi @XmlElement(name = "flatpack", type = FlatpackDataFormat.class), @XmlElement(name = "fory", type = ForyDataFormat.class), @XmlElement(name = "grok", type = GrokDataFormat.class), + @XmlElement(name = "groovyJson", type = GroovyJSonDataFormat.class), @XmlElement(name = "groovyXml", type = GroovyXmlDataFormat.class), @XmlElement(name = "gzipDeflater", type = GzipDeflaterDataFormat.class), @XmlElement(name = "hl7", type = HL7DataFormat.class), diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyJSonDataFormat.java b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyJSonDataFormat.java new file mode 100644 index 000000000000..b563f34a1e19 --- /dev/null +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyJSonDataFormat.java @@ -0,0 +1,118 @@ +/* + * 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.model.dataformat; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlTransient; + +import org.apache.camel.builder.DataFormatBuilder; +import org.apache.camel.model.DataFormatDefinition; +import org.apache.camel.spi.Metadata; + +/** + * Transform between JSon and java.util.Map or java.util.List objects. + */ +@Metadata(firstVersion = "4.19.0", label = "dataformat,transformation,json", title = "Groovy JSon") +@XmlRootElement(name = "groovyJson") +@XmlAccessorType(XmlAccessType.FIELD) +public class GroovyJSonDataFormat extends DataFormatDefinition { + + @XmlAttribute + @Metadata(javaType = "java.lang.Boolean", defaultValue = "true") + private String prettyPrint; + + public GroovyJSonDataFormat() { + super("groovyJson"); + } + + protected GroovyJSonDataFormat(GroovyJSonDataFormat source) { + super(source); + this.prettyPrint = source.prettyPrint; + } + + private GroovyJSonDataFormat(Builder builder) { + this(); + this.prettyPrint = builder.prettyPrint; + } + + @Override + public GroovyJSonDataFormat copyDefinition() { + return new GroovyJSonDataFormat(this); + } + + public String getPrettyPrint() { + return prettyPrint; + } + + /** + * To pretty printing output nicely formatted. + * <p/> + * Is by default true. + */ + public void setPrettyPrint(String prettyPrint) { + this.prettyPrint = prettyPrint; + } + + public GroovyJSonDataFormat prettyPrint(boolean prettyPrint) { + return prettyPrint(Boolean.toString(prettyPrint)); + } + + public GroovyJSonDataFormat prettyPrint(String prettyPrint) { + this.prettyPrint = prettyPrint; + return this; + } + + @Override + public String toString() { + return "GroovyJSonDataFormat"; + } + + @XmlTransient + public static class Builder implements DataFormatBuilder<GroovyJSonDataFormat> { + + private String prettyPrint; + + /** + * To pretty printing output nicely formatted. + * <p/> + * Is by default true. + */ + public Builder prettyPrint(String prettyPrint) { + this.prettyPrint = prettyPrint; + return this; + } + + /** + * To pretty printing output nicely formatted. + * <p/> + * Is by default true. + */ + public Builder prettyPrint(boolean prettyPrint) { + this.prettyPrint = Boolean.toString(prettyPrint); + return this; + } + + @Override + public GroovyJSonDataFormat end() { + return new GroovyJSonDataFormat(this); + } + + } +} diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyXmlDataFormat.java b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyXmlDataFormat.java index d995129a037b..30c5edbe36ab 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyXmlDataFormat.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/dataformat/GroovyXmlDataFormat.java @@ -71,7 +71,7 @@ public class GroovyXmlDataFormat extends DataFormatDefinition { @Override public String toString() { - return "GroovyXmlDataFormat'"; + return "GroovyXmlDataFormat"; } @XmlTransient diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java index 7e794428b1ec..6d8be1e1e7be 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/transformer/DataFormatTransformerDefinition.java @@ -39,6 +39,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat; import org.apache.camel.model.dataformat.FlatpackDataFormat; import org.apache.camel.model.dataformat.ForyDataFormat; import org.apache.camel.model.dataformat.GrokDataFormat; +import org.apache.camel.model.dataformat.GroovyJSonDataFormat; import org.apache.camel.model.dataformat.GroovyXmlDataFormat; import org.apache.camel.model.dataformat.GzipDeflaterDataFormat; import org.apache.camel.model.dataformat.HL7DataFormat; @@ -97,6 +98,7 @@ public class DataFormatTransformerDefinition extends TransformerDefinition { @XmlElement(name = "flatpack", type = FlatpackDataFormat.class), @XmlElement(name = "fory", type = ForyDataFormat.class), @XmlElement(name = "grok", type = GrokDataFormat.class), + @XmlElement(name = "groovyJson", type = GroovyJSonDataFormat.class), @XmlElement(name = "groovyXml", type = GroovyXmlDataFormat.class), @XmlElement(name = "gzipDeflater", type = GzipDeflaterDataFormat.class), @XmlElement(name = "hl7", type = HL7DataFormat.class), diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/DataFormatReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/DataFormatReifier.java index 9c62ffedb2dd..5a7982e3a4d3 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/DataFormatReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/DataFormatReifier.java @@ -170,6 +170,8 @@ public abstract class DataFormatReifier<T extends DataFormatDefinition> extends return new ForyDataFormatReifier(camelContext, definition); } else if (definition instanceof GrokDataFormat) { return new GrokDataFormatReifier(camelContext, definition); + } else if (definition instanceof GroovyJSonDataFormat) { + return new GroovyJSonDataFormatReifier(camelContext, definition); } else if (definition instanceof GroovyXmlDataFormat) { return new GroovyXmlDataFormatReifier(camelContext, definition); } else if (definition instanceof GzipDeflaterDataFormat) { diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/GroovyJSonDataFormatReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/GroovyJSonDataFormatReifier.java new file mode 100644 index 000000000000..7c240218f88f --- /dev/null +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/GroovyJSonDataFormatReifier.java @@ -0,0 +1,36 @@ +/* + * 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.reifier.dataformat; + +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.model.DataFormatDefinition; +import org.apache.camel.model.dataformat.GroovyJSonDataFormat; + +public class GroovyJSonDataFormatReifier extends DataFormatReifier<GroovyJSonDataFormat> { + + public GroovyJSonDataFormatReifier(CamelContext camelContext, DataFormatDefinition definition) { + super(camelContext, (GroovyJSonDataFormat) definition); + } + + @Override + protected void prepareDataFormatConfig(Map<String, Object> properties) { + properties.put("prettyPrint", parseBoolean(definition.getPrettyPrint(), true)); + } + +} diff --git a/core/camel-main/src/generated/resources/org/apache/camel/main/dataformats.properties b/core/camel-main/src/generated/resources/org/apache/camel/main/dataformats.properties index ba3381db70dd..1b8b6f52b65b 100644 --- a/core/camel-main/src/generated/resources/org/apache/camel/main/dataformats.properties +++ b/core/camel-main/src/generated/resources/org/apache/camel/main/dataformats.properties @@ -17,6 +17,7 @@ fhirXml flatpack fory grok +groovyJson groovyXml gson gzipDeflater diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java index a785cc681083..4d643d6ae367 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java @@ -1743,6 +1743,12 @@ public class ModelParser extends BaseParser { default: yield identifiedTypeAttributeHandler().accept(def, key, val); }, noElementHandler(), noValueHandler()); } + protected GroovyJSonDataFormat doParseGroovyJSonDataFormat() throws IOException, XmlPullParserException { + return doParse(new GroovyJSonDataFormat(), (def, key, val) -> switch (key) { + case "prettyPrint": def.setPrettyPrint(val); yield true; + default: yield identifiedTypeAttributeHandler().accept(def, key, val); + }, noElementHandler(), noValueHandler()); + } protected GroovyXmlDataFormat doParseGroovyXmlDataFormat() throws IOException, XmlPullParserException { return doParse(new GroovyXmlDataFormat(), (def, key, val) -> switch (key) { case "attributeMapping": def.setAttributeMapping(val); yield true; @@ -2779,6 +2785,7 @@ public class ModelParser extends BaseParser { case "flatpack": return doParseFlatpackDataFormat(); case "fory": return doParseForyDataFormat(); case "grok": return doParseGrokDataFormat(); + case "groovyJson": return doParseGroovyJSonDataFormat(); case "groovyXml": return doParseGroovyXmlDataFormat(); case "gzipDeflater": return doParseGzipDeflaterDataFormat(); case "hl7": return doParseHL7DataFormat(); diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java index 73f5f229e401..11f7c4882240 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java @@ -434,6 +434,9 @@ public class ModelWriter extends BaseWriter { public void writeGrokDataFormat(GrokDataFormat def) throws IOException { doWriteGrokDataFormat("grok", def); } + public void writeGroovyJSonDataFormat(GroovyJSonDataFormat def) throws IOException { + doWriteGroovyJSonDataFormat("groovyJson", def); + } public void writeGroovyXmlDataFormat(GroovyXmlDataFormat def) throws IOException { doWriteGroovyXmlDataFormat("groovyXml", def); } @@ -1167,6 +1170,7 @@ public class ModelWriter extends BaseWriter { case "FlatpackDataFormat" -> doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v); case "ForyDataFormat" -> doWriteForyDataFormat("fory", (ForyDataFormat) v); case "GrokDataFormat" -> doWriteGrokDataFormat("grok", (GrokDataFormat) v); + case "GroovyJSonDataFormat" -> doWriteGroovyJSonDataFormat("groovyJson", (GroovyJSonDataFormat) v); case "GroovyXmlDataFormat" -> doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v); case "GzipDeflaterDataFormat" -> doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v); case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", (HL7DataFormat) v); @@ -1932,6 +1936,7 @@ public class ModelWriter extends BaseWriter { case "FlatpackDataFormat" -> doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v); case "ForyDataFormat" -> doWriteForyDataFormat("fory", (ForyDataFormat) v); case "GrokDataFormat" -> doWriteGrokDataFormat("grok", (GrokDataFormat) v); + case "GroovyJSonDataFormat" -> doWriteGroovyJSonDataFormat("groovyJson", (GroovyJSonDataFormat) v); case "GroovyXmlDataFormat" -> doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v); case "GzipDeflaterDataFormat" -> doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v); case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", (HL7DataFormat) v); @@ -2229,6 +2234,7 @@ public class ModelWriter extends BaseWriter { case "FlatpackDataFormat" -> doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v); case "ForyDataFormat" -> doWriteForyDataFormat("fory", (ForyDataFormat) v); case "GrokDataFormat" -> doWriteGrokDataFormat("grok", (GrokDataFormat) v); + case "GroovyJSonDataFormat" -> doWriteGroovyJSonDataFormat("groovyJson", (GroovyJSonDataFormat) v); case "GroovyXmlDataFormat" -> doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v); case "GzipDeflaterDataFormat" -> doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v); case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", (HL7DataFormat) v); @@ -2337,6 +2343,12 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("namedOnly", def.getNamedOnly(), null); endElement(name); } + protected void doWriteGroovyJSonDataFormat(String name, GroovyJSonDataFormat def) throws IOException { + startElement(name); + doWriteIdentifiedTypeAttributes(def); + doWriteAttribute("prettyPrint", def.getPrettyPrint(), "true"); + endElement(name); + } protected void doWriteGroovyXmlDataFormat(String name, GroovyXmlDataFormat def) throws IOException { startElement(name); doWriteIdentifiedTypeAttributes(def); @@ -3399,6 +3411,7 @@ public class ModelWriter extends BaseWriter { case "FlatpackDataFormat" -> doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v); case "ForyDataFormat" -> doWriteForyDataFormat("fory", (ForyDataFormat) v); case "GrokDataFormat" -> doWriteGrokDataFormat("grok", (GrokDataFormat) v); + case "GroovyJSonDataFormat" -> doWriteGroovyJSonDataFormat("groovyJson", (GroovyJSonDataFormat) v); case "GroovyXmlDataFormat" -> doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v); case "GzipDeflaterDataFormat" -> doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v); case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", (HL7DataFormat) v); diff --git a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java index d7c31c315287..b25508d86912 100644 --- a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java +++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java @@ -434,6 +434,9 @@ public class ModelWriter extends BaseWriter { public void writeGrokDataFormat(GrokDataFormat def) throws IOException { doWriteGrokDataFormat("grok", def); } + public void writeGroovyJSonDataFormat(GroovyJSonDataFormat def) throws IOException { + doWriteGroovyJSonDataFormat("groovyJson", def); + } public void writeGroovyXmlDataFormat(GroovyXmlDataFormat def) throws IOException { doWriteGroovyXmlDataFormat("groovyXml", def); } @@ -1167,6 +1170,7 @@ public class ModelWriter extends BaseWriter { case "FlatpackDataFormat" -> doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v); case "ForyDataFormat" -> doWriteForyDataFormat("fory", (ForyDataFormat) v); case "GrokDataFormat" -> doWriteGrokDataFormat("grok", (GrokDataFormat) v); + case "GroovyJSonDataFormat" -> doWriteGroovyJSonDataFormat("groovyJson", (GroovyJSonDataFormat) v); case "GroovyXmlDataFormat" -> doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v); case "GzipDeflaterDataFormat" -> doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v); case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", (HL7DataFormat) v); @@ -1932,6 +1936,7 @@ public class ModelWriter extends BaseWriter { case "FlatpackDataFormat" -> doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v); case "ForyDataFormat" -> doWriteForyDataFormat("fory", (ForyDataFormat) v); case "GrokDataFormat" -> doWriteGrokDataFormat("grok", (GrokDataFormat) v); + case "GroovyJSonDataFormat" -> doWriteGroovyJSonDataFormat("groovyJson", (GroovyJSonDataFormat) v); case "GroovyXmlDataFormat" -> doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v); case "GzipDeflaterDataFormat" -> doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v); case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", (HL7DataFormat) v); @@ -2229,6 +2234,7 @@ public class ModelWriter extends BaseWriter { case "FlatpackDataFormat" -> doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v); case "ForyDataFormat" -> doWriteForyDataFormat("fory", (ForyDataFormat) v); case "GrokDataFormat" -> doWriteGrokDataFormat("grok", (GrokDataFormat) v); + case "GroovyJSonDataFormat" -> doWriteGroovyJSonDataFormat("groovyJson", (GroovyJSonDataFormat) v); case "GroovyXmlDataFormat" -> doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v); case "GzipDeflaterDataFormat" -> doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v); case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", (HL7DataFormat) v); @@ -2337,6 +2343,12 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("namedOnly", def.getNamedOnly(), null); endElement(name); } + protected void doWriteGroovyJSonDataFormat(String name, GroovyJSonDataFormat def) throws IOException { + startElement(name); + doWriteIdentifiedTypeAttributes(def); + doWriteAttribute("prettyPrint", def.getPrettyPrint(), "true"); + endElement(name); + } protected void doWriteGroovyXmlDataFormat(String name, GroovyXmlDataFormat def) throws IOException { startElement(name); doWriteIdentifiedTypeAttributes(def); @@ -3399,6 +3411,7 @@ public class ModelWriter extends BaseWriter { case "FlatpackDataFormat" -> doWriteFlatpackDataFormat("flatpack", (FlatpackDataFormat) v); case "ForyDataFormat" -> doWriteForyDataFormat("fory", (ForyDataFormat) v); case "GrokDataFormat" -> doWriteGrokDataFormat("grok", (GrokDataFormat) v); + case "GroovyJSonDataFormat" -> doWriteGroovyJSonDataFormat("groovyJson", (GroovyJSonDataFormat) v); case "GroovyXmlDataFormat" -> doWriteGroovyXmlDataFormat("groovyXml", (GroovyXmlDataFormat) v); case "GzipDeflaterDataFormat" -> doWriteGzipDeflaterDataFormat("gzipDeflater", (GzipDeflaterDataFormat) v); case "HL7DataFormat" -> doWriteHL7DataFormat("hl7", (HL7DataFormat) v); diff --git a/docs/components/modules/dataformats/examples/json/groovyJson.json b/docs/components/modules/dataformats/examples/json/groovyJson.json new file mode 120000 index 000000000000..6a4a35561d1d --- /dev/null +++ b/docs/components/modules/dataformats/examples/json/groovyJson.json @@ -0,0 +1 @@ +../../../../../../components/camel-groovy/src/generated/resources/META-INF/org/apache/camel/groovy/json/groovyJson.json \ No newline at end of file diff --git a/docs/components/modules/dataformats/nav.adoc b/docs/components/modules/dataformats/nav.adoc index cf82edf790ec..a25bc3bf9508 100644 --- a/docs/components/modules/dataformats/nav.adoc +++ b/docs/components/modules/dataformats/nav.adoc @@ -18,6 +18,7 @@ ** xref:flatpack-dataformat.adoc[Flatpack] ** xref:fory-dataformat.adoc[Fory] ** xref:grok-dataformat.adoc[Grok] +** xref:groovyJson-dataformat.adoc[Groovy JSon] ** xref:groovyXml-dataformat.adoc[Groovy XML] ** xref:gzipDeflater-dataformat.adoc[GZip Deflater] ** xref:hl7-dataformat.adoc[HL7] diff --git a/docs/components/modules/dataformats/pages/groovyJson-dataformat.adoc b/docs/components/modules/dataformats/pages/groovyJson-dataformat.adoc new file mode 120000 index 000000000000..d3257bf72b8d --- /dev/null +++ b/docs/components/modules/dataformats/pages/groovyJson-dataformat.adoc @@ -0,0 +1 @@ +../../../../../components/camel-groovy/src/main/docs/groovyJson-dataformat.adoc \ No newline at end of file diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java index 79116a279f7d..853c9d66ea45 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java @@ -133,6 +133,7 @@ import org.apache.camel.model.dataformat.FhirXmlDataFormat; import org.apache.camel.model.dataformat.FlatpackDataFormat; import org.apache.camel.model.dataformat.ForyDataFormat; import org.apache.camel.model.dataformat.GrokDataFormat; +import org.apache.camel.model.dataformat.GroovyJSonDataFormat; import org.apache.camel.model.dataformat.GroovyXmlDataFormat; import org.apache.camel.model.dataformat.GzipDeflaterDataFormat; import org.apache.camel.model.dataformat.HL7DataFormat; @@ -3080,6 +3081,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "fory", type = "object:org.apache.camel.model.dataformat.ForyDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "fromType", type = "string", description = "Set the 'from' data type name. If you specify 'xml:XYZ', the transformer will be picked up if source type is 'xml:XYZ'. If you specify just 'xml', the transformer matches with all of 'xml' source type like 'xml:ABC' or 'xml:DEF'.", displayName = "From Type"), @YamlProperty(name = "grok", type = "object:org.apache.camel.model.dataformat.GrokDataFormat", oneOf = "dataFormatType"), + @YamlProperty(name = "groovyJson", type = "object:org.apache.camel.model.dataformat.GroovyJSonDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "groovyXml", type = "object:org.apache.camel.model.dataformat.GroovyXmlDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "gzipDeflater", type = "object:org.apache.camel.model.dataformat.GzipDeflaterDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "hl7", type = "object:org.apache.camel.model.dataformat.HL7DataFormat", oneOf = "dataFormatType"), @@ -3214,6 +3216,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setDataFormatType(val); break; } + case "groovyJson": { + org.apache.camel.model.dataformat.GroovyJSonDataFormat val = asType(node, org.apache.camel.model.dataformat.GroovyJSonDataFormat.class); + target.setDataFormatType(val); + break; + } case "groovyXml": { org.apache.camel.model.dataformat.GroovyXmlDataFormat val = asType(node, org.apache.camel.model.dataformat.GroovyXmlDataFormat.class); target.setDataFormatType(val); @@ -3411,6 +3418,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "flatpack", type = "object:org.apache.camel.model.dataformat.FlatpackDataFormat"), @YamlProperty(name = "fory", type = "object:org.apache.camel.model.dataformat.ForyDataFormat"), @YamlProperty(name = "grok", type = "object:org.apache.camel.model.dataformat.GrokDataFormat"), + @YamlProperty(name = "groovyJson", type = "object:org.apache.camel.model.dataformat.GroovyJSonDataFormat"), @YamlProperty(name = "groovyXml", type = "object:org.apache.camel.model.dataformat.GroovyXmlDataFormat"), @YamlProperty(name = "gzipDeflater", type = "object:org.apache.camel.model.dataformat.GzipDeflaterDataFormat"), @YamlProperty(name = "hl7", type = "object:org.apache.camel.model.dataformat.HL7DataFormat"), @@ -3622,6 +3630,16 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setDataFormats(existing); break; } + case "groovyJson": { + org.apache.camel.model.dataformat.GroovyJSonDataFormat val = asType(node, org.apache.camel.model.dataformat.GroovyJSonDataFormat.class); + java.util.List<org.apache.camel.model.DataFormatDefinition> existing = target.getDataFormats(); + if (existing == null) { + existing = new java.util.ArrayList<>(); + } + existing.add(val); + target.setDataFormats(existing); + break; + } case "groovyXml": { org.apache.camel.model.dataformat.GroovyXmlDataFormat val = asType(node, org.apache.camel.model.dataformat.GroovyXmlDataFormat.class); java.util.List<org.apache.camel.model.DataFormatDefinition> existing = target.getDataFormats(); @@ -6223,6 +6241,51 @@ public final class ModelDeserializers extends YamlDeserializerSupport { } } + @YamlType( + nodes = "groovyJson", + types = org.apache.camel.model.dataformat.GroovyJSonDataFormat.class, + order = org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1, + displayName = "Groovy JSon", + description = "Transform between JSon and java.util.Map or java.util.List objects.", + deprecated = false, + properties = { + @YamlProperty(name = "id", type = "string", description = "The id of this node", displayName = "Id"), + @YamlProperty(name = "prettyPrint", type = "boolean", defaultValue = "true", description = "To pretty printing output nicely formatted. Is by default true.", displayName = "Pretty Print") + } + ) + public static class GroovyJSonDataFormatDeserializer extends YamlDeserializerBase<GroovyJSonDataFormat> { + public GroovyJSonDataFormatDeserializer() { + super(GroovyJSonDataFormat.class); + } + + @Override + protected GroovyJSonDataFormat newInstance() { + return new GroovyJSonDataFormat(); + } + + @Override + protected boolean setProperty(GroovyJSonDataFormat target, String propertyKey, + String propertyName, Node node) { + propertyKey = org.apache.camel.util.StringHelper.dashToCamelCase(propertyKey); + switch(propertyKey) { + case "id": { + String val = asText(node); + target.setId(val); + break; + } + case "prettyPrint": { + String val = asText(node); + target.setPrettyPrint(val); + break; + } + default: { + return false; + } + } + return true; + } + } + @YamlType( nodes = "groovyXml", types = org.apache.camel.model.dataformat.GroovyXmlDataFormat.class, @@ -9165,6 +9228,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "flatpack", type = "object:org.apache.camel.model.dataformat.FlatpackDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "fory", type = "object:org.apache.camel.model.dataformat.ForyDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "grok", type = "object:org.apache.camel.model.dataformat.GrokDataFormat", oneOf = "dataFormatType"), + @YamlProperty(name = "groovyJson", type = "object:org.apache.camel.model.dataformat.GroovyJSonDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "groovyXml", type = "object:org.apache.camel.model.dataformat.GroovyXmlDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "gzipDeflater", type = "object:org.apache.camel.model.dataformat.GzipDeflaterDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "hl7", type = "object:org.apache.camel.model.dataformat.HL7DataFormat", oneOf = "dataFormatType"), @@ -9302,6 +9366,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setDataFormatType(val); break; } + case "groovyJson": { + org.apache.camel.model.dataformat.GroovyJSonDataFormat val = asType(node, org.apache.camel.model.dataformat.GroovyJSonDataFormat.class); + target.setDataFormatType(val); + break; + } case "groovyXml": { org.apache.camel.model.dataformat.GroovyXmlDataFormat val = asType(node, org.apache.camel.model.dataformat.GroovyXmlDataFormat.class); target.setDataFormatType(val); @@ -19156,6 +19225,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "flatpack", type = "object:org.apache.camel.model.dataformat.FlatpackDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "fory", type = "object:org.apache.camel.model.dataformat.ForyDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "grok", type = "object:org.apache.camel.model.dataformat.GrokDataFormat", oneOf = "dataFormatType"), + @YamlProperty(name = "groovyJson", type = "object:org.apache.camel.model.dataformat.GroovyJSonDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "groovyXml", type = "object:org.apache.camel.model.dataformat.GroovyXmlDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "gzipDeflater", type = "object:org.apache.camel.model.dataformat.GzipDeflaterDataFormat", oneOf = "dataFormatType"), @YamlProperty(name = "hl7", type = "object:org.apache.camel.model.dataformat.HL7DataFormat", oneOf = "dataFormatType"), @@ -19298,6 +19368,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setDataFormatType(val); break; } + case "groovyJson": { + org.apache.camel.model.dataformat.GroovyJSonDataFormat val = asType(node, org.apache.camel.model.dataformat.GroovyJSonDataFormat.class); + target.setDataFormatType(val); + break; + } case "groovyXml": { org.apache.camel.model.dataformat.GroovyXmlDataFormat val = asType(node, org.apache.camel.model.dataformat.GroovyXmlDataFormat.class); target.setDataFormatType(val); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java index 39318914917e..5325f3a98672 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java @@ -137,6 +137,8 @@ public final class ModelDeserializersResolver implements YamlDeserializerResolve case "org.apache.camel.model.dataformat.GrokDataFormat": return new ModelDeserializers.GrokDataFormatDeserializer(); case "groovy": return new ModelDeserializers.GroovyExpressionDeserializer(); case "org.apache.camel.model.language.GroovyExpression": return new ModelDeserializers.GroovyExpressionDeserializer(); + case "groovyJson": return new ModelDeserializers.GroovyJSonDataFormatDeserializer(); + case "org.apache.camel.model.dataformat.GroovyJSonDataFormat": return new ModelDeserializers.GroovyJSonDataFormatDeserializer(); case "groovyXml": return new ModelDeserializers.GroovyXmlDataFormatDeserializer(); case "org.apache.camel.model.dataformat.GroovyXmlDataFormat": return new ModelDeserializers.GroovyXmlDataFormatDeserializer(); case "gzipDeflater": return new ModelDeserializers.GzipDeflaterDataFormatDeserializer(); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json index 77eea4027a73..cd51c7139364 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json @@ -3032,6 +3032,8 @@ "required" : [ "fory" ] }, { "required" : [ "grok" ] + }, { + "required" : [ "groovyJson" ] }, { "required" : [ "groovyXml" ] }, { @@ -3216,6 +3218,14 @@ "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.GrokDataFormat" } } + }, { + "type" : "object", + "required" : [ "groovyJson" ], + "properties" : { + "groovyJson" : { + "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.GroovyJSonDataFormat" + } + } }, { "type" : "object", "required" : [ "groovyXml" ], @@ -3514,6 +3524,7 @@ "flatpack" : { }, "fory" : { }, "grok" : { }, + "groovyJson" : { }, "groovyXml" : { }, "gzipDeflater" : { }, "hl7" : { }, @@ -8374,6 +8385,7 @@ "flatpack" : { }, "fory" : { }, "grok" : { }, + "groovyJson" : { }, "groovyXml" : { }, "gzipDeflater" : { }, "hl7" : { }, @@ -8449,6 +8461,8 @@ "required" : [ "fory" ] }, { "required" : [ "grok" ] + }, { + "required" : [ "groovyJson" ] }, { "required" : [ "groovyXml" ] }, { @@ -8633,6 +8647,14 @@ "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.GrokDataFormat" } } + }, { + "type" : "object", + "required" : [ "groovyJson" ], + "properties" : { + "groovyJson" : { + "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.GroovyJSonDataFormat" + } + } }, { "type" : "object", "required" : [ "groovyXml" ], @@ -10116,6 +10138,9 @@ "grok" : { "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.GrokDataFormat" }, + "groovyJson" : { + "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.GroovyJSonDataFormat" + }, "groovyXml" : { "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.GroovyXmlDataFormat" }, @@ -10595,6 +10620,25 @@ }, "required" : [ "pattern" ] }, + "org.apache.camel.model.dataformat.GroovyJSonDataFormat" : { + "title" : "Groovy JSon", + "description" : "Transform between JSon and java.util.Map or java.util.List objects.", + "type" : "object", + "additionalProperties" : false, + "properties" : { + "id" : { + "type" : "string", + "title" : "Id", + "description" : "The id of this node" + }, + "prettyPrint" : { + "type" : "boolean", + "title" : "Pretty Print", + "description" : "To pretty printing output nicely formatted. Is by default true.", + "default" : true + } + } + }, "org.apache.camel.model.dataformat.GroovyXmlDataFormat" : { "title" : "Groovy XML", "description" : "Transform between XML and Groovy Node (Map structure) objects.", @@ -16331,6 +16375,8 @@ "required" : [ "fory" ] }, { "required" : [ "grok" ] + }, { + "required" : [ "groovyJson" ] }, { "required" : [ "groovyXml" ] }, { @@ -16511,6 +16557,14 @@ "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.GrokDataFormat" } } + }, { + "type" : "object", + "required" : [ "groovyJson" ], + "properties" : { + "groovyJson" : { + "$ref" : "#/items/definitions/org.apache.camel.model.dataformat.GroovyJSonDataFormat" + } + } }, { "type" : "object", "required" : [ "groovyXml" ], @@ -16782,6 +16836,7 @@ "flatpack" : { }, "fory" : { }, "grok" : { }, + "groovyJson" : { }, "groovyXml" : { }, "gzipDeflater" : { }, "hl7" : { },
