You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2024/06/03 09:22:17 UTC

(camel) branch cjmamo-CAMEL-19985 created (now 3df0f6a9c6b)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch cjmamo-CAMEL-19985
in repository https://gitbox.apache.org/repos/asf/camel.git


      at 3df0f6a9c6b CAMEL-19985: Smooks component

This branch includes the following new commits:

     new 621e7043693 feat: add Smooks component
     new e48414ad5ec CAMEL-19985: Smooks component
     new 3df0f6a9c6b CAMEL-19985: Smooks component

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(camel) 01/03: feat: add Smooks component

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch cjmamo-CAMEL-19985
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 621e7043693613d66ff1c8cfb4c281e10411a0ab
Author: cjmamo <82...@users.noreply.github.com>
AuthorDate: Thu May 30 17:05:40 2024 +0200

    feat: add Smooks component
    
    Refs: https://github.com/smooks/smooks-camel-cartridge/issues/211
---
 bom/camel-bom/pom.xml                              |   5 +
 catalog/camel-allcomponents/pom.xml                |   5 +
 .../org/apache/camel/catalog/components.properties |   1 +
 components/camel-smooks/pom.xml                    | 103 +++++++
 .../smooks/SmooksComponentConfigurer.java          |  63 ++++
 .../component/smooks/SmooksEndpointConfigurer.java | 165 +++++++++++
 .../component/smooks/SmooksEndpointUriFactory.java |  92 ++++++
 .../smooks/converter/ResultConverterLoader.java    |  73 +++++
 .../smooks/converter/SourceConverterLoader.java    |  62 ++++
 .../org/apache/camel/component/smooks/smooks.json  |  53 ++++
 .../services/org/apache/camel/TypeConverterLoader  |   3 +
 .../services/org/apache/camel/component.properties |   7 +
 .../services/org/apache/camel/component/smooks     |   2 +
 .../org/apache/camel/configurer/smooks-component   |   2 +
 .../org/apache/camel/configurer/smooks-endpoint    |   2 +
 .../org/apache/camel/urifactory/smooks-endpoint    |   2 +
 .../src/main/docs/smooks-component.adoc            |  48 +++
 .../camel/component/smooks/SmooksComponent.java    |  51 ++++
 .../camel/component/smooks/SmooksEndpoint.java     |  61 ++++
 .../camel/component/smooks/SmooksProcessor.java    | 291 +++++++++++++++++++
 .../smooks/converter/ResultConverter.java          | 133 +++++++++
 .../smooks/converter/SourceConverter.java          |  67 +++++
 .../apache/camel/component/smooks/Coordinate.java  |  81 ++++++
 .../component/smooks/SmooksComponentTest.java      |  72 +++++
 .../component/smooks/SmooksProcessorTest.java      | 322 +++++++++++++++++++++
 .../smooks/converter/ResultConverterTest.java      |  64 ++++
 .../smooks/converter/SourceConverterTest.java      |  54 ++++
 .../src/test/resources/EBCDIC-input-message.txt    |   1 +
 .../camel-smooks/src/test/resources/data/order.txt |   4 +
 .../src/test/resources/edi-mapping-model.dfdl.xsd  |  79 +++++
 .../test/resources/edi-to-xml-smooks-config.xml    |  35 +++
 .../src/test/resources/xml/expected-order.xml      |  51 ++++
 components/pom.xml                                 |   1 +
 .../org/apache/camel/main/components.properties    |   1 +
 docs/components/modules/ROOT/nav.adoc              |   1 +
 .../component/ComponentsBuilderFactory.java        |  14 +
 .../builder/endpoint/EndpointBuilderFactory.java   |   1 +
 .../camel/builder/endpoint/EndpointBuilders.java   |   1 +
 .../builder/endpoint/StaticEndpointBuilders.java   |  42 +++
 .../camel-component-known-dependencies.properties  |   1 +
 parent/pom.xml                                     |   5 +
 41 files changed, 2121 insertions(+)

diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index a250592fbbd..5bfbac4377a 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -1812,6 +1812,11 @@
         <artifactId>camel-smb</artifactId>
         <version>4.7.0-SNAPSHOT</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-smooks</artifactId>
+        <version>4.7.0-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-smpp</artifactId>
diff --git a/catalog/camel-allcomponents/pom.xml b/catalog/camel-allcomponents/pom.xml
index daf1adf8836..96f648880e9 100644
--- a/catalog/camel-allcomponents/pom.xml
+++ b/catalog/camel-allcomponents/pom.xml
@@ -1592,6 +1592,11 @@
             <artifactId>camel-smb</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-smooks</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-smpp</artifactId>
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components.properties
index eda05e1c4c1..e321b253135 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components.properties
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components.properties
@@ -285,6 +285,7 @@ sjms
 sjms2
 slack
 smb
+smooks
 smpp
 smpps
 smtp
