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

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

commit 1ee83e533cfca1adcaaf2ba2b8e2effe0e5833f7
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Thu Mar 14 18:48:09 2024 +0100

    CAMEL-17641: Generate json metadata for pojo beans in camel-core that end 
users can use such as AggregationStrategy implementations. And have that 
information in camel-catalog for tooling assistance.
---
 .../org/apache/camel/catalog/beans.properties      | 10 ++++
 .../catalog/beans/DefaultHeaderFilterStrategy.json | 16 +++++
 .../catalog/beans/FileIdempotentRepository.json    | 16 +++++
 .../beans/GroupedBodyAggregationStrategy.json      | 15 +++++
 .../beans/GroupedExchangeAggregationStrategy.json  | 15 +++++
 .../beans/GroupedMessageAggregationStrategy.json   | 15 +++++
 .../catalog/beans/MemoryAggregationRepository.json | 16 +++++
 .../catalog/beans}/MemoryIdempotentRepository.json |  2 +-
 .../catalog/beans/StringAggregationStrategy.json   | 16 +++++
 .../beans/UseLatestAggregationStrategy.json        | 15 +++++
 .../beans/UseOriginalAggregationStrategy.json      | 15 +++++
 .../catalog/components/langchain-embeddings.json   |  4 +-
 .../camel/bean/DefaultHeaderFilterStrategy.json    |  2 +-
 .../camel/bean/FileIdempotentRepository.json       |  2 +-
 .../camel/bean/MemoryIdempotentRepository.json     |  2 +-
 .../org/apache/camel/tooling/model/JsonMapper.java | 38 ++++++++++++
 .../apache/camel/tooling/model/PojoBeanModel.java  | 46 +++++++++++++++
 .../maven/packaging/GeneratePojoBeanMojo.java      |  2 +-
 .../camel/maven/packaging/PrepareCatalogMojo.java  | 69 +++++++++++++++++++++-
 19 files changed, 308 insertions(+), 8 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans.properties
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans.properties
new file mode 100644
index 00000000000..682e217224d
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans.properties
@@ -0,0 +1,10 @@
+DefaultHeaderFilterStrategy
+FileIdempotentRepository
+GroupedBodyAggregationStrategy
+GroupedExchangeAggregationStrategy
+GroupedMessageAggregationStrategy
+MemoryAggregationRepository
+MemoryIdempotentRepository
+StringAggregationStrategy
+UseLatestAggregationStrategy
+UseOriginalAggregationStrategy
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/DefaultHeaderFilterStrategy.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/DefaultHeaderFilterStrategy.json
new file mode 100644
index 00000000000..bfe3e06376a
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/DefaultHeaderFilterStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "DefaultHeaderFilterStrategy",
+    "javaType": "org.apache.camel.support.DefaultHeaderFilterStrategy",
+    "interfaceType": "org.apache.camel.spi.HeaderFilterStrategy",
+    "title": "Default Header Filter Strategy",
+    "description": "The default header filtering strategy. Users can configure 
which headers is allowed or denied.",
+    "deprecated": true,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-support",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "allowNullValues": { "index": 0, "kind": "property", 
"displayName": "Allow Null Values", "label": "advanced", "required": false, 
"type": "object", "javaType": 
"org.apache.camel.support.DefaultHeaderFilterStrategy", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "false", "description": 
"Whether to allow null values. By default a header is skipped if its value is 
null. Setting this to true will preserve the header." }, "caseInsensitive": { 
"in [...]
+  }
+}
+
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/FileIdempotentRepository.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/FileIdempotentRepository.json
new file mode 100644
index 00000000000..ca6dbee7ea3
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/FileIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "FileIdempotentRepository",
+    "javaType": 
"org.apache.camel.support.processor.idempotent.FileIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "File Idempotent Repository",
+    "description": "A file based IdempotentRepository.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-support",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "dropOldestFileStore": { "index": 0, "kind": "property", 
"displayName": "Drop Oldest File Store", "required": false, "type": "object", 
"javaType": 
"org.apache.camel.support.processor.idempotent.FileIdempotentRepository", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1000", "description": "Sets the number of oldest entries to drop from the file 
store when the maximum capacity is hit to reduce disk space to allow room for 
new entries." }, "f [...]
+  }
+}
+
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedBodyAggregationStrategy.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedBodyAggregationStrategy.json
new file mode 100644
index 00000000000..10edccd31e1
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedBodyAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "GroupedBodyAggregationStrategy",
+    "javaType": 
"org.apache.camel.processor.aggregate.GroupedBodyAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Grouped Body Aggregation Strategy",
+    "description": "Aggregate body of input Message into a single combined 
Exchange holding all the aggregated bodies in a List of type Object as the 
message body. This aggregation strategy can be used in combination with 
Splitter to batch messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedExchangeAggregationStrategy.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedExchangeAggregationStrategy.json
new file mode 100644
index 00000000000..7ba11aca0c4
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedExchangeAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "GroupedExchangeAggregationStrategy",
+    "javaType": 
"org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Grouped Exchange Aggregation Strategy",
+    "description": "Aggregate all Exchanges into a single combined Exchange 
holding all the aggregated exchanges in a List of Exchange as the message body. 
This aggregation strategy can be used in combination with Splitter to batch 
messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedMessageAggregationStrategy.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedMessageAggregationStrategy.json
new file mode 100644
index 00000000000..a03cad939d9
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedMessageAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "GroupedMessageAggregationStrategy",
+    "javaType": 
"org.apache.camel.processor.aggregate.GroupedMessageAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Grouped Message Aggregation Strategy",
+    "description": "Aggregate all Message into a single combined Exchange 
holding all the aggregated messages in a List of Message as the message body. 
This aggregation strategy can be used in combination with Splitter to batch 
messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryAggregationRepository.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryAggregationRepository.json
new file mode 100644
index 00000000000..4e2092ec9fc
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "MemoryAggregationRepository",
+    "javaType": 
"org.apache.camel.processor.aggregate.MemoryAggregationRepository",
+    "interfaceType": 
"org.apache.camel.spi.OptimisticLockingAggregationRepository",
+    "title": "Memory Aggregation Repository",
+    "description": "A memory based AggregationRepository which stores Exchange 
in memory only.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT",
+    "options": { "optimisticLocking": { "index": 0, "kind": "property", 
"displayName": "Optimistic Locking", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "description": "Whether to use optimistic locking" } }
+  }
+}
+
diff --git 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryIdempotentRepository.json
similarity index 56%
copy from 
core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
copy to 
catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryIdempotentRepository.json
index 4c152136b51..a70bbdcdf2e 100644
--- 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryIdempotentRepository.json
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "cacheSize": { "index": 0, "kind": "property", "displayName": 
"Cache Size", "required": false, "type": "object", "javaType": 
"org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1000", "description": "Maximum elements that can be stored in-memory" } }
+    "properties": { "cacheSize": { "index": 0, "kind": "property", 
"displayName": "Cache Size", "required": false, "type": "object", "javaType": 
"org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1000", "description": "Maximum elements that can be stored in-memory" } }
   }
 }
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/StringAggregationStrategy.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/StringAggregationStrategy.json
new file mode 100644
index 00000000000..1702da816d7
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/StringAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "StringAggregationStrategy",
+    "javaType": 
"org.apache.camel.processor.aggregate.StringAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "String Aggregation Strategy",
+    "description": "Aggregate result of pick expression into a single combined 
Exchange holding all the aggregated bodies in a String as the message body. 
This aggregation strategy can used in combination with Splitter to batch 
messages",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT",
+    "options": { "delimiter": { "index": 0, "kind": "property", "displayName": 
"Delimiter", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Delimiter used for joining strings together." } }
+  }
+}
+
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseLatestAggregationStrategy.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseLatestAggregationStrategy.json
new file mode 100644
index 00000000000..5d73c66d791
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseLatestAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "UseLatestAggregationStrategy",
+    "javaType": 
"org.apache.camel.processor.aggregate.UseLatestAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Use Latest Aggregation Strategy",
+    "description": "An AggregationStrategy which just uses the latest exchange 
which is useful for status messages where old status messages have no real 
value. Another example is things like market data prices, where old stock 
prices are not that relevant, only the current price is.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseOriginalAggregationStrategy.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseOriginalAggregationStrategy.json
new file mode 100644
index 00000000000..7ab066f5d79
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseOriginalAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "UseOriginalAggregationStrategy",
+    "javaType": 
"org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Use Original Aggregation Strategy",
+    "description": "An AggregationStrategy which just uses the original 
exchange which can be needed when you want to preserve the original Exchange. 
For example when splitting an Exchange and then you may want to keep routing 
using the original Exchange.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain-embeddings.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain-embeddings.json
index a064e3985a3..00a08f7f076 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain-embeddings.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain-embeddings.json
@@ -3,7 +3,7 @@
     "kind": "component",
     "name": "langchain-embeddings",
     "title": "Langchain4j Embeddings",
-    "description": "Langchain4j Embeddings",
+    "description": "Perform operations on the Qdrant Vector Database.",
     "deprecated": false,
     "firstVersion": "4.5.0",
     "label": "ai",
@@ -11,7 +11,7 @@
     "supportLevel": "Preview",
     "groupId": "org.apache.camel",
     "artifactId": "camel-langchain-embeddings",
-    "version": "4.5.0-SNAPSHOT",
+    "version": "4.4.0-SNAPSHOT",
     "scheme": "langchain-embeddings",
     "extendsScheme": "",
     "syntax": "langchain-embeddings:embeddingId",
diff --git 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/DefaultHeaderFilterStrategy.json
 
b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/DefaultHeaderFilterStrategy.json
index 8d359b034cd..bfe3e06376a 100644
--- 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/DefaultHeaderFilterStrategy.json
+++ 
b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/DefaultHeaderFilterStrategy.json
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "allowNullValues": { "index": 0, "kind": "property", 
"displayName": "Allow Null Values", "label": "advanced", "required": false, 
"type": "object", "javaType": 
"org.apache.camel.support.DefaultHeaderFilterStrategy", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "false", "description": 
"Whether to allow null values. By default a header is skipped if its value is 
null. Setting this to true will preserve the header." }, "caseInsensitive": { 
"index [...]
+    "properties": { "allowNullValues": { "index": 0, "kind": "property", 
"displayName": "Allow Null Values", "label": "advanced", "required": false, 
"type": "object", "javaType": 
"org.apache.camel.support.DefaultHeaderFilterStrategy", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "false", "description": 
"Whether to allow null values. By default a header is skipped if its value is 
null. Setting this to true will preserve the header." }, "caseInsensitive": { 
"in [...]
   }
 }
 
diff --git 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/FileIdempotentRepository.json
 
b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/FileIdempotentRepository.json
index e40fb4b2bee..ca6dbee7ea3 100644
--- 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/FileIdempotentRepository.json
+++ 
b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/FileIdempotentRepository.json
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "dropOldestFileStore": { "index": 0, "kind": "property", 
"displayName": "Drop Oldest File Store", "required": false, "type": "object", 
"javaType": 
"org.apache.camel.support.processor.idempotent.FileIdempotentRepository", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1000", "description": "Sets the number of oldest entries to drop from the file 
store when the maximum capacity is hit to reduce disk space to allow room for 
new entries." }, "file [...]
+    "properties": { "dropOldestFileStore": { "index": 0, "kind": "property", 
"displayName": "Drop Oldest File Store", "required": false, "type": "object", 
"javaType": 
"org.apache.camel.support.processor.idempotent.FileIdempotentRepository", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1000", "description": "Sets the number of oldest entries to drop from the file 
store when the maximum capacity is hit to reduce disk space to allow room for 
new entries." }, "f [...]
   }
 }
 
diff --git 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
 
b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
index 4c152136b51..a70bbdcdf2e 100644
--- 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
+++ 
b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "cacheSize": { "index": 0, "kind": "property", "displayName": 
"Cache Size", "required": false, "type": "object", "javaType": 
"org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1000", "description": "Maximum elements that can be stored in-memory" } }
+    "properties": { "cacheSize": { "index": 0, "kind": "property", 
"displayName": "Cache Size", "required": false, "type": "object", "javaType": 
"org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1000", "description": "Maximum elements that can be stored in-memory" } }
   }
 }
 