diff --git a/components/camel-smooks/pom.xml b/components/camel-smooks/pom.xml
new file mode 100644
index 00000000000..4128c93c996
--- /dev/null
+++ b/components/camel-smooks/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>4.7.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-smooks</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Camel :: Smooks :: Parent</name>
+    <description>Camel Smooks Component</description>
+
+    <properties>
+        <smooks.version>2.0.0-RC4</smooks.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.smooks</groupId>
+                <artifactId>smooks-bom</artifactId>
+                <version>${smooks.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.smooks</groupId>
+            <artifactId>smooks-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-file</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-attachments</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.smooks.cartridges.edi</groupId>
+            <artifactId>smooks-edi-cartridge</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.smooks.cartridges</groupId>
+            <artifactId>smooks-javabean-cartridge</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.xmlunit</groupId>
+            <artifactId>xmlunit-core</artifactId>
+            <version>2.9.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>${mockito-version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <version>${hamcrest-version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksComponentConfigurer.java b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksComponentConfigurer.java
new file mode 100644
index 00000000000..dcc652ca67c
--- /dev/null
+++ b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksComponentConfigurer.java
@@ -0,0 +1,63 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.smooks;
+
+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.EndpointSchemaGeneratorMojo")
+@SuppressWarnings("unchecked")
+public class SmooksComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        SmooksComponent target = (SmooksComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "autowiredenabled":
+        case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "autowiredenabled":
+        case "autowiredEnabled": return boolean.class;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return boolean.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        SmooksComponent target = (SmooksComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "autowiredenabled":
+        case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointConfigurer.java b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointConfigurer.java
new file mode 100644
index 00000000000..09fb353e905
--- /dev/null
+++ b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointConfigurer.java
@@ -0,0 +1,165 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.smooks;
+
+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.EndpointSchemaGeneratorMojo")
+@SuppressWarnings("unchecked")
+public class SmooksEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        SmooksEndpoint target = (SmooksEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "backofferrorthreshold":
+        case "backoffErrorThreshold": target.setBackoffErrorThreshold(property(camelContext, int.class, value)); return true;
+        case "backoffidlethreshold":
+        case "backoffIdleThreshold": target.setBackoffIdleThreshold(property(camelContext, int.class, value)); return true;
+        case "backoffmultiplier":
+        case "backoffMultiplier": target.setBackoffMultiplier(property(camelContext, int.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "delay": target.setDelay(property(camelContext, long.class, value)); return true;
+        case "exceptionhandler":
+        case "exceptionHandler": target.setExceptionHandler(property(camelContext, org.apache.camel.spi.ExceptionHandler.class, value)); return true;
+        case "exchangepattern":
+        case "exchangePattern": target.setExchangePattern(property(camelContext, org.apache.camel.ExchangePattern.class, value)); return true;
+        case "greedy": target.setGreedy(property(camelContext, boolean.class, value)); return true;
+        case "initialdelay":
+        case "initialDelay": target.setInitialDelay(property(camelContext, long.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        case "pollstrategy":
+        case "pollStrategy": target.setPollStrategy(property(camelContext, org.apache.camel.spi.PollingConsumerPollStrategy.class, value)); return true;
+        case "repeatcount":
+        case "repeatCount": target.setRepeatCount(property(camelContext, long.class, value)); return true;
+        case "runlogginglevel":
+        case "runLoggingLevel": target.setRunLoggingLevel(property(camelContext, org.apache.camel.LoggingLevel.class, value)); return true;
+        case "scheduledexecutorservice":
+        case "scheduledExecutorService": target.setScheduledExecutorService(property(camelContext, java.util.concurrent.ScheduledExecutorService.class, value)); return true;
+        case "scheduler": target.setScheduler(property(camelContext, java.lang.Object.class, value)); return true;
+        case "schedulerproperties":
+        case "schedulerProperties": target.setSchedulerProperties(property(camelContext, java.util.Map.class, value)); return true;
+        case "sendemptymessagewhenidle":
+        case "sendEmptyMessageWhenIdle": target.setSendEmptyMessageWhenIdle(property(camelContext, boolean.class, value)); return true;
+        case "startscheduler":
+        case "startScheduler": target.setStartScheduler(property(camelContext, boolean.class, value)); return true;
+        case "timeunit":
+        case "timeUnit": target.setTimeUnit(property(camelContext, java.util.concurrent.TimeUnit.class, value)); return true;
+        case "usefixeddelay":
+        case "useFixedDelay": target.setUseFixedDelay(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "backofferrorthreshold":
+        case "backoffErrorThreshold": return int.class;
+        case "backoffidlethreshold":
+        case "backoffIdleThreshold": return int.class;
+        case "backoffmultiplier":
+        case "backoffMultiplier": return int.class;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return boolean.class;
+        case "delay": return long.class;
+        case "exceptionhandler":
+        case "exceptionHandler": return org.apache.camel.spi.ExceptionHandler.class;
+        case "exchangepattern":
+        case "exchangePattern": return org.apache.camel.ExchangePattern.class;
+        case "greedy": return boolean.class;
+        case "initialdelay":
+        case "initialDelay": return long.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        case "pollstrategy":
+        case "pollStrategy": return org.apache.camel.spi.PollingConsumerPollStrategy.class;
+        case "repeatcount":
+        case "repeatCount": return long.class;
+        case "runlogginglevel":
+        case "runLoggingLevel": return org.apache.camel.LoggingLevel.class;
+        case "scheduledexecutorservice":
+        case "scheduledExecutorService": return java.util.concurrent.ScheduledExecutorService.class;
+        case "scheduler": return java.lang.Object.class;
+        case "schedulerproperties":
+        case "schedulerProperties": return java.util.Map.class;
+        case "sendemptymessagewhenidle":
+        case "sendEmptyMessageWhenIdle": return boolean.class;
+        case "startscheduler":
+        case "startScheduler": return boolean.class;
+        case "timeunit":
+        case "timeUnit": return java.util.concurrent.TimeUnit.class;
+        case "usefixeddelay":
+        case "useFixedDelay": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        SmooksEndpoint target = (SmooksEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "backofferrorthreshold":
+        case "backoffErrorThreshold": return target.getBackoffErrorThreshold();
+        case "backoffidlethreshold":
+        case "backoffIdleThreshold": return target.getBackoffIdleThreshold();
+        case "backoffmultiplier":
+        case "backoffMultiplier": return target.getBackoffMultiplier();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "delay": return target.getDelay();
+        case "exceptionhandler":
+        case "exceptionHandler": return target.getExceptionHandler();
+        case "exchangepattern":
+        case "exchangePattern": return target.getExchangePattern();
+        case "greedy": return target.isGreedy();
+        case "initialdelay":
+        case "initialDelay": return target.getInitialDelay();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        case "pollstrategy":
+        case "pollStrategy": return target.getPollStrategy();
+        case "repeatcount":
+        case "repeatCount": return target.getRepeatCount();
+        case "runlogginglevel":
+        case "runLoggingLevel": return target.getRunLoggingLevel();
+        case "scheduledexecutorservice":
+        case "scheduledExecutorService": return target.getScheduledExecutorService();
+        case "scheduler": return target.getScheduler();
+        case "schedulerproperties":
+        case "schedulerProperties": return target.getSchedulerProperties();
+        case "sendemptymessagewhenidle":
+        case "sendEmptyMessageWhenIdle": return target.isSendEmptyMessageWhenIdle();
+        case "startscheduler":
+        case "startScheduler": return target.isStartScheduler();
+        case "timeunit":
+        case "timeUnit": return target.getTimeUnit();
+        case "usefixeddelay":
+        case "useFixedDelay": return target.isUseFixedDelay();
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "schedulerproperties":
+        case "schedulerProperties": return java.lang.Object.class;
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointUriFactory.java b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointUriFactory.java
new file mode 100644
index 00000000000..a7552824dd9
--- /dev/null
+++ b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointUriFactory.java
@@ -0,0 +1,92 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.smooks;
+
+import javax.annotation.processing.Generated;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.spi.EndpointUriFactory;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.GenerateEndpointUriFactoryMojo")
+public class SmooksEndpointUriFactory extends org.apache.camel.support.component.EndpointUriFactorySupport implements EndpointUriFactory {
+
+    private static final String BASE = "://smooks-config-path";
+
+    private static final Set<String> PROPERTY_NAMES;
+    private static final Set<String> SECRET_PROPERTY_NAMES;
+    private static final Set<String> MULTI_VALUE_PREFIXES;
+    static {
+        Set<String> props = new HashSet<>(21);
+        props.add("backoffErrorThreshold");
+        props.add("backoffIdleThreshold");
+        props.add("backoffMultiplier");
+        props.add("bridgeErrorHandler");
+        props.add("database");
+        props.add("delay");
+        props.add("exceptionHandler");
+        props.add("exchangePattern");
+        props.add("greedy");
+        props.add("initialDelay");
+        props.add("lazyStartProducer");
+        props.add("pollStrategy");
+        props.add("repeatCount");
+        props.add("runLoggingLevel");
+        props.add("scheduledExecutorService");
+        props.add("scheduler");
+        props.add("schedulerProperties");
+        props.add("sendEmptyMessageWhenIdle");
+        props.add("startScheduler");
+        props.add("timeUnit");
+        props.add("useFixedDelay");
+        PROPERTY_NAMES = Collections.unmodifiableSet(props);
+        SECRET_PROPERTY_NAMES = Collections.emptySet();
+        Set<String> prefixes = new HashSet<>(1);
+        prefixes.add("scheduler.");
+        MULTI_VALUE_PREFIXES = Collections.unmodifiableSet(prefixes);
+    }
+
+    @Override
+    public boolean isEnabled(String scheme) {
+        return "smooks".equals(scheme);
+    }
+
+    @Override
+    public String buildUri(String scheme, Map<String, Object> properties, boolean encode) throws URISyntaxException {
+        String syntax = scheme + BASE;
+        String uri = syntax;
+
+        Map<String, Object> copy = new HashMap<>(properties);
+
+        uri = buildPathParameter(syntax, uri, "database", null, true, copy);
+        uri = buildQueryParameters(uri, copy, encode);
+        return uri;
+    }
+
+    @Override
+    public Set<String> propertyNames() {
+        return PROPERTY_NAMES;
+    }
+
+    @Override
+    public Set<String> secretPropertyNames() {
+        return SECRET_PROPERTY_NAMES;
+    }
+
+    @Override
+    public Set<String> multiValuePrefixes() {
+        return MULTI_VALUE_PREFIXES;
+    }
+
+    @Override
+    public boolean isLenientProperties() {
+        return false;
+    }
+}
+
diff --git a/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/converter/ResultConverterLoader.java b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/converter/ResultConverterLoader.java
new file mode 100644
index 00000000000..2280a868479
--- /dev/null
+++ b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/converter/ResultConverterLoader.java
@@ -0,0 +1,73 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.smooks.converter;
+
+import javax.annotation.processing.Generated;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.DeferredContextBinding;
+import org.apache.camel.Exchange;
+import org.apache.camel.TypeConversionException;
+import org.apache.camel.TypeConverterLoaderException;
+import org.apache.camel.spi.TypeConverterLoader;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.support.SimpleTypeConverter;
+import org.apache.camel.support.TypeConverterSupport;
+import org.apache.camel.util.DoubleMap;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.TypeConverterLoaderGeneratorMojo")
+@SuppressWarnings("unchecked")
+@DeferredContextBinding
+public final class ResultConverterLoader implements TypeConverterLoader, CamelContextAware {
+
+    private CamelContext camelContext;
+
+    public ResultConverterLoader() {
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void load(TypeConverterRegistry registry) throws TypeConverterLoaderException {
+        registerConverters(registry);
+        registerFallbackConverters(registry);
+    }
+
+    private void registerConverters(TypeConverterRegistry registry) {
+        addTypeConverter(registry, java.lang.Double.class, org.smooks.io.payload.JavaResult.ResultMap.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.ResultConverter.toDouble((org.smooks.io.payload.JavaResult.ResultMap) value));
+        addTypeConverter(registry, java.lang.Integer.class, org.smooks.io.payload.JavaResult.ResultMap.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.ResultConverter.toInteger((org.smooks.io.payload.JavaResult.ResultMap) value));
+        addTypeConverter(registry, java.lang.String.class, org.smooks.io.payload.StringResult.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.ResultConverter.toString((org.smooks.io.payload.StringResult) value));
+        addTypeConverter(registry, java.util.List.class, org.smooks.io.payload.JavaResult.ResultMap.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.ResultConverter.toList((org.smooks.io.payload.JavaResult.ResultMap) value, exchange));
+        addTypeConverter(registry, javax.xml.transform.stream.StreamSource.class, org.smooks.io.payload.StringResult.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.ResultConverter.toStreamSource((org.smooks.io.payload.StringResult) value));
+        addTypeConverter(registry, org.w3c.dom.Node.class, javax.xml.transform.dom.DOMResult.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.ResultConverter.toDocument((javax.xml.transform.dom.DOMResult) value));
+    }
+
+    private static void addTypeConverter(TypeConverterRegistry registry, Class<?> toType, Class<?> fromType, boolean allowNull, SimpleTypeConverter.ConversionMethod method) {
+        registry.addTypeConverter(toType, fromType, new SimpleTypeConverter(allowNull, method));
+    }
+
+    private void registerFallbackConverters(TypeConverterRegistry registry) {
+        addFallbackTypeConverter(registry, false, false, (type, exchange, value) -> org.apache.camel.component.smooks.converter.ResultConverter.convertTo(type, exchange, value, registry));
+    }
+
+    private static void addFallbackTypeConverter(TypeConverterRegistry registry, boolean allowNull, boolean canPromote, SimpleTypeConverter.ConversionMethod method) {
+        registry.addFallbackTypeConverter(new SimpleTypeConverter(allowNull, method), canPromote);
+    }
+}
diff --git a/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/converter/SourceConverterLoader.java b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/converter/SourceConverterLoader.java
new file mode 100644
index 00000000000..72cbcb7b288
--- /dev/null
+++ b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/converter/SourceConverterLoader.java
@@ -0,0 +1,62 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.smooks.converter;
+
+import javax.annotation.processing.Generated;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.DeferredContextBinding;
+import org.apache.camel.Exchange;
+import org.apache.camel.TypeConversionException;
+import org.apache.camel.TypeConverterLoaderException;
+import org.apache.camel.spi.TypeConverterLoader;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.support.SimpleTypeConverter;
+import org.apache.camel.support.TypeConverterSupport;
+import org.apache.camel.util.DoubleMap;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.TypeConverterLoaderGeneratorMojo")
+@SuppressWarnings("unchecked")
+@DeferredContextBinding
+public final class SourceConverterLoader implements TypeConverterLoader, CamelContextAware {
+
+    private CamelContext camelContext;
+
+    public SourceConverterLoader() {
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void load(TypeConverterRegistry registry) throws TypeConverterLoaderException {
+        registerConverters(registry);
+    }
+
+    private void registerConverters(TypeConverterRegistry registry) {
+        addTypeConverter(registry, javax.xml.transform.Source.class, java.io.InputStream.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.SourceConverter.toStreamSource((java.io.InputStream) value));
+        addTypeConverter(registry, javax.xml.transform.Source.class, org.apache.camel.component.file.GenericFile.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.SourceConverter.toStreamSource((org.apache.camel.component.file.GenericFile) value));
+        addTypeConverter(registry, org.smooks.io.payload.JavaSource.class, java.lang.Object.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.SourceConverter.toJavaSource(value));
+        addTypeConverter(registry, org.smooks.io.payload.JavaSource.class, org.smooks.io.payload.JavaResult.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.SourceConverter.toJavaSource((org.smooks.io.payload.JavaResult) value));
+        addTypeConverter(registry, org.smooks.io.payload.JavaSourceWithoutEventStream.class, java.lang.Object.class, false,
+            (type, exchange, value) -> org.apache.camel.component.smooks.converter.SourceConverter.toJavaSourceWithoutEventStream(value));
+    }
+
+    private static void addTypeConverter(TypeConverterRegistry registry, Class<?> toType, Class<?> fromType, boolean allowNull, SimpleTypeConverter.ConversionMethod method) {
+        registry.addTypeConverter(toType, fromType, new SimpleTypeConverter(allowNull, method));
+    }
+}
diff --git a/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json b/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
new file mode 100644
index 00000000000..cb677a24991
--- /dev/null
+++ b/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
@@ -0,0 +1,53 @@
+{
+  "component": {
+    "kind": "component",
+    "name": "smooks",
+    "title": "Smooks",
+    "description": "Applies fragment-based processing in Smooks to perform a variety of operations like transformation.",
+    "deprecated": false,
+    "firstVersion": "4.7.0",
+    "label": "file",
+    "javaType": "org.apache.camel.component.smooks.SmooksComponent",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-smooks",
+    "version": "4.7.0-SNAPSHOT",
+    "scheme": "smooks",
+    "extendsScheme": "",
+    "syntax": "smooks:\/\/smooks-config-path",
+    "async": false,
+    "api": false,
+    "consumerOnly": false,
+    "producerOnly": false,
+    "lenientProperties": false,
+    "remote": true
+  },
+  "componentProperties": {
+    "bridgeErrorHandler": { "index": 0, "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming messages, or the like [...]
+    "lazyStartProducer": { "index": 1, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...]
+    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+  },
+  "properties": {
+    "database": { "index": 0, "kind": "path", "displayName": "Database", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "database name" },
+    "sendEmptyMessageWhenIdle": { "index": 1, "kind": "parameter", "displayName": "Send Empty Message When Idle", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the polling consumer did not poll any files, you can enable this option to send an empty message (no body) instead." },
+    "bridgeErrorHandler": { "index": 2, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming  [...]
+    "exceptionHandler": { "index": 3, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By def [...]
+    "exchangePattern": { "index": 4, "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+    "pollStrategy": { "index": 5, "kind": "parameter", "displayName": "Poll Strategy", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.PollingConsumerPollStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your custom implementation to control error handling usually occurred during the pol [...]
+    "lazyStartProducer": { "index": 6, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produc [...]
+    "backoffErrorThreshold": { "index": 7, "kind": "parameter", "displayName": "Backoff Error Threshold", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "description": "The number of subsequent error polls (failed due some error) that should happen before the backoffMultipler should kick-in." },
+    "backoffIdleThreshold": { "index": 8, "kind": "parameter", "displayName": "Backoff Idle Threshold", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "description": "The number of subsequent idle polls that should happen before the backoffMultipler should kick-in." },
+    "backoffMultiplier": { "index": 9, "kind": "parameter", "displayName": "Backoff Multiplier", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "description": "To let the scheduled polling consumer backoff if there has been a number of subsequent idles\/errors in a row. The multiplier is then the number of polls that will be skipped before the next actual attempt is ha [...]
+    "delay": { "index": 10, "kind": "parameter", "displayName": "Delay", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 500, "description": "Milliseconds before the next poll." },
+    "greedy": { "index": 11, "kind": "parameter", "displayName": "Greedy", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If greedy is enabled, then the ScheduledPollConsumer will run immediately again, if the previous run polled 1 or more messages." },
+    "initialDelay": { "index": 12, "kind": "parameter", "displayName": "Initial Delay", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000, "description": "Milliseconds before the first poll starts." },
+    "repeatCount": { "index": 13, "kind": "parameter", "displayName": "Repeat Count", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "description": "Specifies a maximum limit of number of fires. So if you set it to 1, the scheduler will only fire once. If you set it to 5, it will only fire five times. A value of zero or negative means fire forever." },
+    "runLoggingLevel": { "index": 14, "kind": "parameter", "displayName": "Run Logging Level", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "object", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "TRACE", "description": "The consumer logs a start\/complete log line when it polls. This option allows you to configure the l [...]
+    "scheduledExecutorService": { "index": 15, "kind": "parameter", "displayName": "Scheduled Executor Service", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "object", "javaType": "java.util.concurrent.ScheduledExecutorService", "deprecated": false, "autowired": false, "secret": false, "description": "Allows for configuring a custom\/shared thread pool to use for the consumer. By default each consumer has its own single threaded thread pool." },
+    "scheduler": { "index": 16, "kind": "parameter", "displayName": "Scheduler", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "object", "javaType": "java.lang.Object", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "none", "description": "To use a cron scheduler from either camel-spring or camel-quartz component. Use value spring or quartz for built in scheduler" },
+    "schedulerProperties": { "index": 17, "kind": "parameter", "displayName": "Scheduler Properties", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": "scheduler.", "multiValue": true, "deprecated": false, "autowired": false, "secret": false, "description": "To configure additional properties when using a custom scheduler or any of the Quartz, Spring based scheduler." },
+    "startScheduler": { "index": 18, "kind": "parameter", "displayName": "Start Scheduler", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether the scheduler should be auto started." },
+    "timeUnit": { "index": 19, "kind": "parameter", "displayName": "Time Unit", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "object", "javaType": "java.util.concurrent.TimeUnit", "enum": [ "NANOSECONDS", "MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", "DAYS" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "MILLISECONDS", "description": "Time unit for initialDelay and delay options." },
+    "useFixedDelay": { "index": 20, "kind": "parameter", "displayName": "Use Fixed Delay", "group": "scheduler", "label": "consumer,scheduler", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in JDK for details." }
+  }
+}
diff --git a/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader
new file mode 100644
index 00000000000..5b76f723f6b
--- /dev/null
+++ b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader
@@ -0,0 +1,3 @@
+# Generated by camel build tools - do NOT edit this file!
+org.apache.camel.component.smooks.converter.ResultConverterLoader
+org.apache.camel.component.smooks.converter.SourceConverterLoader
diff --git a/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/component.properties b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/component.properties
new file mode 100644
index 00000000000..4f818d51d25
--- /dev/null
+++ b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/component.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+components=smooks
+groupId=org.apache.camel
+artifactId=camel-smooks
+version=4.7.0-SNAPSHOT
+projectName=Camel :: Smooks :: Parent
+projectDescription=Camel Smooks Component
diff --git a/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/component/smooks b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/component/smooks
new file mode 100644
index 00000000000..94f3d034fed
--- /dev/null
+++ b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/component/smooks
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.smooks.SmooksComponent
diff --git a/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/configurer/smooks-component b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/configurer/smooks-component
new file mode 100644
index 00000000000..ad88c91d6a2
--- /dev/null
+++ b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/configurer/smooks-component
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.smooks.SmooksComponentConfigurer
diff --git a/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/configurer/smooks-endpoint b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/configurer/smooks-endpoint
new file mode 100644
index 00000000000..27edabac926
--- /dev/null
+++ b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/configurer/smooks-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.smooks.SmooksEndpointConfigurer
diff --git a/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/urifactory/smooks-endpoint b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/urifactory/smooks-endpoint
new file mode 100644
index 00000000000..e371a6ef04e
--- /dev/null
+++ b/components/camel-smooks/src/generated/resources/META-INF/services/org/apache/camel/urifactory/smooks-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.smooks.SmooksEndpointUriFactory
diff --git a/components/camel-smooks/src/main/docs/smooks-component.adoc b/components/camel-smooks/src/main/docs/smooks-component.adoc
new file mode 100644
index 00000000000..d5d1a1056af
--- /dev/null
+++ b/components/camel-smooks/src/main/docs/smooks-component.adoc
@@ -0,0 +1,48 @@
+= Smooks Component
+:doctitle: Smooks
+:shortname: smooks
+:artifactid: camel-smooks
+:description: Applies fragment-based processing in Smooks to perform a variety of operations like transformation.
+:since: 4.7
+:supportlevel: Preview
+:tabs-sync-option:
+:component-header: Both producer and consumer are supported
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The Camel Smooks component uses https://www.smooks.org/[Smooks] to break up the structured data (EDI, CSV, POJO, etc...) of a Camel message body into fragments. These fragments can be processed independently of one another from within Smooks.
+
+Common applications of Smooks include transformation (e.g., EDI to CSV, POJO to EDI, POJO to XML), routing (e.g., split, transform, and route fragments to destinations such as JMS queues, file systems, and databases), and enrichment (e.g., enriching a fragment with data from a database).
+
+Maven users will need to add the following dependency to their `+pom.xml+`.
+
+[source,xml]
+----
+<dependency>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>camel-smooks</artifactId>
+    <version>x.x.x</version>
+    <!-- use the same version as your Camel core version -->
+</dependency>
+----
+
+== URI Format
+
+....
+smooks://smooks-config-path[?options]
+....
+
+// component-configure options: START
+
+// component-configure options: END
+
+// component options: START
+include::partial$component-configure-options.adoc[]
+include::partial$component-endpoint-options.adoc[]
+// component options: END
+
+// endpoint options: START
+
+// endpoint options: END
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksComponent.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksComponent.java
new file mode 100644
index 00000000000..42bcf7cf613
--- /dev/null
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksComponent.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks;
+
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.spi.annotations.Component;
+import org.apache.camel.support.DefaultComponent;
+
+/**
+ * Smook Camel Component.
+ * <p/>
+ * <p>
+ * Example usage:
+ *
+ * <pre>
+ * from(&quot;direct:a&quot;).to(&quot;smooks://edi-to-xml-smooks-config.xml&quot;)
+ * </pre>
+ *
+ * @author Christian Mueller
+ * @author Daniel Bevenius
+ */
+@Component("smooks")
+public class SmooksComponent extends DefaultComponent {
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        SmooksProcessor smooksProcessor = new SmooksProcessor(remaining, getCamelContext());
+        configureSmooksProcessor(smooksProcessor, uri, remaining, parameters);
+        return new SmooksEndpoint(uri, this, smooksProcessor);
+    }
+
+    protected void configureSmooksProcessor(SmooksProcessor smooksProcessor, String uri, String remaining,
+                                            Map<String, Object> parameters) throws Exception {
+        setProperties(smooksProcessor, parameters);
+    }
+
+}
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java
new file mode 100644
index 00000000000..641d58f3d10
--- /dev/null
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks;
+
+import org.apache.camel.Category;
+import org.apache.camel.Component;
+import org.apache.camel.Service;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriPath;
+import org.apache.camel.support.ProcessorEndpoint;
+import org.smooks.api.SmooksException;
+
+/**
+ * Applies fragment-based processing in Smooks to perform a variety of operations like transformation.
+ */
+@UriEndpoint(firstVersion = "4.7.0", scheme = "smooks", title = "Smooks", syntax = "smooks://smooks-config-path", category = { Category.FILE })
+public class SmooksEndpoint extends ProcessorEndpoint implements Service {
+
+    @UriPath(description = "database name")
+    @Metadata(required = true)
+    private String database;
+
+    private final SmooksProcessor smooksProcessor;
+
+    public SmooksEndpoint(String endpointUri, Component component, SmooksProcessor processor) {
+        super(endpointUri, component, processor);
+        this.smooksProcessor = processor;
+    }
+
+    public void start() {
+        try {
+            smooksProcessor.start();
+        } catch (Exception e) {
+            throw new SmooksException(e.getMessage(), e);
+        }
+    }
+
+    public void stop() {
+        try {
+            smooksProcessor.stop();
+        } catch (Exception e) {
+            throw new SmooksException(e.getMessage(), e);
+        }
+    }
+
+}
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
new file mode 100644
index 00000000000..3636f2f86a3
--- /dev/null
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
@@ -0,0 +1,291 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.*;
+import java.util.Map.Entry;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Node;
+
+import org.xml.sax.SAXException;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.Service;
+import org.apache.camel.WrappedFile;
+import org.apache.camel.attachment.Attachment;
+import org.apache.camel.attachment.AttachmentMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.smooks.Smooks;
+import org.smooks.SmooksFactory;
+import org.smooks.api.ExecutionContext;
+import org.smooks.api.SmooksException;
+import org.smooks.api.TypedKey;
+import org.smooks.api.delivery.VisitorAppender;
+import org.smooks.api.resource.visitor.Visitor;
+import org.smooks.engine.lookup.ExportsLookup;
+import org.smooks.engine.report.HtmlReportGenerator;
+import org.smooks.io.payload.Exports;
+
+/**
+ * Smooks {@link Processor} for Camel.
+ *
+ * @author Christian Mueller
+ * @author Daniel Bevenius
+ */
+public class SmooksProcessor implements Processor, Service, CamelContextAware {
+    public static final String SMOOKS_EXECUTION_CONTEXT = "CamelSmooksExecutionContext";
+    public static final String CAMEL_CHARACTER_ENCODING = "CamelCharsetName";
+    private static final Logger LOGGER = LoggerFactory.getLogger(SmooksProcessor.class);
+    public static final TypedKey<Exchange> EXCHANGE_TYPED_KEY = TypedKey.of();
+
+    private Smooks smooks;
+    private String configUri;
+    private String reportPath;
+
+    private Set<VisitorAppender> visitorAppenders = new HashSet<>();
+    private Map<String, Visitor> selectorVisitorMap = new HashMap<>();
+    private CamelContext camelContext;
+    private boolean attachmentsSupported = false;
+
+    public SmooksProcessor(final CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    public SmooksProcessor(final Smooks smooks, final CamelContext camelContext) {
+        this(camelContext);
+        this.smooks = smooks;
+    }
+
+    public SmooksProcessor(final String configUri, final CamelContext camelContext) throws IOException, SAXException {
+        this(camelContext);
+        this.configUri = configUri;
+    }
+
+    public void process(final Exchange exchange) {
+        //forward headers
+        exchange.getMessage().setHeaders(exchange.getIn().getHeaders());
+
+        if (attachmentsSupported) {
+            //forward attachments
+            if (exchange.getIn(AttachmentMessage.class).hasAttachments()) {
+                for (Entry<String, Attachment> attachmentObject : exchange.getIn(AttachmentMessage.class).getAttachmentObjects().entrySet()) {
+                    exchange.getMessage(AttachmentMessage.class).addAttachmentObject(attachmentObject.getKey(), attachmentObject.getValue());
+                }
+            }
+        }
+
+        final ExecutionContext executionContext = smooks.createExecutionContext();
+        executionContext.put(EXCHANGE_TYPED_KEY, exchange);
+        String charsetName = (String) exchange.getProperty(CAMEL_CHARACTER_ENCODING);
+        if (charsetName != null) //if provided use the came character encoding
+        {
+            executionContext.setContentEncoding(charsetName);
+        }
+        exchange.getIn().setHeader(SMOOKS_EXECUTION_CONTEXT, executionContext);
+        setupSmooksReporting(executionContext);
+
+        final Exports exports = smooks.getApplicationContext().getRegistry().lookup(new ExportsLookup());
+        if (exports.hasExports()) {
+            final Result[] results = exports.createResults();
+            smooks.filterSource(executionContext, getSource(exchange), results);
+            setResultOnBody(exports, results, exchange);
+        } else {
+            smooks.filterSource(executionContext, getSource(exchange));
+        }
+
+        executionContext.remove(EXCHANGE_TYPED_KEY);
+    }
+
+    protected void setResultOnBody(final Exports exports, final Result[] results, final Exchange exchange) {
+        final Message message = exchange.getMessage();
+        final List<Object> objects = Exports.extractResults(results, exports);
+        if (objects.size() == 1) {
+            Object value = objects.get(0);
+            message.setBody(value);
+        } else {
+            message.setBody(objects);
+        }
+    }
+
+    private void setupSmooksReporting(final ExecutionContext executionContext) {
+        if (reportPath != null) {
+            try {
+                executionContext.getContentDeliveryRuntime().addExecutionEventListener(new HtmlReportGenerator(reportPath, executionContext.getApplicationContext()));
+            } catch (final IOException e) {
+                LOGGER.info("Could not generate Smooks Report. The reportPath specified was [" + reportPath + "].", e);
+            }
+        }
+    }
+
+    private Source getSource(final Exchange exchange) {
+        Object payload = exchange.getIn().getBody();
+
+
+        if (payload instanceof SAXSource) {
+            return new StreamSource((Reader) ((SAXSource) payload).getXMLReader());
+        }
+
+        if (payload instanceof Source) {
+            return (Source) payload;
+        }
+
+        if (payload instanceof Node) {
+            return new DOMSource((Node) payload);
+        }
+
+        if (payload instanceof InputStream) {
+            return new StreamSource((InputStream) payload);
+        }
+
+        if (payload instanceof Reader) {
+            return new StreamSource((Reader) payload);
+        }
+
+        if (payload instanceof WrappedFile) {
+            return new StreamSource((File) exchange.getIn().getBody(WrappedFile.class).getFile());
+        }
+
+        return exchange.getIn().getBody(Source.class);
+    }
+
+    public String getSmooksConfig() {
+        return configUri;
+    }
+
+    public void setSmooksConfig(final String smooksConfig) {
+        this.configUri = smooksConfig;
+    }
+
+    /**
+     * Add a visitor instance.
+     *
+     * @param visitor        The visitor implementation.
+     * @param targetSelector The message fragment target selector.
+     * @return This instance.
+     */
+    public SmooksProcessor addVisitor(Visitor visitor, String targetSelector) {
+        selectorVisitorMap.put(targetSelector, visitor);
+        return this;
+    }
+
+    /**
+     * Add a visitor instance to <code>this</code> Smooks instance via a
+     * {@link VisitorAppender}.
+     *
+     * @param appender The visitor appender.
+     * @return This instance.
+     */
+    public SmooksProcessor addVisitor(VisitorAppender appender) {
+        visitorAppenders.add(appender);
+        return this;
+    }
+
+    public void setReportPath(String reportPath) {
+        this.reportPath = reportPath;
+    }
+
+    @Override
+    public void start() {
+        try {
+            if (smooks == null) {
+                smooks = createSmooks();
+                if (configUri != null) {
+                    smooks.addResourceConfigs(configUri);
+                }
+                smooks.getApplicationContext().getRegistry().registerObject(CamelContext.class, camelContext);
+            }
+
+            addAppenders(smooks, visitorAppenders);
+            addVisitors(smooks, selectorVisitorMap);
+
+            InputStream inputStream = null;
+            try {
+                inputStream = camelContext.getClassResolver().loadResourceAsStream("META-INF/services/org/apache/camel/other.properties");
+                if (inputStream != null) {
+                    final Properties properties = new Properties();
+                    properties.load(inputStream);
+                    if (properties.getProperty("name") != null && properties.getProperty("name").equals("attachments")) {
+                        attachmentsSupported = true;
+                    }
+                }
+            } finally {
+                if (!attachmentsSupported) {
+                    LOGGER.warn("Attachments module could not be found: attachments will not be propagated");
+                }
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            }
+
+            LOGGER.info(this + " Started");
+        } catch (SAXException | IOException e) {
+            throw new SmooksException(e.getMessage(), e);
+        }
+    }
+
+    private Smooks createSmooks() {
+        final SmooksFactory smooksFactory = (SmooksFactory) camelContext.getRegistry().lookupByName(SmooksFactory.class.getName());
+        return smooksFactory != null ? smooksFactory.createInstance() : new Smooks();
+    }
+
+    private void addAppenders(Smooks smooks, Set<VisitorAppender> visitorAppenders) {
+        for (VisitorAppender appender : visitorAppenders)
+            smooks.addVisitors(appender);
+    }
+
+    private void addVisitors(Smooks smooks, Map<String, Visitor> selectorVisitorMap) {
+        for (Entry<String, Visitor> entry : selectorVisitorMap.entrySet())
+            smooks.addVisitor(entry.getValue(), entry.getKey());
+    }
+
+    public void stop() {
+        if (smooks != null) {
+            smooks.close();
+            smooks = null;
+        }
+        LOGGER.info(this + " Stopped");
+    }
+
+    @Override
+    public String toString() {
+        return "SmooksProcessor [configUri=" + configUri + "]";
+    }
+
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+}
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/ResultConverter.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/ResultConverter.java
new file mode 100644
index 00000000000..74d6d41376b
--- /dev/null
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/ResultConverter.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks.converter;
+
+import java.io.StringReader;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Node;
+
+import org.apache.camel.Converter;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.smooks.io.payload.JavaResult;
+import org.smooks.io.payload.StringResult;
+
+/**
+ * ResultConverter converts from different {@link Result} types.
+ *
+ * @author Daniel Bevenius
+ */
+@Converter(generateLoader = true)
+public class ResultConverter {
+    public static final String SMOOKS_RESULT_KEY = "SmooksResultKeys";
+
+    private ResultConverter() {
+    }
+
+    @Converter
+    public static Node toDocument(DOMResult domResult) {
+        return domResult.getNode();
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Converter
+    public static List toList(JavaResult.ResultMap javaResult, Exchange exchange) {
+        String resultKey = (String) exchange.getProperty(SMOOKS_RESULT_KEY);
+        if (resultKey != null) {
+            return (List) getResultsFromJavaResult(javaResult, resultKey);
+        } else {
+            return (List) getSingleObjectFromJavaResult(javaResult);
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Converter
+    public static Integer toInteger(JavaResult.ResultMap result) {
+        return (Integer) getSingleObjectFromJavaResult(result);
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Converter
+    public static Double toDouble(JavaResult.ResultMap result) {
+        return (Double) getSingleObjectFromJavaResult(result);
+    }
+
+    @Converter
+    public static String toString(StringResult result) {
+        return result.getResult();
+    }
+
+
+    @SuppressWarnings("rawtypes")
+    public static Map toMap(JavaResult.ResultMap resultBeans, Exchange exchange) {
+        Message outMessage = exchange.getOut();
+        outMessage.setBody(resultBeans);
+
+        @SuppressWarnings("unchecked")
+        Set<Entry<String, Object>> entrySet = resultBeans.entrySet();
+        for (Entry<String, Object> entry : entrySet) {
+            outMessage.setBody(entry.getValue(), entry.getValue().getClass());
+        }
+        return resultBeans;
+    }
+
+    @SuppressWarnings("rawtypes")
+    private static Object getResultsFromJavaResult(JavaResult.ResultMap resultMap, String resultKey) {
+        return resultMap.get(resultKey);
+    }
+
+    private static Object getSingleObjectFromJavaResult(@SuppressWarnings("rawtypes") JavaResult.ResultMap resultMap) {
+        if (resultMap.size() == 1) {
+            return resultMap.values().iterator().next();
+        }
+        return null;
+    }
+
+    @Converter
+    public static StreamSource toStreamSource(StringResult stringResult) {
+        String result = stringResult.getResult();
+        if (result != null) {
+            StringReader stringReader = new StringReader(result);
+            return new StreamSource(stringReader);
+        }
+
+        return null;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Converter(fallback = true)
+    public static <T> T convertTo(Class<T> type, Exchange exchange, Object value, TypeConverterRegistry registry) {
+        if (value instanceof JavaResult.ResultMap) {
+            for (Object mapValue : ((Map) value).values()) {
+                if (type.isInstance(mapValue)) {
+                    return type.cast(mapValue);
+                }
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/SourceConverter.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/SourceConverter.java
new file mode 100644
index 00000000000..994d249fc3e
--- /dev/null
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/SourceConverter.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks.converter;
+
+import java.io.File;
+import java.io.InputStream;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.camel.Converter;
+import org.apache.camel.component.file.GenericFile;
+import org.smooks.io.payload.JavaResult;
+import org.smooks.io.payload.JavaSource;
+import org.smooks.io.payload.JavaSourceWithoutEventStream;
+
+/**
+ * SourceConverter is a Camel {@link Converter} that converts from different
+ * formats to {@link Source} instances. </p>
+ *
+ * @author Daniel Bevenius
+ */
+@Converter(generateLoader = true)
+public class SourceConverter {
+    private SourceConverter() {
+    }
+
+    @Converter
+    public static JavaSourceWithoutEventStream toJavaSourceWithoutEventStream(Object payload) {
+        return new JavaSourceWithoutEventStream(payload);
+    }
+
+    @Converter
+    public static JavaSource toJavaSource(Object payload) {
+        return new JavaSource(payload);
+    }
+
+    @Converter
+    public static Source toStreamSource(InputStream in) {
+        return new StreamSource(in);
+    }
+
+    @Converter
+    public static JavaSource toJavaSource(JavaResult result) {
+        return new JavaSource(result.getResultMap().values());
+    }
+
+    @Converter
+    public static Source toStreamSource(GenericFile<File> genericFile) {
+        return new StreamSource((File) genericFile.getBody());
+    }
+
+}
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/Coordinate.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/Coordinate.java
new file mode 100644
index 00000000000..742e96adc33
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/Coordinate.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks;
+
+/**
+ * @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
+ */
+public class Coordinate {
+
+    private Integer x;
+    private Integer y;
+
+    public Coordinate() {
+    }
+
+    public Coordinate(final int x, final int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    public Integer getX() {
+        return x;
+    }
+
+    public void setX(Integer x) {
+        this.x = x;
+    }
+
+    public Integer getY() {
+        return y;
+    }
+
+    public void setY(Integer y) {
+        this.y = y;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + x;
+        result = prime * result + y;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        Coordinate other = (Coordinate) obj;
+        if (!x.equals(other.x))
+            return false;
+        if (!y.equals(other.y))
+            return false;
+        return true;
+    }
+
+    public String toString() {
+        return "Coordinate [x=" + x + ", y=" + y + "]";
+    }
+
+
+}
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksComponentTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksComponentTest.java
new file mode 100644
index 00000000000..ed87219c5c2
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksComponentTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.smooks.support.StreamUtils;
+import org.xmlunit.builder.DiffBuilder;
+
+import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied;
+import static org.apache.camel.test.junit5.TestSupport.assertIsInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+/**
+ * Unit test for {@link SmooksComponent}.
+ *
+ * @author Christian Mueller
+ * @author Daniel Bevenius
+ */
+public class SmooksComponentTest extends CamelTestSupport {
+    @EndpointInject(value = "mock:result")
+    private MockEndpoint mockEndpoint;
+
+    @Test
+    public void unmarshalEdi() throws Exception {
+        mockEndpoint.expectedMessageCount(1);
+        assertIsSatisfied(mockEndpoint);
+
+        Exchange exchange = mockEndpoint.assertExchangeReceived(0);
+
+        assertIsInstanceOf(Document.class, exchange.getIn().getBody());
+        assertFalse(DiffBuilder.compare(StreamUtils.readStreamAsString(getClass().getResourceAsStream("/xml/expected-order.xml"), "UTF-8")).
+                withTest(exchange.getIn().getBody(String.class)).
+                ignoreComments().
+                ignoreWhitespace().
+                build().
+                hasDifferences());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("file://src/test/resources/data?noop=true")
+                        .to("smooks://edi-to-xml-smooks-config.xml")
+                        .convertBodyTo(Node.class).to("mock:result");
+            }
+        };
+    }
+}
+
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java
new file mode 100644
index 00000000000..5cf61198854
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.Map;
+
+import jakarta.activation.DataHandler;
+import jakarta.activation.DataSource;
+
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.attachment.AttachmentMessage;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.smooks.Smooks;
+import org.smooks.cartridges.javabean.Bean;
+import org.smooks.cartridges.javabean.Value;
+import org.smooks.io.payload.Exports;
+import org.smooks.io.payload.JavaResult;
+import org.smooks.io.payload.StringResult;
+import org.smooks.io.payload.StringSource;
+import org.smooks.support.StreamUtils;
+import org.xmlunit.builder.DiffBuilder;
+
+import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied;
+import static org.apache.camel.test.junit5.TestSupport.assertIsInstanceOf;
+import static org.apache.camel.test.junit5.TestSupport.deleteDirectory;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Unit test for {@link SmooksProcessor}.
+ *
+ * @author Christian Mueller
+ * @author Daniel Bevenius
+ */
+public class SmooksProcessorTest extends CamelTestSupport {
+    @EndpointInject(value = "mock:result")
+    private MockEndpoint result;
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    private void assertOneProcessedMessage() throws Exception {
+        result.expectedMessageCount(1);
+        template.sendBody("direct://input", getOrderEdi());
+
+        assertIsSatisfied();
+
+        Exchange exchange = result.assertExchangeReceived(0);
+        assertIsInstanceOf(Document.class, exchange.getIn().getBody());
+        assertFalse(DiffBuilder.compare(getExpectedOrderXml()).withTest(exchange.getIn().getBody(String.class)).
+                ignoreComments().
+                ignoreWhitespace().
+                build().
+                hasDifferences());
+    }
+
+    @Test
+    public void testProcess() throws Exception {
+        context.addRoutes(createEdiToXmlRouteBuilder());
+        context.start();
+        assertOneProcessedMessage();
+    }
+
+    @Test
+    public void testProcessGivenAttachment() throws Exception {
+        context.addRoutes(createEdiToXmlRouteBuilder());
+        context.start();
+        final DefaultExchange exchange = new DefaultExchange(context);
+        final String attachmentContent = "A dummy attachment";
+        final String attachmentId = "testAttachment";
+        addAttachment(attachmentContent, attachmentId, exchange);
+        exchange.getIn().setBody(getOrderEdi());
+
+        template.send("direct://input", exchange);
+
+        final DataHandler datahandler = result.assertExchangeReceived(0).getIn(AttachmentMessage.class).getAttachment(attachmentId);
+        assertThat(datahandler, is(notNullValue()));
+        assertThat(datahandler.getContent(), is(instanceOf(ByteArrayInputStream.class)));
+
+        final String actualAttachmentContent = getAttachmentContent(datahandler);
+        assertThat(actualAttachmentContent, is(equalTo(attachmentContent)));
+    }
+
+    @Test
+    public void testProcessCreatesSmooksReport() throws Exception {
+        context.addRoutes(createEdiToXmlRouteBuilder());
+        context.start();
+        assertOneProcessedMessage();
+
+        File report = new File("target/smooks-report.html");
+        report.deleteOnExit();
+        assertTrue(report.exists(), "Smooks report was not generated.");
+    }
+
+    @Test
+    public void testProcessGivenCamelCharsetNameProperty() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() {
+                Smooks smooks = new Smooks().setExports(new Exports(JavaResult.class));
+                from("direct:a")
+                        .process(new SmooksProcessor(smooks, context)
+                                .addVisitor(new Value("customer", "/order/header/customer", String.class, smooks.getApplicationContext().getRegistry())));
+            }
+
+        });
+        enableJMX();
+        context.start();
+        Exchange response = template.request("direct:a", new Processor() {
+            public void process(Exchange exchange) {
+                InputStream in = this.getClass().getResourceAsStream("/EBCDIC-input-message.txt");
+                exchange.getIn().setBody(new StreamSource(in));
+                exchange.setProperty("CamelCharsetName", "Cp1047");
+            }
+        });
+        assertEquals("Joe", response.getMessage().getBody(String.class));
+    }
+
+    @Test
+    public void testProcessGivenFileWhenSmooksExportIsStringResult() throws Exception {
+        deleteDirectory("target/smooks");
+        context.addRoutes(new RouteBuilder() {
+            public void configure() {
+                from("file://target/smooks").
+                        process(new SmooksProcessor(new Smooks().setExports(new Exports(StringResult.class)), context)).
+                        to("mock:a");
+            }
+        });
+        context.start();
+        template.sendBody("file://target/smooks", "<blah />");
+
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:a");
+        mockEndpoint.expectedMessageCount(1);
+
+        assertIsSatisfied(mockEndpoint);
+
+        assertEquals("<blah/>", mockEndpoint.getExchanges().get(0).getIn().getBody(String.class));
+    }
+
+    @Test
+    public void testProcessWhenSmooksExportIsJavaResultAndBodyIsVisitedByJavaBeanValue() throws Exception {
+        Smooks smooks = new Smooks().setExports(new Exports(JavaResult.class));
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:a")
+                        .process(new SmooksProcessor(smooks, context)
+                                .addVisitor(new Value("x", "/coord/@x", Integer.class, smooks.getApplicationContext().getRegistry())));
+            }
+        });
+        enableJMX();
+        context.start();
+        Exchange response = template.request("direct:a", exchange -> exchange.getIn().setBody(new StringSource("<coord x='1234' />")));
+        assertEquals(1234, response.getMessage().getBody(Integer.class));
+    }
+
+    @Test
+    public void testProcessWhenSmooksExportIsJavaResultAndBodyIsVisitedByMultipleJavaBeanValues() throws Exception {
+        Smooks smooks = new Smooks().setExports(new Exports(JavaResult.class));
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:b").process(new SmooksProcessor(smooks, context).
+                        addVisitor(new Value("x", "/coord/@x", Integer.class, smooks.getApplicationContext().getRegistry())).
+                        addVisitor(new Value("y", "/coord/@y", Double.class, smooks.getApplicationContext().getRegistry())));
+            }
+        });
+        context.start();
+        Exchange response = template.request("direct:b", exchange -> exchange.getIn().setBody(new StringSource("<coord x='1234' y='98765.76' />")));
+        Map javaResult = response.getOut().getBody(Map.class);
+        Integer x = (Integer) javaResult.get("x");
+        assertEquals(1234, (int) x);
+        Double y = (Double) javaResult.get("y");
+        assertEquals(98765.76D, y, 0.01D);
+    }
+
+    @Test
+    public void testProcessWhenSmooksExportIsJavaResultAndBodyIsVisitedByBean() throws Exception {
+        Smooks smooks = new Smooks().setExports(new Exports(JavaResult.class));
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:c").process(new SmooksProcessor(smooks, context).
+                        addVisitor(new Bean(Coordinate.class, "coordinate", smooks.getApplicationContext().getRegistry()).
+                                bindTo("x", "/coord/@x").
+                                bindTo("y", "/coord/@y")));
+            }
+        });
+        context.start();
+        Exchange response = template.request("direct:c", exchange -> exchange.getIn().setBody(new StringSource("<coord x='111' y='222' />")));
+
+        Coordinate coord = response.getMessage().getBody(Coordinate.class);
+
+        assertEquals((Integer) 111, coord.getX());
+        assertEquals((Integer) 222, coord.getY());
+    }
+
+    @Test
+    public void testProcessWhenSmooksExportIsStringResult() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            public void configure() {
+                from("direct:a")
+                        .process(new SmooksProcessor(new Smooks().setExports(new Exports(StringResult.class)), context))
+                        .to("direct:b");
+
+                from("direct:b").convertBodyTo(String.class).process(new DirectBProcessor());
+            }
+        });
+        context.start();
+        template.request("direct:a", exchange -> exchange.getIn().setBody(new StringSource("<x/>")));
+
+        assertEquals("<x/>", DirectBProcessor.inMessage);
+    }
+
+    private static class DirectBProcessor implements Processor {
+        private static String inMessage;
+
+        public void process(Exchange exchange) {
+            inMessage = (String) exchange.getIn().getBody();
+        }
+    }
+
+    private void addAttachment(final String attachment, final String id, final Exchange exchange) {
+        final DataSource ds = new StringDataSource(attachment);
+        final DataHandler dataHandler = new DataHandler(ds);
+        exchange.getIn(AttachmentMessage.class).addAttachment(id, dataHandler);
+    }
+
+    private String getAttachmentContent(final DataHandler datahandler) throws IOException {
+        final ByteArrayInputStream bs = (ByteArrayInputStream) datahandler.getContent();
+        return new String(StreamUtils.readStream(bs));
+    }
+
+    protected RouteBuilder createEdiToXmlRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                SmooksProcessor processor = new SmooksProcessor("edi-to-xml-smooks-config.xml", context);
+                processor.setReportPath("target/smooks-report.html");
+
+                from("direct:input").process(processor).convertBodyTo(Node.class).to("mock:result");
+            }
+        };
+    }
+
+    private String getExpectedOrderXml() throws IOException {
+        return StreamUtils.readStream(new InputStreamReader(getClass().getResourceAsStream("/xml/expected-order.xml")));
+    }
+
+    private String getOrderEdi() throws IOException {
+        return StreamUtils.readStream(new InputStreamReader(getClass().getResourceAsStream("/data/order.txt")));
+    }
+
+    private static class StringDataSource implements DataSource {
+        private final String string;
+
+        private StringDataSource(final String string) {
+            this.string = string;
+
+        }
+
+        public String getContentType() {
+            return "text/plain";
+        }
+
+        public InputStream getInputStream() throws IOException {
+            return new ByteArrayInputStream(string.getBytes());
+        }
+
+        public String getName() {
+            return "StringDataSource";
+        }
+
+        public OutputStream getOutputStream() throws IOException {
+            throw new IOException("Method 'getOutputStream' is not implemented");
+        }
+
+    }
+}
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/ResultConverterTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/ResultConverterTest.java
new file mode 100644
index 00000000000..408da4585d8
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/ResultConverterTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks.converter;
+
+import java.io.BufferedReader;
+import java.io.StringWriter;
+
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.camel.TypeConverter;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.smooks.io.payload.StringResult;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Unit test for {@link ResultConverter}.
+ *
+ * @author Daniel Bevenius
+ */
+public class ResultConverterTest {
+    private TypeConverter typeConverter;
+
+    @BeforeEach
+    public void beforeEach() {
+        DefaultCamelContext camelContext = new DefaultCamelContext();
+        typeConverter = camelContext.getTypeConverter();
+    }
+
+    @Test
+    public void convertStringResultToStreamSource() throws Exception {
+        StringResult stringResult = createStringResult("Bajja");
+
+        StreamSource streamSource = typeConverter.convertTo(StreamSource.class, stringResult);
+
+        BufferedReader reader = new BufferedReader(streamSource.getReader());
+        assertEquals("Bajja", reader.readLine());
+    }
+
+    private StringResult createStringResult(String string) {
+        StringWriter stringWriter = new StringWriter();
+        stringWriter.write(string);
+        StringResult stringResult = new StringResult();
+        stringResult.setWriter(stringWriter);
+        return stringResult;
+    }
+
+}
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/SourceConverterTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/SourceConverterTest.java
new file mode 100644
index 00000000000..92396a6ab8a
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/SourceConverterTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.smooks.converter;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.TypeConverter;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.smooks.io.payload.JavaSourceWithoutEventStream;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * Unit test for {@link SourceConverter}. </p>
+ *
+ * @author Daniel Bevenius
+ */
+public class SourceConverterTest {
+    private TypeConverter typeConverter;
+
+    @BeforeEach
+    public void beforeEach() {
+        CamelContext camelContext = new DefaultCamelContext();
+        typeConverter = camelContext.getTypeConverter();
+    }
+
+    @Test
+    public void convertStringToJavaSourceWithoutEventStream() {
+        final String payload = "dummyPayload";
+        final JavaSourceWithoutEventStream javaSource = typeConverter.convertTo(JavaSourceWithoutEventStream.class, payload);
+        final Map<String, Object> beans = javaSource.getBeans();
+        final String actualPayload = (String) beans.get("string");
+
+        assertThat(payload, is(actualPayload));
+    }
+}
diff --git a/components/camel-smooks/src/test/resources/EBCDIC-input-message.txt b/components/camel-smooks/src/test/resources/EBCDIC-input-message.txt
new file mode 100644
index 00000000000..bd37c1664e6
--- /dev/null
+++ b/components/camel-smooks/src/test/resources/EBCDIC-input-message.txt
@@ -0,0 +1 @@
+L�����n@@@@L������n@@@@@@@@L����n慄@Ֆ�@��@��z��z��@���@����La����n@@@@@@@@L��������@������~������nі�La��������n@@@@La������n@@@@L�����`�����n@@@@@@@@L�����`����n@@@@@@@@@@@@L�������n�La�������n@@@@@@@@@@@@L��������n�La��������n@@@@@@@@@@@@L�����n�K��La�����n@@@@@@@@La�����`����n@@@@@@@@L�����`����n@@@@@@@@@@@@L�������n�La�������n@@@@@@@@@@@@L��������n�La��������n@@@@@@@@@@@@L�����n�K��La�����n@@@@@@@@La�����`����n@@@@La�����`�����nLa�����n
\ No newline at end of file
diff --git a/components/camel-smooks/src/test/resources/data/order.txt b/components/camel-smooks/src/test/resources/data/order.txt
new file mode 100644
index 00000000000..060c2422ac8
--- /dev/null
+++ b/components/camel-smooks/src/test/resources/data/order.txt
@@ -0,0 +1,4 @@
+HDR*1*0*59.97*64.92*4.95*Wed Nov 15 13:45:28 EST 2006
+CUS*user1*Harry^Fletcher*SD
+ORD*1*1*364*The 40-Year-Old Virgin*29.98
+ORD*2*1*299*Pulp Fiction*29.99
diff --git a/components/camel-smooks/src/test/resources/edi-mapping-model.dfdl.xsd b/components/camel-smooks/src/test/resources/edi-mapping-model.dfdl.xsd
new file mode 100644
index 00000000000..27411ddee31
--- /dev/null
+++ b/components/camel-smooks/src/test/resources/edi-mapping-model.dfdl.xsd
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+    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.
+
+-->
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+            xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/" xmlns:ibmEdiFmt="http://www.ibm.com/dfdl/EDI/Format">
+
+    <xsd:import namespace="http://www.ibm.com/dfdl/EDI/Format"
+                schemaLocation="/EDIFACT-Common/IBM_EDI_Format.dfdl.xsd"/>
+
+    <xsd:annotation>
+        <xsd:appinfo source="http://www.ogf.org/dfdl/">
+            <dfdl:format ref="ibmEdiFmt:EDIFormat"/>
+        </xsd:appinfo>
+    </xsd:annotation>
+
+    <xsd:element name="Order">
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:sequence dfdl:initiatedContent="yes">
+                    <xsd:element dfdl:initiator="HDR" dfdl:ref="ibmEdiFmt:EDISegmentFormat" name="header">
+                        <xsd:complexType>
+                            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
+                                <xsd:element name="order-id" type="xsd:string"/>
+                                <xsd:element name="status-code" type="xsd:string"/>
+                                <xsd:element name="net-amount" type="xsd:string"/>
+                                <xsd:element name="total-amount" type="xsd:string"/>
+                                <xsd:element name="tax" type="xsd:string"/>
+                                <xsd:element name="date" type="xsd:string"/>
+                            </xsd:sequence>
+                        </xsd:complexType>
+                    </xsd:element>
+                    <xsd:element dfdl:initiator="CUS" dfdl:ref="ibmEdiFmt:EDISegmentFormat" name="customer-details">
+                        <xsd:complexType>
+                            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
+                                <xsd:element name="username" type="xsd:string"/>
+                                <xsd:element name="name">
+                                    <xsd:complexType>
+                                        <xsd:sequence dfdl:ref="ibmEdiFmt:EDICompositeSequenceFormat">
+                                            <xsd:element name="firstname" type="xsd:string"/>
+                                            <xsd:element name="lastname" type="xsd:string"/>
+                                        </xsd:sequence>
+                                    </xsd:complexType>
+                                </xsd:element>
+                                <xsd:element name="state" type="xsd:string"/>
+                            </xsd:sequence>
+                        </xsd:complexType>
+                    </xsd:element>
+                    <xsd:element dfdl:initiator="ORD" dfdl:ref="ibmEdiFmt:EDISegmentFormat" name="order-item" maxOccurs="unbounded">
+                        <xsd:complexType>
+                            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
+                                <xsd:element name="position" type="xsd:string"/>
+                                <xsd:element name="quantity" type="xsd:string"/>
+                                <xsd:element name="product-id" type="xsd:string"/>
+                                <xsd:element name="title" type="xsd:string"/>
+                                <xsd:element name="price" type="xsd:string"/>
+                            </xsd:sequence>
+                        </xsd:complexType>
+                    </xsd:element>
+                </xsd:sequence>
+            </xsd:sequence>
+        </xsd:complexType>
+    </xsd:element>
+</xsd:schema>
\ No newline at end of file
diff --git a/components/camel-smooks/src/test/resources/edi-to-xml-smooks-config.xml b/components/camel-smooks/src/test/resources/edi-to-xml-smooks-config.xml
new file mode 100644
index 00000000000..82a5641a4e2
--- /dev/null
+++ b/components/camel-smooks/src/test/resources/edi-to-xml-smooks-config.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+
+    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.
+
+-->
+<smooks-resource-list
+        xmlns="https://www.smooks.org/xsd/smooks-2.0.xsd"
+        xmlns:edi="https://www.smooks.org/xsd/smooks/edi-2.0.xsd"
+        xmlns:core="https://www.smooks.org/xsd/smooks/smooks-core-1.6.xsd">
+
+    <!--
+    Configure the EDI Reader to process the message stream into a stream of SAX events.
+    -->
+    <edi:parser schemaUri="/edi-mapping-model.dfdl.xsd" segmentTerminator="%NL;" dataElementSeparator="*"
+                compositeDataElementSeparator="^"/>
+
+    <core:exports>
+        <core:result type="javax.xml.transform.dom.DOMResult"/>
+    </core:exports>
+
+</smooks-resource-list>
diff --git a/components/camel-smooks/src/test/resources/xml/expected-order.xml b/components/camel-smooks/src/test/resources/xml/expected-order.xml
new file mode 100644
index 00000000000..86521d8d1e9
--- /dev/null
+++ b/components/camel-smooks/src/test/resources/xml/expected-order.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<Order>
+    <header>
+        <order-id>1</order-id>
+        <status-code>0</status-code>
+        <net-amount>59.97</net-amount>
+        <total-amount>64.92</total-amount>
+        <tax>4.95</tax>
+        <date>Wed Nov 15 13:45:28 EST 2006</date>
+    </header>
+    <customer-details>
+        <username>user1</username>
+        <name>
+            <firstname>Harry</firstname>
+            <lastname>Fletcher</lastname>
+        </name>
+        <state>SD</state>
+    </customer-details>
+    <order-item>
+        <position>1</position>
+        <quantity>1</quantity>
+        <product-id>364</product-id>
+        <title>The 40-Year-Old Virgin</title>
+        <price>29.98</price>
+    </order-item>
+    <order-item>
+        <position>2</position>
+        <quantity>1</quantity>
+        <product-id>299</product-id>
+        <title>Pulp Fiction</title>
+        <price>29.99</price>
+    </order-item>
+</Order>
diff --git a/components/pom.xml b/components/pom.xml
index 9ff2502109d..a6e903a87e2 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -272,6 +272,7 @@
         <module>camel-sjms</module>
         <module>camel-slack</module>
         <module>camel-smb</module>
+        <module>camel-smooks</module>
         <module>camel-smpp</module>
         <module>camel-snakeyaml</module>
         <module>camel-snmp</module>
diff --git a/core/camel-main/src/generated/resources/org/apache/camel/main/components.properties b/core/camel-main/src/generated/resources/org/apache/camel/main/components.properties
index eda05e1c4c1..e321b253135 100644
--- a/core/camel-main/src/generated/resources/org/apache/camel/main/components.properties
+++ b/core/camel-main/src/generated/resources/org/apache/camel/main/components.properties
@@ -285,6 +285,7 @@ sjms
 sjms2
 slack
 smb
+smooks
 smpp
 smpps
 smtp
diff --git a/docs/components/modules/ROOT/nav.adoc b/docs/components/modules/ROOT/nav.adoc
index bbe5ed8bdc5..8b249c0f7e6 100644
--- a/docs/components/modules/ROOT/nav.adoc
+++ b/docs/components/modules/ROOT/nav.adoc
@@ -291,6 +291,7 @@
 ** xref:sjms2-component.adoc[Simple JMS2]
 ** xref:slack-component.adoc[Slack]
 ** xref:smb-component.adoc[SMB]
+** xref:smooks-component.adoc[Smooks]
 ** xref:smpp-component.adoc[SMPP]
 ** xref:snmp-component.adoc[SNMP]
 ** xref:splunk-component.adoc[Splunk]
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
index 95f70147e4b..5f699878c50 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
@@ -3855,6 +3855,20 @@ public interface ComponentsBuilderFactory {
     static SmbComponentBuilderFactory.SmbComponentBuilder smb() {
         return SmbComponentBuilderFactory.smb();
     }
+    /**
+     * Smooks (camel-smooks)
+     * Applies fragment-based processing in Smooks to perform a variety of
+     * operations like transformation.
+     * 
+     * Category: file
+     * Since: 4.7
+     * Maven coordinates: org.apache.camel:camel-smooks
+     * 
+     * @return the dsl builder
+     */
+    static SmooksComponentBuilderFactory.SmooksComponentBuilder smooks() {
+        return SmooksComponentBuilderFactory.smooks();
+    }
     /**
      * SMPP (camel-smpp)
      * Send and receive SMS messages using a SMSC (Short Message Service
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java
index e44d78fd785..553cf1630f3 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilderFactory.java
@@ -302,6 +302,7 @@ public interface EndpointBuilderFactory
             org.apache.camel.builder.endpoint.dsl.SjmsEndpointBuilderFactory.SjmsBuilders,
             org.apache.camel.builder.endpoint.dsl.SlackEndpointBuilderFactory.SlackBuilders,
             org.apache.camel.builder.endpoint.dsl.SmbEndpointBuilderFactory.SmbBuilders,
+            org.apache.camel.builder.endpoint.dsl.SmooksEndpointBuilderFactory.SmooksBuilders,
             org.apache.camel.builder.endpoint.dsl.SmppEndpointBuilderFactory.SmppBuilders,
             org.apache.camel.builder.endpoint.dsl.SnmpEndpointBuilderFactory.SnmpBuilders,
             org.apache.camel.builder.endpoint.dsl.Sns2EndpointBuilderFactory.Sns2Builders,
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilders.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilders.java
index 00484b3cc26..b91d8600978 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilders.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/EndpointBuilders.java
@@ -299,6 +299,7 @@ public interface EndpointBuilders
             org.apache.camel.builder.endpoint.dsl.SjmsEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.SlackEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.SmbEndpointBuilderFactory,
+            org.apache.camel.builder.endpoint.dsl.SmooksEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.SmppEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.SnmpEndpointBuilderFactory,
             org.apache.camel.builder.endpoint.dsl.Sns2EndpointBuilderFactory,
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
index 59f2e70906f..dad93cb86c3 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
@@ -13035,6 +13035,48 @@ public class StaticEndpointBuilders {
     public static SmbEndpointBuilderFactory.SmbEndpointBuilder smb(String componentName, String path) {
         return SmbEndpointBuilderFactory.endpointBuilder(componentName, path);
     }
+    /**
+     * Smooks (camel-smooks)
+     * Applies fragment-based processing in Smooks to perform a variety of
+     * operations like transformation.
+     * 
+     * Category: file
+     * Since: 4.7
+     * Maven coordinates: org.apache.camel:camel-smooks
+     * 
+     * Syntax: <code>smooks://smooks-config-path</code>
+     * 
+     * Path parameter: database (required)
+     * database name
+     * 
+     * @param path smooks-config-path
+     * @return the dsl builder
+     */
+    public static SmooksEndpointBuilderFactory.SmooksEndpointBuilder smooks(String path) {
+        return smooks("smooks", path);
+    }
+    /**
+     * Smooks (camel-smooks)
+     * Applies fragment-based processing in Smooks to perform a variety of
+     * operations like transformation.
+     * 
+     * Category: file
+     * Since: 4.7
+     * Maven coordinates: org.apache.camel:camel-smooks
+     * 
+     * Syntax: <code>smooks://smooks-config-path</code>
+     * 
+     * Path parameter: database (required)
+     * database name
+     * 
+     * @param componentName to use a custom component name for the endpoint
+     * instead of the default name
+     * @param path smooks-config-path
+     * @return the dsl builder
+     */
+    public static SmooksEndpointBuilderFactory.SmooksEndpointBuilder smooks(String componentName, String path) {
+        return SmooksEndpointBuilderFactory.endpointBuilder(componentName, path);
+    }
     /**
      * SMPP (camel-smpp)
      * Send and receive SMS messages using a SMSC (Short Message Service
diff --git a/dsl/camel-kamelet-main/src/generated/resources/camel-component-known-dependencies.properties b/dsl/camel-kamelet-main/src/generated/resources/camel-component-known-dependencies.properties
index 9d682b56ca3..138872650e2 100644
--- a/dsl/camel-kamelet-main/src/generated/resources/camel-component-known-dependencies.properties
+++ b/dsl/camel-kamelet-main/src/generated/resources/camel-component-known-dependencies.properties
@@ -295,6 +295,7 @@ org.apache.camel.component.sjms.SjmsComponent=camel:sjms
 org.apache.camel.component.sjms2.Sjms2Component=camel:sjms2
 org.apache.camel.component.slack.SlackComponent=camel:slack
 org.apache.camel.component.smb.SmbComponent=camel:smb
+org.apache.camel.component.smooks.SmooksComponent=camel:smooks
 org.apache.camel.component.smpp.SmppComponent=camel:smpp
 org.apache.camel.component.snmp.SnmpComponent=camel:snmp
 org.apache.camel.component.splunk.SplunkComponent=camel:splunk
diff --git a/parent/pom.xml b/parent/pom.xml
index c7e4d872490..00df68bb3d5 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -2209,6 +2209,11 @@
                 <artifactId>camel-smb</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-smooks</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-smpp</artifactId>


(camel) 02/03: CAMEL-19985: Smooks component

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch cjmamo-CAMEL-19985
in repository https://gitbox.apache.org/repos/asf/camel.git

commit e48414ad5ece73e6588c8144c196762f7c0281e7
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Jun 3 10:59:29 2024 +0200

    CAMEL-19985: Smooks component
---
 .../apache/camel/catalog/components}/smooks.json   |   0
 .../component/smooks/SmooksEndpointUriFactory.java |   6 +-
 .../org/apache/camel/component/smooks/smooks.json  |   8 +-
 .../src/main/docs/smooks-component.adoc            |   2 +-
 .../camel/component/smooks/SmooksComponent.java    |  20 +-
 .../camel/component/smooks/SmooksEndpoint.java     |  43 +-
 .../camel/component/smooks/SmooksProcessor.java    | 133 ++--
 .../smooks/converter/ResultConverter.java          |   3 +-
 .../smooks/converter/SourceConverter.java          |   4 +-
 .../apache/camel/component/smooks/Coordinate.java  |   3 -
 .../component/smooks/SmooksComponentTest.java      |   7 +-
 .../component/smooks/SmooksProcessorTest.java      |   7 +-
 .../smooks/converter/ResultConverterTest.java      |   6 +-
 .../smooks/converter/SourceConverterTest.java      |   6 +-
 .../dsl/SmooksComponentBuilderFactory.java         | 151 ++++
 .../endpoint/dsl/SmooksEndpointBuilderFactory.java | 847 +++++++++++++++++++++
 16 files changed, 1108 insertions(+), 138 deletions(-)

diff --git a/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json
similarity index 100%
copy from components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
copy to catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json
diff --git a/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointUriFactory.java b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointUriFactory.java
index a7552824dd9..781876531a3 100644
--- a/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointUriFactory.java
+++ b/components/camel-smooks/src/generated/java/org/apache/camel/component/smooks/SmooksEndpointUriFactory.java
@@ -17,7 +17,7 @@ import org.apache.camel.spi.EndpointUriFactory;
 @Generated("org.apache.camel.maven.packaging.GenerateEndpointUriFactoryMojo")
 public class SmooksEndpointUriFactory extends org.apache.camel.support.component.EndpointUriFactorySupport implements EndpointUriFactory {
 
-    private static final String BASE = "://smooks-config-path";
+    private static final String BASE = ":smooksConfig";
 
     private static final Set<String> PROPERTY_NAMES;
     private static final Set<String> SECRET_PROPERTY_NAMES;
@@ -28,7 +28,6 @@ public class SmooksEndpointUriFactory extends org.apache.camel.support.component
         props.add("backoffIdleThreshold");
         props.add("backoffMultiplier");
         props.add("bridgeErrorHandler");
-        props.add("database");
         props.add("delay");
         props.add("exceptionHandler");
         props.add("exchangePattern");
@@ -42,6 +41,7 @@ public class SmooksEndpointUriFactory extends org.apache.camel.support.component
         props.add("scheduler");
         props.add("schedulerProperties");
         props.add("sendEmptyMessageWhenIdle");
+        props.add("smooksConfig");
         props.add("startScheduler");
         props.add("timeUnit");
         props.add("useFixedDelay");
@@ -64,7 +64,7 @@ public class SmooksEndpointUriFactory extends org.apache.camel.support.component
 
         Map<String, Object> copy = new HashMap<>(properties);
 
-        uri = buildPathParameter(syntax, uri, "database", null, true, copy);
+        uri = buildPathParameter(syntax, uri, "smooksConfig", null, true, copy);
         uri = buildQueryParameters(uri, copy, encode);
         return uri;
     }
diff --git a/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json b/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
index cb677a24991..993bf295f63 100644
--- a/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
+++ b/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
@@ -3,10 +3,10 @@
     "kind": "component",
     "name": "smooks",
     "title": "Smooks",
-    "description": "Applies fragment-based processing in Smooks to perform a variety of operations like transformation.",
+    "description": "EDI, XML, CSV, etc. based data transformation using Smooks.",
     "deprecated": false,
     "firstVersion": "4.7.0",
-    "label": "file",
+    "label": "transformation",
     "javaType": "org.apache.camel.component.smooks.SmooksComponent",
     "supportLevel": "Preview",
     "groupId": "org.apache.camel",
@@ -14,7 +14,7 @@
     "version": "4.7.0-SNAPSHOT",
     "scheme": "smooks",
     "extendsScheme": "",
-    "syntax": "smooks:\/\/smooks-config-path",
+    "syntax": "smooks:smooksConfig",
     "async": false,
     "api": false,
     "consumerOnly": false,
@@ -28,7 +28,7 @@
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
   },
   "properties": {
-    "database": { "index": 0, "kind": "path", "displayName": "Database", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "database name" },
+    "smooksConfig": { "index": 0, "kind": "path", "displayName": "Smooks Config", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "description": "Smooks XML configuration file" },
     "sendEmptyMessageWhenIdle": { "index": 1, "kind": "parameter", "displayName": "Send Empty Message When Idle", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the polling consumer did not poll any files, you can enable this option to send an empty message (no body) instead." },
     "bridgeErrorHandler": { "index": 2, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming  [...]
     "exceptionHandler": { "index": 3, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By def [...]
diff --git a/components/camel-smooks/src/main/docs/smooks-component.adoc b/components/camel-smooks/src/main/docs/smooks-component.adoc
index d5d1a1056af..1a7f571a90d 100644
--- a/components/camel-smooks/src/main/docs/smooks-component.adoc
+++ b/components/camel-smooks/src/main/docs/smooks-component.adoc
@@ -2,7 +2,7 @@
 :doctitle: Smooks
 :shortname: smooks
 :artifactid: camel-smooks
-:description: Applies fragment-based processing in Smooks to perform a variety of operations like transformation.
+:description: EDI, XML, CSV, etc. based data transformation using Smooks.
 :since: 4.7
 :supportlevel: Preview
 :tabs-sync-option:
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksComponent.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksComponent.java
index 42bcf7cf613..cf2406bebc1 100644
--- a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksComponent.java
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksComponent.java
@@ -22,25 +22,17 @@ import org.apache.camel.Endpoint;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
 
-/**
- * Smook Camel Component.
- * <p/>
- * <p>
- * Example usage:
- *
- * <pre>
- * from(&quot;direct:a&quot;).to(&quot;smooks://edi-to-xml-smooks-config.xml&quot;)
- * </pre>
- *
- * @author Christian Mueller
- * @author Daniel Bevenius
- */
 @Component("smooks")
 public class SmooksComponent extends DefaultComponent {
+
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
         SmooksProcessor smooksProcessor = new SmooksProcessor(remaining, getCamelContext());
         configureSmooksProcessor(smooksProcessor, uri, remaining, parameters);
-        return new SmooksEndpoint(uri, this, smooksProcessor);
+
+        SmooksEndpoint endpoint = new SmooksEndpoint(uri, this, smooksProcessor);
+        endpoint.setSmooksConfig(remaining);
+        setProperties(endpoint, parameters);
+        return endpoint;
     }
 
     protected void configureSmooksProcessor(SmooksProcessor smooksProcessor, String uri, String remaining,
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java
index 641d58f3d10..29e6df5b160 100644
--- a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java
@@ -18,22 +18,21 @@ package org.apache.camel.component.smooks;
 
 import org.apache.camel.Category;
 import org.apache.camel.Component;
-import org.apache.camel.Service;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriPath;
 import org.apache.camel.support.ProcessorEndpoint;
-import org.smooks.api.SmooksException;
+import org.apache.camel.support.service.ServiceHelper;
 
 /**
- * Applies fragment-based processing in Smooks to perform a variety of operations like transformation.
+ * EDI, XML, CSV, etc. based data transformation using Smooks.
  */
-@UriEndpoint(firstVersion = "4.7.0", scheme = "smooks", title = "Smooks", syntax = "smooks://smooks-config-path", category = { Category.FILE })
-public class SmooksEndpoint extends ProcessorEndpoint implements Service {
+@UriEndpoint(firstVersion = "4.7.0", scheme = "smooks", title = "Smooks", syntax = "smooks:smooksConfig", category = { Category.TRANSFORMATION })
+public class SmooksEndpoint extends ProcessorEndpoint {
 
-    @UriPath(description = "database name")
-    @Metadata(required = true)
-    private String database;
+    @UriPath(description = "Smooks XML configuration file")
+    @Metadata(required = true, supportFileReference = true)
+    private String smooksConfig;
 
     private final SmooksProcessor smooksProcessor;
 
@@ -42,20 +41,24 @@ public class SmooksEndpoint extends ProcessorEndpoint implements Service {
         this.smooksProcessor = processor;
     }
 
-    public void start() {
-        try {
-            smooksProcessor.start();
-        } catch (Exception e) {
-            throw new SmooksException(e.getMessage(), e);
-        }
+    public String getSmooksConfig() {
+        return smooksConfig;
     }
 
-    public void stop() {
-        try {
-            smooksProcessor.stop();
-        } catch (Exception e) {
-            throw new SmooksException(e.getMessage(), e);
-        }
+    public void setSmooksConfig(String smooksConfig) {
+        this.smooksConfig = smooksConfig;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        ServiceHelper.startService(smooksProcessor);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+        ServiceHelper.stopService(smooksProcessor);
     }
 
 }
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
index 3636f2f86a3..a6abc57aa1c 100644
--- a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
@@ -38,10 +38,12 @@ import org.apache.camel.CamelContextAware;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.Processor;
-import org.apache.camel.Service;
 import org.apache.camel.WrappedFile;
 import org.apache.camel.attachment.Attachment;
 import org.apache.camel.attachment.AttachmentMessage;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.IOHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.smooks.Smooks;
@@ -57,24 +59,22 @@ import org.smooks.io.payload.Exports;
 
 /**
  * Smooks {@link Processor} for Camel.
- *
- * @author Christian Mueller
- * @author Daniel Bevenius
  */
-public class SmooksProcessor implements Processor, Service, CamelContextAware {
+public class SmooksProcessor extends ServiceSupport implements Processor, CamelContextAware {
+
     public static final String SMOOKS_EXECUTION_CONTEXT = "CamelSmooksExecutionContext";
-    public static final String CAMEL_CHARACTER_ENCODING = "CamelCharsetName";
-    private static final Logger LOGGER = LoggerFactory.getLogger(SmooksProcessor.class);
-    public static final TypedKey<Exchange> EXCHANGE_TYPED_KEY = TypedKey.of();
+
+    private static final TypedKey<Exchange> EXCHANGE_TYPED_KEY = TypedKey.of();
+    private static final Logger LOG = LoggerFactory.getLogger(SmooksProcessor.class);
 
     private Smooks smooks;
     private String configUri;
     private String reportPath;
 
-    private Set<VisitorAppender> visitorAppenders = new HashSet<>();
-    private Map<String, Visitor> selectorVisitorMap = new HashMap<>();
+    private final Set<VisitorAppender> visitorAppender = new HashSet<>();
+    private final Map<String, Visitor> selectorVisitorMap = new HashMap<>();
     private CamelContext camelContext;
-    private boolean attachmentsSupported = false;
+    private boolean attachmentsSupported;
 
     public SmooksProcessor(final CamelContext camelContext) {
         this.camelContext = camelContext;
@@ -90,6 +90,14 @@ public class SmooksProcessor implements Processor, Service, CamelContextAware {
         this.configUri = configUri;
     }
 
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
     public void process(final Exchange exchange) {
         //forward headers
         exchange.getMessage().setHeaders(exchange.getIn().getHeaders());
@@ -104,25 +112,27 @@ public class SmooksProcessor implements Processor, Service, CamelContextAware {
         }
 
         final ExecutionContext executionContext = smooks.createExecutionContext();
-        executionContext.put(EXCHANGE_TYPED_KEY, exchange);
-        String charsetName = (String) exchange.getProperty(CAMEL_CHARACTER_ENCODING);
-        if (charsetName != null) //if provided use the came character encoding
-        {
-            executionContext.setContentEncoding(charsetName);
-        }
-        exchange.getIn().setHeader(SMOOKS_EXECUTION_CONTEXT, executionContext);
-        setupSmooksReporting(executionContext);
-
-        final Exports exports = smooks.getApplicationContext().getRegistry().lookup(new ExportsLookup());
-        if (exports.hasExports()) {
-            final Result[] results = exports.createResults();
-            smooks.filterSource(executionContext, getSource(exchange), results);
-            setResultOnBody(exports, results, exchange);
-        } else {
-            smooks.filterSource(executionContext, getSource(exchange));
+        try {
+            executionContext.put(EXCHANGE_TYPED_KEY, exchange);
+            String charsetName = (String) exchange.getProperty(Exchange.CHARSET_NAME);
+            if (charsetName != null) {
+                // if provided use the came character encoding
+                executionContext.setContentEncoding(charsetName);
+            }
+            exchange.getIn().setHeader(SMOOKS_EXECUTION_CONTEXT, executionContext);
+            setupSmooksReporting(executionContext);
+
+            final Exports exports = smooks.getApplicationContext().getRegistry().lookup(new ExportsLookup());
+            if (exports.hasExports()) {
+                final Result[] results = exports.createResults();
+                smooks.filterSource(executionContext, getSource(exchange), results);
+                setResultOnBody(exports, results, exchange);
+            } else {
+                smooks.filterSource(executionContext, getSource(exchange));
+            }
+        } finally {
+            executionContext.remove(EXCHANGE_TYPED_KEY);
         }
-
-        executionContext.remove(EXCHANGE_TYPED_KEY);
     }
 
     protected void setResultOnBody(final Exports exports, final Result[] results, final Exchange exchange) {
@@ -141,7 +151,7 @@ public class SmooksProcessor implements Processor, Service, CamelContextAware {
             try {
                 executionContext.getContentDeliveryRuntime().addExecutionEventListener(new HtmlReportGenerator(reportPath, executionContext.getApplicationContext()));
             } catch (final IOException e) {
-                LOGGER.info("Could not generate Smooks Report. The reportPath specified was [" + reportPath + "].", e);
+                LOG.warn("Cannot generate Smooks Report. The reportPath specified was [" + reportPath + "]. This exception is ignored.", e);
             }
         }
     }
@@ -205,7 +215,7 @@ public class SmooksProcessor implements Processor, Service, CamelContextAware {
      * @return This instance.
      */
     public SmooksProcessor addVisitor(VisitorAppender appender) {
-        visitorAppenders.add(appender);
+        visitorAppender.add(appender);
         return this;
     }
 
@@ -213,19 +223,35 @@ public class SmooksProcessor implements Processor, Service, CamelContextAware {
         this.reportPath = reportPath;
     }
 
+    private Smooks createSmooks() {
+        final SmooksFactory smooksFactory = (SmooksFactory) camelContext.getRegistry().lookupByName(SmooksFactory.class.getName());
+        return smooksFactory != null ? smooksFactory.createInstance() : new Smooks();
+    }
+
+    private void addAppender(Smooks smooks, Set<VisitorAppender> visitorAppenders) {
+        for (VisitorAppender appender : visitorAppenders)
+            smooks.addVisitors(appender);
+    }
+
+    private void addVisitor(Smooks smooks, Map<String, Visitor> selectorVisitorMap) {
+        for (Entry<String, Visitor> entry : selectorVisitorMap.entrySet())
+            smooks.addVisitor(entry.getValue(), entry.getKey());
+    }
+
     @Override
-    public void start() {
+    protected void doStart() throws Exception {
         try {
             if (smooks == null) {
                 smooks = createSmooks();
                 if (configUri != null) {
-                    smooks.addResourceConfigs(configUri);
+                    InputStream is = ResourceHelper.resolveMandatoryResourceAsInputStream(camelContext, configUri);
+                    smooks.addResourceConfigs(is);
                 }
                 smooks.getApplicationContext().getRegistry().registerObject(CamelContext.class, camelContext);
             }
 
-            addAppenders(smooks, visitorAppenders);
-            addVisitors(smooks, selectorVisitorMap);
+            addAppender(smooks, visitorAppender);
+            addVisitor(smooks, selectorVisitorMap);
 
             InputStream inputStream = null;
             try {
@@ -239,53 +265,28 @@ public class SmooksProcessor implements Processor, Service, CamelContextAware {
                 }
             } finally {
                 if (!attachmentsSupported) {
-                    LOGGER.warn("Attachments module could not be found: attachments will not be propagated");
+                    LOG.warn("Attachments module could not be found: attachments will not be propagated");
                 }
                 if (inputStream != null) {
                     inputStream.close();
                 }
             }
-
-            LOGGER.info(this + " Started");
-        } catch (SAXException | IOException e) {
+        } catch (Exception e) {
             throw new SmooksException(e.getMessage(), e);
         }
     }
 
-    private Smooks createSmooks() {
-        final SmooksFactory smooksFactory = (SmooksFactory) camelContext.getRegistry().lookupByName(SmooksFactory.class.getName());
-        return smooksFactory != null ? smooksFactory.createInstance() : new Smooks();
-    }
-
-    private void addAppenders(Smooks smooks, Set<VisitorAppender> visitorAppenders) {
-        for (VisitorAppender appender : visitorAppenders)
-            smooks.addVisitors(appender);
-    }
-
-    private void addVisitors(Smooks smooks, Map<String, Visitor> selectorVisitorMap) {
-        for (Entry<String, Visitor> entry : selectorVisitorMap.entrySet())
-            smooks.addVisitor(entry.getValue(), entry.getKey());
-    }
-
-    public void stop() {
+    @Override
+    protected void doStop() throws Exception {
         if (smooks != null) {
-            smooks.close();
+            IOHelper.close(smooks);
             smooks = null;
         }
-        LOGGER.info(this + " Stopped");
     }
 
     @Override
     public String toString() {
-        return "SmooksProcessor [configUri=" + configUri + "]";
-    }
-
-    public void setCamelContext(CamelContext camelContext) {
-        this.camelContext = camelContext;
-    }
-
-    public CamelContext getCamelContext() {
-        return camelContext;
+        return "SmooksProcessor[configUri=" + configUri + "]";
     }
 
 }
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/ResultConverter.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/ResultConverter.java
index 74d6d41376b..06897d8f8fb 100644
--- a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/ResultConverter.java
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/ResultConverter.java
@@ -37,11 +37,10 @@ import org.smooks.io.payload.StringResult;
 
 /**
  * ResultConverter converts from different {@link Result} types.
- *
- * @author Daniel Bevenius
  */
 @Converter(generateLoader = true)
 public class ResultConverter {
+
     public static final String SMOOKS_RESULT_KEY = "SmooksResultKeys";
 
     private ResultConverter() {
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/SourceConverter.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/SourceConverter.java
index 994d249fc3e..a411b4a784a 100644
--- a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/SourceConverter.java
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/converter/SourceConverter.java
@@ -31,8 +31,6 @@ import org.smooks.io.payload.JavaSourceWithoutEventStream;
 /**
  * SourceConverter is a Camel {@link Converter} that converts from different
  * formats to {@link Source} instances. </p>
- *
- * @author Daniel Bevenius
  */
 @Converter(generateLoader = true)
 public class SourceConverter {
@@ -61,7 +59,7 @@ public class SourceConverter {
 
     @Converter
     public static Source toStreamSource(GenericFile<File> genericFile) {
-        return new StreamSource((File) genericFile.getBody());
+        return new StreamSource(genericFile.getFile());
     }
 
 }
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/Coordinate.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/Coordinate.java
index 742e96adc33..af4c1af02fd 100644
--- a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/Coordinate.java
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/Coordinate.java
@@ -16,9 +16,6 @@
  */
 package org.apache.camel.component.smooks;
 
-/**
- * @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
- */
 public class Coordinate {
 
     private Integer x;
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksComponentTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksComponentTest.java
index ed87219c5c2..44fcc9b252e 100644
--- a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksComponentTest.java
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksComponentTest.java
@@ -32,13 +32,8 @@ import static org.apache.camel.component.mock.MockEndpoint.assertIsSatisfied;
 import static org.apache.camel.test.junit5.TestSupport.assertIsInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 
-/**
- * Unit test for {@link SmooksComponent}.
- *
- * @author Christian Mueller
- * @author Daniel Bevenius
- */
 public class SmooksComponentTest extends CamelTestSupport {
+
     @EndpointInject(value = "mock:result")
     private MockEndpoint mockEndpoint;
 
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java
index 5cf61198854..82afff24154 100644
--- a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java
@@ -63,13 +63,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-/**
- * Unit test for {@link SmooksProcessor}.
- *
- * @author Christian Mueller
- * @author Daniel Bevenius
- */
 public class SmooksProcessorTest extends CamelTestSupport {
+
     @EndpointInject(value = "mock:result")
     private MockEndpoint result;
 
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/ResultConverterTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/ResultConverterTest.java
index 408da4585d8..08d3e52cb9d 100644
--- a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/ResultConverterTest.java
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/ResultConverterTest.java
@@ -29,12 +29,8 @@ import org.smooks.io.payload.StringResult;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-/**
- * Unit test for {@link ResultConverter}.
- *
- * @author Daniel Bevenius
- */
 public class ResultConverterTest {
+
     private TypeConverter typeConverter;
 
     @BeforeEach
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/SourceConverterTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/SourceConverterTest.java
index 92396a6ab8a..fdc52368d11 100644
--- a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/SourceConverterTest.java
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/converter/SourceConverterTest.java
@@ -28,12 +28,8 @@ import org.smooks.io.payload.JavaSourceWithoutEventStream;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-/**
- * Unit test for {@link SourceConverter}. </p>
- *
- * @author Daniel Bevenius
- */
 public class SourceConverterTest {
+
     private TypeConverter typeConverter;
 
     @BeforeEach
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmooksComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmooksComponentBuilderFactory.java
new file mode 100644
index 00000000000..1e9b50ea171
--- /dev/null
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmooksComponentBuilderFactory.java
@@ -0,0 +1,151 @@
+/* Generated by camel build tools - do NOT edit this file! */
+/*
+ * 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.builder.component.dsl;
+
+import javax.annotation.processing.Generated;
+import org.apache.camel.Component;
+import org.apache.camel.builder.component.AbstractComponentBuilder;
+import org.apache.camel.builder.component.ComponentBuilder;
+import org.apache.camel.component.smooks.SmooksComponent;
+
+/**
+ * Applies fragment-based processing in Smooks to perform a variety of
+ * operations like transformation.
+ * 
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.ComponentDslMojo")
+public interface SmooksComponentBuilderFactory {
+
+    /**
+     * Smooks (camel-smooks)
+     * Applies fragment-based processing in Smooks to perform a variety of
+     * operations like transformation.
+     * 
+     * Category: file
+     * Since: 4.7
+     * Maven coordinates: org.apache.camel:camel-smooks
+     * 
+     * @return the dsl builder
+     */
+    static SmooksComponentBuilder smooks() {
+        return new SmooksComponentBuilderImpl();
+    }
+
+    /**
+     * Builder for the Smooks component.
+     */
+    interface SmooksComponentBuilder extends ComponentBuilder<SmooksComponent> {
+    
+        
+        /**
+         * Allows for bridging the consumer to the Camel routing Error Handler,
+         * which mean any exceptions (if possible) occurred while the Camel
+         * consumer is trying to pickup incoming messages, or the likes, will
+         * now be processed as a message and handled by the routing Error
+         * Handler. Important: This is only possible if the 3rd party component
+         * allows Camel to be alerted if an exception was thrown. Some
+         * components handle this internally only, and therefore
+         * bridgeErrorHandler is not possible. In other situations we may
+         * improve the Camel component to hook into the 3rd party component and
+         * make this possible for future releases. By default the consumer will
+         * use the org.apache.camel.spi.ExceptionHandler to deal with
+         * exceptions, that will be logged at WARN or ERROR level and ignored.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param bridgeErrorHandler the value to set
+         * @return the dsl builder
+         */
+        default SmooksComponentBuilder bridgeErrorHandler(boolean bridgeErrorHandler) {
+            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
+            return this;
+        }
+    
+        
+        /**
+         * Whether the producer should be started lazy (on the first message).
+         * By starting lazy you can use this to allow CamelContext and routes to
+         * startup in situations where a producer may otherwise fail during
+         * starting and cause the route to fail being started. By deferring this
+         * startup to be lazy then the startup failure can be handled during
+         * routing messages via Camel's routing error handlers. Beware that when
+         * the first message is processed then creating and starting the
+         * producer may take a little time and prolong the total processing time
+         * of the processing.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: producer
+         * 
+         * @param lazyStartProducer the value to set
+         * @return the dsl builder
+         */
+        default SmooksComponentBuilder lazyStartProducer(boolean lazyStartProducer) {
+            doSetProperty("lazyStartProducer", lazyStartProducer);
+            return this;
+        }
+    
+        
+        /**
+         * Whether autowiring is enabled. This is used for automatic autowiring
+         * options (the option must be marked as autowired) by looking up in the
+         * registry to find if there is a single instance of matching type,
+         * which then gets configured on the component. This can be used for
+         * automatic configuring JDBC data sources, JMS connection factories,
+         * AWS Clients, etc.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: true
+         * Group: advanced
+         * 
+         * @param autowiredEnabled the value to set
+         * @return the dsl builder
+         */
+        default SmooksComponentBuilder autowiredEnabled(boolean autowiredEnabled) {
+            doSetProperty("autowiredEnabled", autowiredEnabled);
+            return this;
+        }
+    }
+
+    class SmooksComponentBuilderImpl
+            extends AbstractComponentBuilder<SmooksComponent>
+            implements SmooksComponentBuilder {
+        @Override
+        protected SmooksComponent buildConcreteComponent() {
+            return new SmooksComponent();
+        }
+        @Override
+        protected boolean setPropertyOnComponent(
+                Component component,
+                String name,
+                Object value) {
+            switch (name) {
+            case "bridgeErrorHandler": ((SmooksComponent) component).setBridgeErrorHandler((boolean) value); return true;
+            case "lazyStartProducer": ((SmooksComponent) component).setLazyStartProducer((boolean) value); return true;
+            case "autowiredEnabled": ((SmooksComponent) component).setAutowiredEnabled((boolean) value); return true;
+            default: return false;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java
new file mode 100644
index 00000000000..f1fef38d77a
--- /dev/null
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java
@@ -0,0 +1,847 @@
+/* Generated by camel build tools - do NOT edit this file! */
+/*
+ * 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.builder.endpoint.dsl;
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.function.*;
+import java.util.stream.*;
+import javax.annotation.processing.Generated;
+import org.apache.camel.builder.EndpointConsumerBuilder;
+import org.apache.camel.builder.EndpointProducerBuilder;
+import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
+
+/**
+ * Applies fragment-based processing in Smooks to perform a variety of
+ * operations like transformation.
+ * 
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
+public interface SmooksEndpointBuilderFactory {
+
+    /**
+     * Builder for endpoint consumers for the Smooks component.
+     */
+    public interface SmooksEndpointConsumerBuilder
+            extends
+                EndpointConsumerBuilder {
+        default AdvancedSmooksEndpointConsumerBuilder advanced() {
+            return (AdvancedSmooksEndpointConsumerBuilder) this;
+        }
+        /**
+         * If the polling consumer did not poll any files, you can enable this
+         * option to send an empty message (no body) instead.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param sendEmptyMessageWhenIdle the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder sendEmptyMessageWhenIdle(boolean sendEmptyMessageWhenIdle) {
+            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
+            return this;
+        }
+        /**
+         * If the polling consumer did not poll any files, you can enable this
+         * option to send an empty message (no body) instead.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param sendEmptyMessageWhenIdle the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder sendEmptyMessageWhenIdle(String sendEmptyMessageWhenIdle) {
+            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
+            return this;
+        }
+        /**
+         * The number of subsequent error polls (failed due some error) that
+         * should happen before the backoffMultipler should kick-in.
+         * 
+         * The option is a: <code>int</code> type.
+         * 
+         * Group: scheduler
+         * 
+         * @param backoffErrorThreshold the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder backoffErrorThreshold(int backoffErrorThreshold) {
+            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
+            return this;
+        }
+        /**
+         * The number of subsequent error polls (failed due some error) that
+         * should happen before the backoffMultipler should kick-in.
+         * 
+         * The option will be converted to a <code>int</code> type.
+         * 
+         * Group: scheduler
+         * 
+         * @param backoffErrorThreshold the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder backoffErrorThreshold(String backoffErrorThreshold) {
+            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
+            return this;
+        }
+        /**
+         * The number of subsequent idle polls that should happen before the
+         * backoffMultipler should kick-in.
+         * 
+         * The option is a: <code>int</code> type.
+         * 
+         * Group: scheduler
+         * 
+         * @param backoffIdleThreshold the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder backoffIdleThreshold(int backoffIdleThreshold) {
+            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
+            return this;
+        }
+        /**
+         * The number of subsequent idle polls that should happen before the
+         * backoffMultipler should kick-in.
+         * 
+         * The option will be converted to a <code>int</code> type.
+         * 
+         * Group: scheduler
+         * 
+         * @param backoffIdleThreshold the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder backoffIdleThreshold(String backoffIdleThreshold) {
+            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
+            return this;
+        }
+        /**
+         * To let the scheduled polling consumer backoff if there has been a
+         * number of subsequent idles/errors in a row. The multiplier is then
+         * the number of polls that will be skipped before the next actual
+         * attempt is happening again. When this option is in use then
+         * backoffIdleThreshold and/or backoffErrorThreshold must also be
+         * configured.
+         * 
+         * The option is a: <code>int</code> type.
+         * 
+         * Group: scheduler
+         * 
+         * @param backoffMultiplier the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder backoffMultiplier(int backoffMultiplier) {
+            doSetProperty("backoffMultiplier", backoffMultiplier);
+            return this;
+        }
+        /**
+         * To let the scheduled polling consumer backoff if there has been a
+         * number of subsequent idles/errors in a row. The multiplier is then
+         * the number of polls that will be skipped before the next actual
+         * attempt is happening again. When this option is in use then
+         * backoffIdleThreshold and/or backoffErrorThreshold must also be
+         * configured.
+         * 
+         * The option will be converted to a <code>int</code> type.
+         * 
+         * Group: scheduler
+         * 
+         * @param backoffMultiplier the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder backoffMultiplier(String backoffMultiplier) {
+            doSetProperty("backoffMultiplier", backoffMultiplier);
+            return this;
+        }
+        /**
+         * Milliseconds before the next poll.
+         * 
+         * The option is a: <code>long</code> type.
+         * 
+         * Default: 500
+         * Group: scheduler
+         * 
+         * @param delay the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder delay(long delay) {
+            doSetProperty("delay", delay);
+            return this;
+        }
+        /**
+         * Milliseconds before the next poll.
+         * 
+         * The option will be converted to a <code>long</code> type.
+         * 
+         * Default: 500
+         * Group: scheduler
+         * 
+         * @param delay the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder delay(String delay) {
+            doSetProperty("delay", delay);
+            return this;
+        }
+        /**
+         * If greedy is enabled, then the ScheduledPollConsumer will run
+         * immediately again, if the previous run polled 1 or more messages.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: scheduler
+         * 
+         * @param greedy the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder greedy(boolean greedy) {
+            doSetProperty("greedy", greedy);
+            return this;
+        }
+        /**
+         * If greedy is enabled, then the ScheduledPollConsumer will run
+         * immediately again, if the previous run polled 1 or more messages.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: scheduler
+         * 
+         * @param greedy the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder greedy(String greedy) {
+            doSetProperty("greedy", greedy);
+            return this;
+        }
+        /**
+         * Milliseconds before the first poll starts.
+         * 
+         * The option is a: <code>long</code> type.
+         * 
+         * Default: 1000
+         * Group: scheduler
+         * 
+         * @param initialDelay the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder initialDelay(long initialDelay) {
+            doSetProperty("initialDelay", initialDelay);
+            return this;
+        }
+        /**
+         * Milliseconds before the first poll starts.
+         * 
+         * The option will be converted to a <code>long</code> type.
+         * 
+         * Default: 1000
+         * Group: scheduler
+         * 
+         * @param initialDelay the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder initialDelay(String initialDelay) {
+            doSetProperty("initialDelay", initialDelay);
+            return this;
+        }
+        /**
+         * Specifies a maximum limit of number of fires. So if you set it to 1,
+         * the scheduler will only fire once. If you set it to 5, it will only
+         * fire five times. A value of zero or negative means fire forever.
+         * 
+         * The option is a: <code>long</code> type.
+         * 
+         * Default: 0
+         * Group: scheduler
+         * 
+         * @param repeatCount the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder repeatCount(long repeatCount) {
+            doSetProperty("repeatCount", repeatCount);
+            return this;
+        }
+        /**
+         * Specifies a maximum limit of number of fires. So if you set it to 1,
+         * the scheduler will only fire once. If you set it to 5, it will only
+         * fire five times. A value of zero or negative means fire forever.
+         * 
+         * The option will be converted to a <code>long</code> type.
+         * 
+         * Default: 0
+         * Group: scheduler
+         * 
+         * @param repeatCount the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder repeatCount(String repeatCount) {
+            doSetProperty("repeatCount", repeatCount);
+            return this;
+        }
+        /**
+         * The consumer logs a start/complete log line when it polls. This
+         * option allows you to configure the logging level for that.
+         * 
+         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
+         * 
+         * Default: TRACE
+         * Group: scheduler
+         * 
+         * @param runLoggingLevel the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder runLoggingLevel(org.apache.camel.LoggingLevel runLoggingLevel) {
+            doSetProperty("runLoggingLevel", runLoggingLevel);
+            return this;
+        }
+        /**
+         * The consumer logs a start/complete log line when it polls. This
+         * option allows you to configure the logging level for that.
+         * 
+         * The option will be converted to a
+         * <code>org.apache.camel.LoggingLevel</code> type.
+         * 
+         * Default: TRACE
+         * Group: scheduler
+         * 
+         * @param runLoggingLevel the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder runLoggingLevel(String runLoggingLevel) {
+            doSetProperty("runLoggingLevel", runLoggingLevel);
+            return this;
+        }
+        /**
+         * Allows for configuring a custom/shared thread pool to use for the
+         * consumer. By default each consumer has its own single threaded thread
+         * pool.
+         * 
+         * The option is a:
+         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
+         * 
+         * Group: scheduler
+         * 
+         * @param scheduledExecutorService the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder scheduledExecutorService(ScheduledExecutorService scheduledExecutorService) {
+            doSetProperty("scheduledExecutorService", scheduledExecutorService);
+            return this;
+        }
+        /**
+         * Allows for configuring a custom/shared thread pool to use for the
+         * consumer. By default each consumer has its own single threaded thread
+         * pool.
+         * 
+         * The option will be converted to a
+         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
+         * 
+         * Group: scheduler
+         * 
+         * @param scheduledExecutorService the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder scheduledExecutorService(String scheduledExecutorService) {
+            doSetProperty("scheduledExecutorService", scheduledExecutorService);
+            return this;
+        }
+        /**
+         * To use a cron scheduler from either camel-spring or camel-quartz
+         * component. Use value spring or quartz for built in scheduler.
+         * 
+         * The option is a: <code>java.lang.Object</code> type.
+         * 
+         * Default: none
+         * Group: scheduler
+         * 
+         * @param scheduler the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder scheduler(Object scheduler) {
+            doSetProperty("scheduler", scheduler);
+            return this;
+        }
+        /**
+         * To use a cron scheduler from either camel-spring or camel-quartz
+         * component. Use value spring or quartz for built in scheduler.
+         * 
+         * The option will be converted to a <code>java.lang.Object</code> type.
+         * 
+         * Default: none
+         * Group: scheduler
+         * 
+         * @param scheduler the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder scheduler(String scheduler) {
+            doSetProperty("scheduler", scheduler);
+            return this;
+        }
+        /**
+         * To configure additional properties when using a custom scheduler or
+         * any of the Quartz, Spring based scheduler.
+         * 
+         * The option is a: <code>java.util.Map&lt;java.lang.String,
+         * java.lang.Object&gt;</code> type.
+         * The option is multivalued, and you can use the
+         * schedulerProperties(String, Object) method to add a value (call the
+         * method multiple times to set more values).
+         * 
+         * Group: scheduler
+         * 
+         * @param key the option key
+         * @param value the option value
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder schedulerProperties(String key, Object value) {
+            doSetMultiValueProperty("schedulerProperties", "scheduler." + key, value);
+            return this;
+        }
+        /**
+         * To configure additional properties when using a custom scheduler or
+         * any of the Quartz, Spring based scheduler.
+         * 
+         * The option is a: <code>java.util.Map&lt;java.lang.String,
+         * java.lang.Object&gt;</code> type.
+         * The option is multivalued, and you can use the
+         * schedulerProperties(String, Object) method to add a value (call the
+         * method multiple times to set more values).
+         * 
+         * Group: scheduler
+         * 
+         * @param values the values
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder schedulerProperties(Map values) {
+            doSetMultiValueProperties("schedulerProperties", "scheduler.", values);
+            return this;
+        }
+        /**
+         * Whether the scheduler should be auto started.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: true
+         * Group: scheduler
+         * 
+         * @param startScheduler the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder startScheduler(boolean startScheduler) {
+            doSetProperty("startScheduler", startScheduler);
+            return this;
+        }
+        /**
+         * Whether the scheduler should be auto started.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: true
+         * Group: scheduler
+         * 
+         * @param startScheduler the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder startScheduler(String startScheduler) {
+            doSetProperty("startScheduler", startScheduler);
+            return this;
+        }
+        /**
+         * Time unit for initialDelay and delay options.
+         * 
+         * The option is a: <code>java.util.concurrent.TimeUnit</code> type.
+         * 
+         * Default: MILLISECONDS
+         * Group: scheduler
+         * 
+         * @param timeUnit the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder timeUnit(TimeUnit timeUnit) {
+            doSetProperty("timeUnit", timeUnit);
+            return this;
+        }
+        /**
+         * Time unit for initialDelay and delay options.
+         * 
+         * The option will be converted to a
+         * <code>java.util.concurrent.TimeUnit</code> type.
+         * 
+         * Default: MILLISECONDS
+         * Group: scheduler
+         * 
+         * @param timeUnit the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder timeUnit(String timeUnit) {
+            doSetProperty("timeUnit", timeUnit);
+            return this;
+        }
+        /**
+         * Controls if fixed delay or fixed rate is used. See
+         * ScheduledExecutorService in JDK for details.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: true
+         * Group: scheduler
+         * 
+         * @param useFixedDelay the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder useFixedDelay(boolean useFixedDelay) {
+            doSetProperty("useFixedDelay", useFixedDelay);
+            return this;
+        }
+        /**
+         * Controls if fixed delay or fixed rate is used. See
+         * ScheduledExecutorService in JDK for details.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: true
+         * Group: scheduler
+         * 
+         * @param useFixedDelay the value to set
+         * @return the dsl builder
+         */
+        default SmooksEndpointConsumerBuilder useFixedDelay(String useFixedDelay) {
+            doSetProperty("useFixedDelay", useFixedDelay);
+            return this;
+        }
+    }
+
+    /**
+     * Advanced builder for endpoint consumers for the Smooks component.
+     */
+    public interface AdvancedSmooksEndpointConsumerBuilder
+            extends
+                EndpointConsumerBuilder {
+        default SmooksEndpointConsumerBuilder basic() {
+            return (SmooksEndpointConsumerBuilder) this;
+        }
+        /**
+         * Allows for bridging the consumer to the Camel routing Error Handler,
+         * which mean any exceptions (if possible) occurred while the Camel
+         * consumer is trying to pickup incoming messages, or the likes, will
+         * now be processed as a message and handled by the routing Error
+         * Handler. Important: This is only possible if the 3rd party component
+         * allows Camel to be alerted if an exception was thrown. Some
+         * components handle this internally only, and therefore
+         * bridgeErrorHandler is not possible. In other situations we may
+         * improve the Camel component to hook into the 3rd party component and
+         * make this possible for future releases. By default the consumer will
+         * use the org.apache.camel.spi.ExceptionHandler to deal with
+         * exceptions, that will be logged at WARN or ERROR level and ignored.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: consumer (advanced)
+         * 
+         * @param bridgeErrorHandler the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointConsumerBuilder bridgeErrorHandler(boolean bridgeErrorHandler) {
+            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
+            return this;
+        }
+        /**
+         * Allows for bridging the consumer to the Camel routing Error Handler,
+         * which mean any exceptions (if possible) occurred while the Camel
+         * consumer is trying to pickup incoming messages, or the likes, will
+         * now be processed as a message and handled by the routing Error
+         * Handler. Important: This is only possible if the 3rd party component
+         * allows Camel to be alerted if an exception was thrown. Some
+         * components handle this internally only, and therefore
+         * bridgeErrorHandler is not possible. In other situations we may
+         * improve the Camel component to hook into the 3rd party component and
+         * make this possible for future releases. By default the consumer will
+         * use the org.apache.camel.spi.ExceptionHandler to deal with
+         * exceptions, that will be logged at WARN or ERROR level and ignored.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: consumer (advanced)
+         * 
+         * @param bridgeErrorHandler the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointConsumerBuilder bridgeErrorHandler(String bridgeErrorHandler) {
+            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
+            return this;
+        }
+        /**
+         * To let the consumer use a custom ExceptionHandler. Notice if the
+         * option bridgeErrorHandler is enabled then this option is not in use.
+         * By default the consumer will deal with exceptions, that will be
+         * logged at WARN or ERROR level and ignored.
+         * 
+         * The option is a: <code>org.apache.camel.spi.ExceptionHandler</code>
+         * type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param exceptionHandler the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointConsumerBuilder exceptionHandler(org.apache.camel.spi.ExceptionHandler exceptionHandler) {
+            doSetProperty("exceptionHandler", exceptionHandler);
+            return this;
+        }
+        /**
+         * To let the consumer use a custom ExceptionHandler. Notice if the
+         * option bridgeErrorHandler is enabled then this option is not in use.
+         * By default the consumer will deal with exceptions, that will be
+         * logged at WARN or ERROR level and ignored.
+         * 
+         * The option will be converted to a
+         * <code>org.apache.camel.spi.ExceptionHandler</code> type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param exceptionHandler the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointConsumerBuilder exceptionHandler(String exceptionHandler) {
+            doSetProperty("exceptionHandler", exceptionHandler);
+            return this;
+        }
+        /**
+         * Sets the exchange pattern when the consumer creates an exchange.
+         * 
+         * The option is a: <code>org.apache.camel.ExchangePattern</code> type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param exchangePattern the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointConsumerBuilder exchangePattern(org.apache.camel.ExchangePattern exchangePattern) {
+            doSetProperty("exchangePattern", exchangePattern);
+            return this;
+        }
+        /**
+         * Sets the exchange pattern when the consumer creates an exchange.
+         * 
+         * The option will be converted to a
+         * <code>org.apache.camel.ExchangePattern</code> type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param exchangePattern the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointConsumerBuilder exchangePattern(String exchangePattern) {
+            doSetProperty("exchangePattern", exchangePattern);
+            return this;
+        }
+        /**
+         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
+         * you to provide your custom implementation to control error handling
+         * usually occurred during the poll operation before an Exchange have
+         * been created and being routed in Camel.
+         * 
+         * The option is a:
+         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param pollStrategy the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointConsumerBuilder pollStrategy(org.apache.camel.spi.PollingConsumerPollStrategy pollStrategy) {
+            doSetProperty("pollStrategy", pollStrategy);
+            return this;
+        }
+        /**
+         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
+         * you to provide your custom implementation to control error handling
+         * usually occurred during the poll operation before an Exchange have
+         * been created and being routed in Camel.
+         * 
+         * The option will be converted to a
+         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
+         * 
+         * Group: consumer (advanced)
+         * 
+         * @param pollStrategy the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointConsumerBuilder pollStrategy(String pollStrategy) {
+            doSetProperty("pollStrategy", pollStrategy);
+            return this;
+        }
+    }
+
+    /**
+     * Builder for endpoint producers for the Smooks component.
+     */
+    public interface SmooksEndpointProducerBuilder
+            extends
+                EndpointProducerBuilder {
+        default AdvancedSmooksEndpointProducerBuilder advanced() {
+            return (AdvancedSmooksEndpointProducerBuilder) this;
+        }
+
+    }
+
+    /**
+     * Advanced builder for endpoint producers for the Smooks component.
+     */
+    public interface AdvancedSmooksEndpointProducerBuilder extends EndpointProducerBuilder {
+        default SmooksEndpointProducerBuilder basic() {
+            return (SmooksEndpointProducerBuilder) this;
+        }
+
+        /**
+         * Whether the producer should be started lazy (on the first message).
+         * By starting lazy you can use this to allow CamelContext and routes to
+         * startup in situations where a producer may otherwise fail during
+         * starting and cause the route to fail being started. By deferring this
+         * startup to be lazy then the startup failure can be handled during
+         * routing messages via Camel's routing error handlers. Beware that when
+         * the first message is processed then creating and starting the
+         * producer may take a little time and prolong the total processing time
+         * of the processing.
+         * 
+         * The option is a: <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: producer (advanced)
+         * 
+         * @param lazyStartProducer the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointProducerBuilder lazyStartProducer(boolean lazyStartProducer) {
+            doSetProperty("lazyStartProducer", lazyStartProducer);
+            return this;
+        }
+        /**
+         * Whether the producer should be started lazy (on the first message).
+         * By starting lazy you can use this to allow CamelContext and routes to
+         * startup in situations where a producer may otherwise fail during
+         * starting and cause the route to fail being started. By deferring this
+         * startup to be lazy then the startup failure can be handled during
+         * routing messages via Camel's routing error handlers. Beware that when
+         * the first message is processed then creating and starting the
+         * producer may take a little time and prolong the total processing time
+         * of the processing.
+         * 
+         * The option will be converted to a <code>boolean</code> type.
+         * 
+         * Default: false
+         * Group: producer (advanced)
+         * 
+         * @param lazyStartProducer the value to set
+         * @return the dsl builder
+         */
+        default AdvancedSmooksEndpointProducerBuilder lazyStartProducer(String lazyStartProducer) {
+            doSetProperty("lazyStartProducer", lazyStartProducer);
+            return this;
+        }
+    }
+
+    /**
+     * Builder for endpoint for the Smooks component.
+     */
+    public interface SmooksEndpointBuilder
+            extends
+                SmooksEndpointConsumerBuilder,
+                SmooksEndpointProducerBuilder {
+        default AdvancedSmooksEndpointBuilder advanced() {
+            return (AdvancedSmooksEndpointBuilder) this;
+        }
+
+    }
+
+    /**
+     * Advanced builder for endpoint for the Smooks component.
+     */
+    public interface AdvancedSmooksEndpointBuilder
+            extends
+                AdvancedSmooksEndpointConsumerBuilder,
+                AdvancedSmooksEndpointProducerBuilder {
+        default SmooksEndpointBuilder basic() {
+            return (SmooksEndpointBuilder) this;
+        }
+
+    }
+
+    public interface SmooksBuilders {
+        /**
+         * Smooks (camel-smooks)
+         * Applies fragment-based processing in Smooks to perform a variety of
+         * operations like transformation.
+         * 
+         * Category: file
+         * Since: 4.7
+         * Maven coordinates: org.apache.camel:camel-smooks
+         * 
+         * Syntax: <code>smooks://smooks-config-path</code>
+         * 
+         * Path parameter: database (required)
+         * database name
+         * 
+         * @param path smooks-config-path
+         * @return the dsl builder
+         */
+        default SmooksEndpointBuilder smooks(String path) {
+            return SmooksEndpointBuilderFactory.endpointBuilder("smooks", path);
+        }
+        /**
+         * Smooks (camel-smooks)
+         * Applies fragment-based processing in Smooks to perform a variety of
+         * operations like transformation.
+         * 
+         * Category: file
+         * Since: 4.7
+         * Maven coordinates: org.apache.camel:camel-smooks
+         * 
+         * Syntax: <code>smooks://smooks-config-path</code>
+         * 
+         * Path parameter: database (required)
+         * database name
+         * 
+         * @param componentName to use a custom component name for the endpoint
+         * instead of the default name
+         * @param path smooks-config-path
+         * @return the dsl builder
+         */
+        default SmooksEndpointBuilder smooks(String componentName, String path) {
+            return SmooksEndpointBuilderFactory.endpointBuilder(componentName, path);
+        }
+
+    }
+    static SmooksEndpointBuilder endpointBuilder(String componentName, String path) {
+        class SmooksEndpointBuilderImpl extends AbstractEndpointBuilder implements SmooksEndpointBuilder, AdvancedSmooksEndpointBuilder {
+            public SmooksEndpointBuilderImpl(String path) {
+                super(componentName, path);
+            }
+        }
+        return new SmooksEndpointBuilderImpl(path);
+    }
+}
\ No newline at end of file


(camel) 03/03: CAMEL-19985: Smooks component

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch cjmamo-CAMEL-19985
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 3df0f6a9c6b309b53c4ffacfc8c3e79f4d6a6c2e
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Jun 3 11:09:06 2024 +0200

    CAMEL-19985: Smooks component
---
 .../apache/camel/catalog/components/smooks.json    |   8 +-
 components/camel-smooks/pom.xml                    |  30 +-
 .../camel/component/smooks/SmooksProcessor.java    |  33 ---
 .../modules/ROOT/examples/json/smooks.json         |   1 +
 .../modules/ROOT/pages/smooks-component.adoc       |   1 +
 .../component/ComponentsBuilderFactory.java        |   5 +-
 .../dsl/SmooksComponentBuilderFactory.java         |   8 +-
 .../builder/endpoint/StaticEndpointBuilders.java   |  30 +-
 .../endpoint/dsl/SmooksEndpointBuilderFactory.java |  33 ++-
 .../apache/camel/kotlin/components/SmooksUriDsl.kt | 329 +++++++++++++++++++++
 parent/pom.xml                                     |   1 +
 11 files changed, 389 insertions(+), 90 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json
index cb677a24991..993bf295f63 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json
@@ -3,10 +3,10 @@
     "kind": "component",
     "name": "smooks",
     "title": "Smooks",
-    "description": "Applies fragment-based processing in Smooks to perform a variety of operations like transformation.",
+    "description": "EDI, XML, CSV, etc. based data transformation using Smooks.",
     "deprecated": false,
     "firstVersion": "4.7.0",
-    "label": "file",
+    "label": "transformation",
     "javaType": "org.apache.camel.component.smooks.SmooksComponent",
     "supportLevel": "Preview",
     "groupId": "org.apache.camel",
@@ -14,7 +14,7 @@
     "version": "4.7.0-SNAPSHOT",
     "scheme": "smooks",
     "extendsScheme": "",
-    "syntax": "smooks:\/\/smooks-config-path",
+    "syntax": "smooks:smooksConfig",
     "async": false,
     "api": false,
     "consumerOnly": false,
@@ -28,7 +28,7 @@
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
   },
   "properties": {
-    "database": { "index": 0, "kind": "path", "displayName": "Database", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "database name" },
+    "smooksConfig": { "index": 0, "kind": "path", "displayName": "Smooks Config", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "description": "Smooks XML configuration file" },
     "sendEmptyMessageWhenIdle": { "index": 1, "kind": "parameter", "displayName": "Send Empty Message When Idle", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the polling consumer did not poll any files, you can enable this option to send an empty message (no body) instead." },
     "bridgeErrorHandler": { "index": 2, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming  [...]
     "exceptionHandler": { "index": 3, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By def [...]
diff --git a/components/camel-smooks/pom.xml b/components/camel-smooks/pom.xml
index 4128c93c996..fe2c481934c 100644
--- a/components/camel-smooks/pom.xml
+++ b/components/camel-smooks/pom.xml
@@ -17,7 +17,8 @@
     limitations under the License.
 
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
     <modelVersion>4.0.0</modelVersion>
 
@@ -33,16 +34,12 @@
     <name>Camel :: Smooks :: Parent</name>
     <description>Camel Smooks Component</description>
 
-    <properties>
-        <smooks.version>2.0.0-RC4</smooks.version>
-    </properties>
-
     <dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>org.smooks</groupId>
                 <artifactId>smooks-bom</artifactId>
-                <version>${smooks.version}</version>
+                <version>${smooks-version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
@@ -50,22 +47,20 @@
     </dependencyManagement>
 
     <dependencies>
-        <dependency>
-            <groupId>org.smooks</groupId>
-            <artifactId>smooks-core</artifactId>
-        </dependency>
+
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-file</artifactId>
+            <artifactId>camel-support</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-attachments</artifactId>
+            <artifactId>camel-file</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-support</artifactId>
+            <groupId>org.smooks</groupId>
+            <artifactId>smooks-core</artifactId>
         </dependency>
+
         <dependency>
             <groupId>org.smooks.cartridges.edi</groupId>
             <artifactId>smooks-edi-cartridge</artifactId>
@@ -81,10 +76,15 @@
             <artifactId>camel-test-junit5</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-attachments</artifactId>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.xmlunit</groupId>
             <artifactId>xmlunit-core</artifactId>
-            <version>2.9.1</version>
+            <version>${xmlunit-version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
index a6abc57aa1c..259c7072ae3 100644
--- a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
@@ -39,8 +39,6 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Message;
 import org.apache.camel.Processor;
 import org.apache.camel.WrappedFile;
-import org.apache.camel.attachment.Attachment;
-import org.apache.camel.attachment.AttachmentMessage;
 import org.apache.camel.support.ResourceHelper;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.IOHelper;
@@ -74,7 +72,6 @@ public class SmooksProcessor extends ServiceSupport implements Processor, CamelC
     private final Set<VisitorAppender> visitorAppender = new HashSet<>();
     private final Map<String, Visitor> selectorVisitorMap = new HashMap<>();
     private CamelContext camelContext;
-    private boolean attachmentsSupported;
 
     public SmooksProcessor(final CamelContext camelContext) {
         this.camelContext = camelContext;
@@ -99,18 +96,6 @@ public class SmooksProcessor extends ServiceSupport implements Processor, CamelC
     }
 
     public void process(final Exchange exchange) {
-        //forward headers
-        exchange.getMessage().setHeaders(exchange.getIn().getHeaders());
-
-        if (attachmentsSupported) {
-            //forward attachments
-            if (exchange.getIn(AttachmentMessage.class).hasAttachments()) {
-                for (Entry<String, Attachment> attachmentObject : exchange.getIn(AttachmentMessage.class).getAttachmentObjects().entrySet()) {
-                    exchange.getMessage(AttachmentMessage.class).addAttachmentObject(attachmentObject.getKey(), attachmentObject.getValue());
-                }
-            }
-        }
-
         final ExecutionContext executionContext = smooks.createExecutionContext();
         try {
             executionContext.put(EXCHANGE_TYPED_KEY, exchange);
@@ -253,24 +238,6 @@ public class SmooksProcessor extends ServiceSupport implements Processor, CamelC
             addAppender(smooks, visitorAppender);
             addVisitor(smooks, selectorVisitorMap);
 
-            InputStream inputStream = null;
-            try {
-                inputStream = camelContext.getClassResolver().loadResourceAsStream("META-INF/services/org/apache/camel/other.properties");
-                if (inputStream != null) {
-                    final Properties properties = new Properties();
-                    properties.load(inputStream);
-                    if (properties.getProperty("name") != null && properties.getProperty("name").equals("attachments")) {
-                        attachmentsSupported = true;
-                    }
-                }
-            } finally {
-                if (!attachmentsSupported) {
-                    LOG.warn("Attachments module could not be found: attachments will not be propagated");
-                }
-                if (inputStream != null) {
-                    inputStream.close();
-                }
-            }
         } catch (Exception e) {
             throw new SmooksException(e.getMessage(), e);
         }
diff --git a/docs/components/modules/ROOT/examples/json/smooks.json b/docs/components/modules/ROOT/examples/json/smooks.json
new file mode 120000
index 00000000000..2b181dead66
--- /dev/null
+++ b/docs/components/modules/ROOT/examples/json/smooks.json
@@ -0,0 +1 @@
+../../../../../../components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
\ No newline at end of file
diff --git a/docs/components/modules/ROOT/pages/smooks-component.adoc b/docs/components/modules/ROOT/pages/smooks-component.adoc
new file mode 120000
index 00000000000..07c7d3d61bb
--- /dev/null
+++ b/docs/components/modules/ROOT/pages/smooks-component.adoc
@@ -0,0 +1 @@
+../../../../../components/camel-smooks/src/main/docs/smooks-component.adoc
\ No newline at end of file
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
index 5f699878c50..2800a975d0d 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
@@ -3857,10 +3857,9 @@ public interface ComponentsBuilderFactory {
     }
     /**
      * Smooks (camel-smooks)
-     * Applies fragment-based processing in Smooks to perform a variety of
-     * operations like transformation.
+     * EDI, XML, CSV, etc. based data transformation using Smooks.
      * 
-     * Category: file
+     * Category: transformation
      * Since: 4.7
      * Maven coordinates: org.apache.camel:camel-smooks
      * 
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmooksComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmooksComponentBuilderFactory.java
index 1e9b50ea171..46ef98ed132 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmooksComponentBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SmooksComponentBuilderFactory.java
@@ -24,8 +24,7 @@ import org.apache.camel.builder.component.ComponentBuilder;
 import org.apache.camel.component.smooks.SmooksComponent;
 
 /**
- * Applies fragment-based processing in Smooks to perform a variety of
- * operations like transformation.
+ * EDI, XML, CSV, etc. based data transformation using Smooks.
  * 
  * Generated by camel build tools - do NOT edit this file!
  */
@@ -34,10 +33,9 @@ public interface SmooksComponentBuilderFactory {
 
     /**
      * Smooks (camel-smooks)
-     * Applies fragment-based processing in Smooks to perform a variety of
-     * operations like transformation.
+     * EDI, XML, CSV, etc. based data transformation using Smooks.
      * 
-     * Category: file
+     * Category: transformation
      * Since: 4.7
      * Maven coordinates: org.apache.camel:camel-smooks
      * 
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
index dad93cb86c3..6df28f8a170 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
@@ -13037,19 +13037,20 @@ public class StaticEndpointBuilders {
     }
     /**
      * Smooks (camel-smooks)
-     * Applies fragment-based processing in Smooks to perform a variety of
-     * operations like transformation.
+     * EDI, XML, CSV, etc. based data transformation using Smooks.
      * 
-     * Category: file
+     * Category: transformation
      * Since: 4.7
      * Maven coordinates: org.apache.camel:camel-smooks
      * 
-     * Syntax: <code>smooks://smooks-config-path</code>
+     * Syntax: <code>smooks:smooksConfig</code>
      * 
-     * Path parameter: database (required)
-     * database name
+     * Path parameter: smooksConfig (required)
+     * Smooks XML configuration file
+     * This option can also be loaded from an existing file, by prefixing with
+     * file: or classpath: followed by the location of the file.
      * 
-     * @param path smooks-config-path
+     * @param path smooksConfig
      * @return the dsl builder
      */
     public static SmooksEndpointBuilderFactory.SmooksEndpointBuilder smooks(String path) {
@@ -13057,21 +13058,22 @@ public class StaticEndpointBuilders {
     }
     /**
      * Smooks (camel-smooks)
-     * Applies fragment-based processing in Smooks to perform a variety of
-     * operations like transformation.
+     * EDI, XML, CSV, etc. based data transformation using Smooks.
      * 
-     * Category: file
+     * Category: transformation
      * Since: 4.7
      * Maven coordinates: org.apache.camel:camel-smooks
      * 
-     * Syntax: <code>smooks://smooks-config-path</code>
+     * Syntax: <code>smooks:smooksConfig</code>
      * 
-     * Path parameter: database (required)
-     * database name
+     * Path parameter: smooksConfig (required)
+     * Smooks XML configuration file
+     * This option can also be loaded from an existing file, by prefixing with
+     * file: or classpath: followed by the location of the file.
      * 
      * @param componentName to use a custom component name for the endpoint
      * instead of the default name
-     * @param path smooks-config-path
+     * @param path smooksConfig
      * @return the dsl builder
      */
     public static SmooksEndpointBuilderFactory.SmooksEndpointBuilder smooks(String componentName, String path) {
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java
index f1fef38d77a..f4825a11130 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java
@@ -27,8 +27,7 @@ import org.apache.camel.builder.EndpointProducerBuilder;
 import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
 
 /**
- * Applies fragment-based processing in Smooks to perform a variety of
- * operations like transformation.
+ * EDI, XML, CSV, etc. based data transformation using Smooks.
  * 
  * Generated by camel build tools - do NOT edit this file!
  */
@@ -794,19 +793,20 @@ public interface SmooksEndpointBuilderFactory {
     public interface SmooksBuilders {
         /**
          * Smooks (camel-smooks)
-         * Applies fragment-based processing in Smooks to perform a variety of
-         * operations like transformation.
+         * EDI, XML, CSV, etc. based data transformation using Smooks.
          * 
-         * Category: file
+         * Category: transformation
          * Since: 4.7
          * Maven coordinates: org.apache.camel:camel-smooks
          * 
-         * Syntax: <code>smooks://smooks-config-path</code>
+         * Syntax: <code>smooks:smooksConfig</code>
          * 
-         * Path parameter: database (required)
-         * database name
+         * Path parameter: smooksConfig (required)
+         * Smooks XML configuration file
+         * This option can also be loaded from an existing file, by prefixing
+         * with file: or classpath: followed by the location of the file.
          * 
-         * @param path smooks-config-path
+         * @param path smooksConfig
          * @return the dsl builder
          */
         default SmooksEndpointBuilder smooks(String path) {
@@ -814,21 +814,22 @@ public interface SmooksEndpointBuilderFactory {
         }
         /**
          * Smooks (camel-smooks)
-         * Applies fragment-based processing in Smooks to perform a variety of
-         * operations like transformation.
+         * EDI, XML, CSV, etc. based data transformation using Smooks.
          * 
-         * Category: file
+         * Category: transformation
          * Since: 4.7
          * Maven coordinates: org.apache.camel:camel-smooks
          * 
-         * Syntax: <code>smooks://smooks-config-path</code>
+         * Syntax: <code>smooks:smooksConfig</code>
          * 
-         * Path parameter: database (required)
-         * database name
+         * Path parameter: smooksConfig (required)
+         * Smooks XML configuration file
+         * This option can also be loaded from an existing file, by prefixing
+         * with file: or classpath: followed by the location of the file.
          * 
          * @param componentName to use a custom component name for the endpoint
          * instead of the default name
-         * @param path smooks-config-path
+         * @param path smooksConfig
          * @return the dsl builder
          */
         default SmooksEndpointBuilder smooks(String componentName, String path) {
diff --git a/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/SmooksUriDsl.kt b/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/SmooksUriDsl.kt
new file mode 100644
index 00000000000..7e2f42edb6b
--- /dev/null
+++ b/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/SmooksUriDsl.kt
@@ -0,0 +1,329 @@
+/*
+ * 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.kotlin.components
+
+import kotlin.Boolean
+import kotlin.Int
+import kotlin.String
+import kotlin.Unit
+import org.apache.camel.kotlin.CamelDslMarker
+import org.apache.camel.kotlin.UriDsl
+
+/**
+ * EDI, XML, CSV, etc. based data transformation using Smooks.
+ */
+public fun UriDsl.smooks(i: SmooksUriDsl.() -> Unit) {
+  SmooksUriDsl(this).apply(i)
+}
+
+@CamelDslMarker
+public class SmooksUriDsl(
+  it: UriDsl,
+) {
+  private val it: UriDsl
+
+  init {
+    this.it = it
+    this.it.component("smooks")
+  }
+
+  private var smooksConfig: String = ""
+
+  /**
+   * Smooks XML configuration file
+   */
+  public fun smooksConfig(smooksConfig: String) {
+    this.smooksConfig = smooksConfig
+    it.url("$smooksConfig")
+  }
+
+  /**
+   * If the polling consumer did not poll any files, you can enable this option to send an empty
+   * message (no body) instead.
+   */
+  public fun sendEmptyMessageWhenIdle(sendEmptyMessageWhenIdle: String) {
+    it.property("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle)
+  }
+
+  /**
+   * If the polling consumer did not poll any files, you can enable this option to send an empty
+   * message (no body) instead.
+   */
+  public fun sendEmptyMessageWhenIdle(sendEmptyMessageWhenIdle: Boolean) {
+    it.property("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle.toString())
+  }
+
+  /**
+   * Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions
+   * (if possible) occurred while the Camel consumer is trying to pickup incoming messages, or the
+   * likes, will now be processed as a message and handled by the routing Error Handler. Important:
+   * This is only possible if the 3rd party component allows Camel to be alerted if an exception was
+   * thrown. Some components handle this internally only, and therefore bridgeErrorHandler is not
+   * possible. In other situations we may improve the Camel component to hook into the 3rd party
+   * component and make this possible for future releases. By default the consumer will use the
+   * org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or
+   * ERROR level and ignored.
+   */
+  public fun bridgeErrorHandler(bridgeErrorHandler: String) {
+    it.property("bridgeErrorHandler", bridgeErrorHandler)
+  }
+
+  /**
+   * Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions
+   * (if possible) occurred while the Camel consumer is trying to pickup incoming messages, or the
+   * likes, will now be processed as a message and handled by the routing Error Handler. Important:
+   * This is only possible if the 3rd party component allows Camel to be alerted if an exception was
+   * thrown. Some components handle this internally only, and therefore bridgeErrorHandler is not
+   * possible. In other situations we may improve the Camel component to hook into the 3rd party
+   * component and make this possible for future releases. By default the consumer will use the
+   * org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or
+   * ERROR level and ignored.
+   */
+  public fun bridgeErrorHandler(bridgeErrorHandler: Boolean) {
+    it.property("bridgeErrorHandler", bridgeErrorHandler.toString())
+  }
+
+  /**
+   * To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is
+   * enabled then this option is not in use. By default the consumer will deal with exceptions, that
+   * will be logged at WARN or ERROR level and ignored.
+   */
+  public fun exceptionHandler(exceptionHandler: String) {
+    it.property("exceptionHandler", exceptionHandler)
+  }
+
+  /**
+   * Sets the exchange pattern when the consumer creates an exchange.
+   */
+  public fun exchangePattern(exchangePattern: String) {
+    it.property("exchangePattern", exchangePattern)
+  }
+
+  /**
+   * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your custom
+   * implementation to control error handling usually occurred during the poll operation before an
+   * Exchange have been created and being routed in Camel.
+   */
+  public fun pollStrategy(pollStrategy: String) {
+    it.property("pollStrategy", pollStrategy)
+  }
+
+  /**
+   * Whether the producer should be started lazy (on the first message). By starting lazy you can
+   * use this to allow CamelContext and routes to startup in situations where a producer may otherwise
+   * fail during starting and cause the route to fail being started. By deferring this startup to be
+   * lazy then the startup failure can be handled during routing messages via Camel's routing error
+   * handlers. Beware that when the first message is processed then creating and starting the producer
+   * may take a little time and prolong the total processing time of the processing.
+   */
+  public fun lazyStartProducer(lazyStartProducer: String) {
+    it.property("lazyStartProducer", lazyStartProducer)
+  }
+
+  /**
+   * Whether the producer should be started lazy (on the first message). By starting lazy you can
+   * use this to allow CamelContext and routes to startup in situations where a producer may otherwise
+   * fail during starting and cause the route to fail being started. By deferring this startup to be
+   * lazy then the startup failure can be handled during routing messages via Camel's routing error
+   * handlers. Beware that when the first message is processed then creating and starting the producer
+   * may take a little time and prolong the total processing time of the processing.
+   */
+  public fun lazyStartProducer(lazyStartProducer: Boolean) {
+    it.property("lazyStartProducer", lazyStartProducer.toString())
+  }
+
+  /**
+   * The number of subsequent error polls (failed due some error) that should happen before the
+   * backoffMultipler should kick-in.
+   */
+  public fun backoffErrorThreshold(backoffErrorThreshold: String) {
+    it.property("backoffErrorThreshold", backoffErrorThreshold)
+  }
+
+  /**
+   * The number of subsequent error polls (failed due some error) that should happen before the
+   * backoffMultipler should kick-in.
+   */
+  public fun backoffErrorThreshold(backoffErrorThreshold: Int) {
+    it.property("backoffErrorThreshold", backoffErrorThreshold.toString())
+  }
+
+  /**
+   * The number of subsequent idle polls that should happen before the backoffMultipler should
+   * kick-in.
+   */
+  public fun backoffIdleThreshold(backoffIdleThreshold: String) {
+    it.property("backoffIdleThreshold", backoffIdleThreshold)
+  }
+
+  /**
+   * The number of subsequent idle polls that should happen before the backoffMultipler should
+   * kick-in.
+   */
+  public fun backoffIdleThreshold(backoffIdleThreshold: Int) {
+    it.property("backoffIdleThreshold", backoffIdleThreshold.toString())
+  }
+
+  /**
+   * To let the scheduled polling consumer backoff if there has been a number of subsequent
+   * idles/errors in a row. The multiplier is then the number of polls that will be skipped before the
+   * next actual attempt is happening again. When this option is in use then backoffIdleThreshold
+   * and/or backoffErrorThreshold must also be configured.
+   */
+  public fun backoffMultiplier(backoffMultiplier: String) {
+    it.property("backoffMultiplier", backoffMultiplier)
+  }
+
+  /**
+   * To let the scheduled polling consumer backoff if there has been a number of subsequent
+   * idles/errors in a row. The multiplier is then the number of polls that will be skipped before the
+   * next actual attempt is happening again. When this option is in use then backoffIdleThreshold
+   * and/or backoffErrorThreshold must also be configured.
+   */
+  public fun backoffMultiplier(backoffMultiplier: Int) {
+    it.property("backoffMultiplier", backoffMultiplier.toString())
+  }
+
+  /**
+   * Milliseconds before the next poll.
+   */
+  public fun delay(delay: String) {
+    it.property("delay", delay)
+  }
+
+  /**
+   * Milliseconds before the next poll.
+   */
+  public fun delay(delay: Int) {
+    it.property("delay", delay.toString())
+  }
+
+  /**
+   * If greedy is enabled, then the ScheduledPollConsumer will run immediately again, if the
+   * previous run polled 1 or more messages.
+   */
+  public fun greedy(greedy: String) {
+    it.property("greedy", greedy)
+  }
+
+  /**
+   * If greedy is enabled, then the ScheduledPollConsumer will run immediately again, if the
+   * previous run polled 1 or more messages.
+   */
+  public fun greedy(greedy: Boolean) {
+    it.property("greedy", greedy.toString())
+  }
+
+  /**
+   * Milliseconds before the first poll starts.
+   */
+  public fun initialDelay(initialDelay: String) {
+    it.property("initialDelay", initialDelay)
+  }
+
+  /**
+   * Milliseconds before the first poll starts.
+   */
+  public fun initialDelay(initialDelay: Int) {
+    it.property("initialDelay", initialDelay.toString())
+  }
+
+  /**
+   * Specifies a maximum limit of number of fires. So if you set it to 1, the scheduler will only
+   * fire once. If you set it to 5, it will only fire five times. A value of zero or negative means
+   * fire forever.
+   */
+  public fun repeatCount(repeatCount: String) {
+    it.property("repeatCount", repeatCount)
+  }
+
+  /**
+   * Specifies a maximum limit of number of fires. So if you set it to 1, the scheduler will only
+   * fire once. If you set it to 5, it will only fire five times. A value of zero or negative means
+   * fire forever.
+   */
+  public fun repeatCount(repeatCount: Int) {
+    it.property("repeatCount", repeatCount.toString())
+  }
+
+  /**
+   * The consumer logs a start/complete log line when it polls. This option allows you to configure
+   * the logging level for that.
+   */
+  public fun runLoggingLevel(runLoggingLevel: String) {
+    it.property("runLoggingLevel", runLoggingLevel)
+  }
+
+  /**
+   * Allows for configuring a custom/shared thread pool to use for the consumer. By default each
+   * consumer has its own single threaded thread pool.
+   */
+  public fun scheduledExecutorService(scheduledExecutorService: String) {
+    it.property("scheduledExecutorService", scheduledExecutorService)
+  }
+
+  /**
+   * To use a cron scheduler from either camel-spring or camel-quartz component. Use value spring or
+   * quartz for built in scheduler
+   */
+  public fun scheduler(scheduler: String) {
+    it.property("scheduler", scheduler)
+  }
+
+  /**
+   * To configure additional properties when using a custom scheduler or any of the Quartz, Spring
+   * based scheduler.
+   */
+  public fun schedulerProperties(schedulerProperties: String) {
+    it.property("schedulerProperties", schedulerProperties)
+  }
+
+  /**
+   * Whether the scheduler should be auto started.
+   */
+  public fun startScheduler(startScheduler: String) {
+    it.property("startScheduler", startScheduler)
+  }
+
+  /**
+   * Whether the scheduler should be auto started.
+   */
+  public fun startScheduler(startScheduler: Boolean) {
+    it.property("startScheduler", startScheduler.toString())
+  }
+
+  /**
+   * Time unit for initialDelay and delay options.
+   */
+  public fun timeUnit(timeUnit: String) {
+    it.property("timeUnit", timeUnit)
+  }
+
+  /**
+   * Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in JDK for details.
+   */
+  public fun useFixedDelay(useFixedDelay: String) {
+    it.property("useFixedDelay", useFixedDelay)
+  }
+
+  /**
+   * Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in JDK for details.
+   */
+  public fun useFixedDelay(useFixedDelay: Boolean) {
+    it.property("useFixedDelay", useFixedDelay.toString())
+  }
+}
diff --git a/parent/pom.xml b/parent/pom.xml
index 00df68bb3d5..87c8ccd0dc3 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -439,6 +439,7 @@
         <smallrye-health-version>4.1.0</smallrye-health-version>
         <smallrye-fault-tolerance-version>6.3.0</smallrye-fault-tolerance-version>
         <smbj-version>0.13.0</smbj-version>
+        <smooks-version>2.0.0-RC4</smooks-version>
         <snakeyaml-version>2.2</snakeyaml-version>
         <snakeyaml-engine-version>2.7</snakeyaml-engine-version>
         <snmp4j-version>3.8.2</snmp4j-version>