diff --git 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
index 2cda577d491..8b5302d5011 100644
--- 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
+++ 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
@@ -71,6 +71,8 @@ public final class JsonMapper {
             return generateOtherModel(obj);
         } else if (obj.containsKey("model")) {
             return generateEipModel(obj);
+        } else if (obj.containsKey("bean")) {
+            return generatePojoBeanModel(obj);
         } else {
             return null;
         }
@@ -315,6 +317,27 @@ public final class JsonMapper {
         return model;
     }
 
+    public static PojoBeanModel generatePojoBeanModel(String json) {
+        JsonObject obj = deserialize(json);
+        return generatePojoBeanModel(obj);
+    }
+
+    public static PojoBeanModel generatePojoBeanModel(JsonObject obj) {
+        JsonObject mobj = (JsonObject) obj.get("bean");
+        PojoBeanModel model = new PojoBeanModel();
+        parseModel(mobj, model);
+        JsonObject mprp = (JsonObject) obj.get("properties");
+        if (mprp != null) {
+            for (Map.Entry<String, Object> entry : mprp.entrySet()) {
+                JsonObject mp = (JsonObject) entry.getValue();
+                PojoBeanModel.PojoBeanOptionModel option = new 
PojoBeanModel.PojoBeanOptionModel();
+                parseOption(mp, option, entry.getKey());
+                model.addOption(option);
+            }
+        }
+        return model;
+    }
+
     public static String createParameterJsonSchema(EipModel model) {
         JsonObject wrapper = asJsonObject(model);
         return serialize(wrapper);
@@ -336,6 +359,21 @@ public final class JsonMapper {
         return wrapper;
     }
 
+    public static String createParameterJsonSchema(PojoBeanModel model) {
+        JsonObject wrapper = asJsonObject(model);
+        return serialize(wrapper);
+    }
+
+    public static JsonObject asJsonObject(PojoBeanModel model) {
+        JsonObject obj = new JsonObject();
+        baseToJson(model, obj);
+        obj.entrySet().removeIf(e -> e.getValue() == null);
+        JsonObject wrapper = new JsonObject();
+        wrapper.put("model", obj);
+        wrapper.put("properties", asJsonObject(model.getOptions()));
+        return wrapper;
+    }
+
     public static LanguageModel generateLanguageModel(String json) {
         JsonObject obj = deserialize(json);
         return generateLanguageModel(obj);
diff --git 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/PojoBeanModel.java
 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/PojoBeanModel.java
new file mode 100644
index 00000000000..fccb953d2f8
--- /dev/null
+++ 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/PojoBeanModel.java
@@ -0,0 +1,46 @@
+/*
+ * 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.tooling.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PojoBeanModel extends 
BaseModel<PojoBeanModel.PojoBeanOptionModel> {
+
+    protected final List<PojoBeanModel.PojoBeanOptionModel> options = new 
ArrayList<>();
+
+    public PojoBeanModel() {
+    }
+
+    public void addOption(PojoBeanModel.PojoBeanOptionModel option) {
+        options.add(option);
+    }
+
+    @Override
+    public List<PojoBeanOptionModel> getOptions() {
+        return options;
+    }
+
+    @Override
+    public String getKind() {
+        return "bean";
+    }
+
+    public static class PojoBeanOptionModel extends BaseOptionModel {
+
+    }
+}
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GeneratePojoBeanMojo.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GeneratePojoBeanMojo.java
index f9d3e0f6400..a19a72ac9df 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GeneratePojoBeanMojo.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GeneratePojoBeanMojo.java
@@ -276,7 +276,7 @@ public class GeneratePojoBeanMojo extends 
AbstractGeneratorMojo {
 
         if (!model.getOptions().isEmpty()) {
             JsonObject options = JsonMapper.asJsonObject(model.getOptions());
-            jo.put("options", options);
+            jo.put("properties", options);
         }
 
         JsonObject root = new JsonObject();
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
index 6809cafa0c9..3a1561a74d0 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
@@ -49,6 +49,7 @@ import org.apache.camel.tooling.model.EipModel;
 import org.apache.camel.tooling.model.JsonMapper;
 import org.apache.camel.tooling.model.LanguageModel;
 import org.apache.camel.tooling.model.OtherModel;
+import org.apache.camel.tooling.model.PojoBeanModel;
 import org.apache.camel.tooling.model.TransformerModel;
 import org.apache.camel.tooling.util.FileUtil;
 import org.apache.camel.tooling.util.PackageHelper;
@@ -119,6 +120,12 @@ public class PrepareCatalogMojo extends AbstractMojo {
     @Parameter(defaultValue = 
"${project.basedir}/src/generated/resources/org/apache/camel/catalog/transformers")
     protected File transformersOutDir;
 
+    /**
+     * The output directory for pojo beans catalog
+     */
+    @Parameter(defaultValue = 
"${project.basedir}/src/generated/resources/org/apache/camel/catalog/beans")
+    protected File beansOutDir;
+
     /**
      * The output directory for dev-consoles catalog
      */
@@ -329,7 +336,7 @@ public class PrepareCatalogMojo extends AbstractMojo {
                                 allJsonFiles.add(p);
                             } else if (f.equals("component.properties") || 
f.equals("dataformat.properties")
                                     || f.equals("language.properties") || 
f.equals("other.properties")
-                                    || f.equals("transformer.properties")) {
+                                    || f.equals("transformer.properties") || 
f.equals("bean.properties")) {
                                 allPropertiesFiles.add(p);
                             }
                         });
@@ -381,6 +388,7 @@ public class PrepareCatalogMojo extends AbstractMojo {
             Set<String> dataformats = executeDataFormats();
             Set<String> languages = executeLanguages();
             Set<String> transformers = executeTransformers();
+            Set<String> beans = executeBeans();
             Set<String> consoles = executeDevConsoles();
             Set<String> others = executeOthers();
             executeDocuments(components, dataformats, languages, others);
@@ -771,6 +779,48 @@ public class PrepareCatalogMojo extends AbstractMojo {
         return transformerNames;
     }
 
+    protected Set<String> executeBeans() throws Exception {
+        Path beansOutDir = this.beansOutDir.toPath();
+
+        getLog().info("Copying all Camel pojo bean json descriptors");
+
+        // lets use sorted set/maps
+        Set<Path> jsonFiles;
+        Set<Path> duplicateJsonFiles;
+        Set<Path> beanFiles;
+
+        // find all beans from the components directory
+        beanFiles = allPropertiesFiles.stream().filter(p -> 
p.endsWith("bean.properties"))
+                .collect(Collectors.toCollection(TreeSet::new));
+        jsonFiles = allJsonFiles.stream().filter(p -> allModels.get(p) 
instanceof PojoBeanModel)
+                .collect(Collectors.toCollection(TreeSet::new));
+
+        getLog().info("Found " + beanFiles.size() + " bean.properties files");
+        getLog().info("Found " + jsonFiles.size() + " bean json files");
+
+        // make sure to create out dir
+        Files.createDirectories(beansOutDir);
+
+        // Check duplicates
+        duplicateJsonFiles = getDuplicates(jsonFiles);
+
+        // Copy all descriptors
+        Map<Path, Path> newJsons = map(jsonFiles, p -> p, p -> 
beansOutDir.resolve(p.getFileName()));
+        try (Stream<Path> stream = list(beansOutDir).filter(p -> 
!newJsons.containsValue(p))) {
+            stream.forEach(this::delete);
+        }
+        newJsons.forEach(this::copy);
+
+        Path all = beansOutDir.resolve("../beans.properties");
+        Set<String> beanNames
+                = 
jsonFiles.stream().map(PrepareCatalogMojo::asComponentName).collect(Collectors.toCollection(TreeSet::new));
+        FileUtil.updateFile(all, String.join("\n", beanNames) + "\n");
+
+        printBeansReport(jsonFiles, duplicateJsonFiles);
+
+        return beanNames;
+    }
+
     protected Set<String> executeDevConsoles() throws Exception {
         Path consolesOutDir = this.consolesOutDir.toPath();
 
@@ -1273,6 +1323,23 @@ public class PrepareCatalogMojo extends AbstractMojo {
         getLog().info(SEPARATOR);
     }
 
+    private void printBeansReport(
+            Set<Path> json, Set<Path> duplicate) {
+        getLog().info(SEPARATOR);
+        getLog().info("");
+        getLog().info("Camel pojo beans catalog report");
+        getLog().info("");
+        getLog().info("\tPojo beans found: " + json.size());
+        printComponentDebug(json);
+        if (!duplicate.isEmpty()) {
+            getLog().info("");
+            getLog().warn("\tDuplicate pojo beans detected: " + 
duplicate.size());
+            printComponentWarning(duplicate);
+        }
+        getLog().info("");
+        getLog().info(SEPARATOR);
+    }
+
     private void printConsolesReport(
             Set<Path> json, Set<Path> duplicate) {
         getLog().info(SEPARATOR);

Reply via email to