This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch beans in repository https://gitbox.apache.org/repos/asf/camel.git
commit 338a5fe45107add83e711d021eb09d08c8149bea Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Mon Jul 1 10:56:33 2024 +0200 CAMEL-20930: camel-core - Bean DSL dev console --- .../apache/camel/impl/console/BeanDevConsole.java | 49 ++++++- .../camel/impl/console/VariablesDevConsole.java | 4 +- .../org/apache/camel/dev-console/bean-model.json | 15 ++ .../org/apache/camel/dev-console/bean-model | 2 + .../org/apache/camel/dev-consoles.properties | 7 + .../apache/camel/model/BeanModelDevConsole.java | 161 +++++++++++++++++++++ .../java/org/apache/camel/util/ObjectHelper.java | 2 +- .../camel/cli/connector/LocalCliConnector.java | 20 +++ .../jbang/core/commands/process/ListVariable.java | 6 +- 9 files changed, 258 insertions(+), 8 deletions(-) diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/BeanDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/BeanDevConsole.java index ad74cb0c332..f5827b4d39a 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/BeanDevConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/BeanDevConsole.java @@ -16,12 +16,17 @@ */ package org.apache.camel.impl.console; +import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; +import org.apache.camel.spi.BeanIntrospection; import org.apache.camel.spi.annotations.DevConsole; +import org.apache.camel.support.PluginHelper; import org.apache.camel.support.console.AbstractDevConsole; +import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; +import org.apache.camel.util.json.Jsoner; @DevConsole(name = "bean", description = "Displays Java beans from the registry") public class BeanDevConsole extends AbstractDevConsole { @@ -50,11 +55,51 @@ public class BeanDevConsole extends AbstractDevConsole { JsonObject jo = new JsonObject(); root.put("beans", jo); + + BeanIntrospection bi = PluginHelper.getBeanIntrospection(getCamelContext()); Map<String, Object> beans = getCamelContext().getRegistry().findByTypeWithName(Object.class); Stream<String> keys = beans.keySet().stream().sorted(String::compareToIgnoreCase); + keys.forEach(k -> { - String v = beans.getOrDefault(k, "null").getClass().getName(); - beans.put(k, v); + Object b = beans.get(k); + if (b != null) { + Map<String, Object> values = new HashMap<>(); + try { + bi.getProperties(b, values, null); + } catch (Exception e) { + // ignore + } + JsonObject jb = new JsonObject(); + jb.put("name", k); + jb.put("type", b.getClass().getName()); + jo.put(k, jb); + + if (!values.isEmpty()) { + JsonArray arr = new JsonArray(); + values.forEach((pk, pv) -> { + Object value = pv; + String type = pv != null ? pv.getClass().getName() : null; + if (type != null) { + value = Jsoner.trySerialize(pv); + if (value == null) { + // cannot serialize so escape + value = Jsoner.escape(pv.toString()); + } else { + // okay so use the value as-s + value = pv; + } + } + JsonObject jp = new JsonObject(); + jp.put("name", pk); + if (type != null) { + jp.put("type", type); + } + jp.put("value", value); + arr.add(jp); + }); + jb.put("properties", arr); + } + } }); return root; diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/VariablesDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/VariablesDevConsole.java index 95260395237..bb36068f931 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/VariablesDevConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/VariablesDevConsole.java @@ -76,10 +76,10 @@ public class VariablesDevConsole extends AbstractDevConsole { String t = v != null ? v.getClass().getName() : null; JsonObject e = new JsonObject(); e.put("key", k); - e.put("value", v); if (t != null) { - e.put("className", t); + e.put("type", t); } + e.put("value", v); arr.add(e); } return arr; diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/dev-console/bean-model.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/dev-console/bean-model.json new file mode 100644 index 00000000000..c49ff95fc82 --- /dev/null +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/dev-console/bean-model.json @@ -0,0 +1,15 @@ +{ + "console": { + "kind": "console", + "group": "camel", + "name": "bean-model", + "title": "Bean Model", + "description": "Displays beans from the DSL model", + "deprecated": false, + "javaType": "org.apache.camel.model.BeanModelDevConsole", + "groupId": "org.apache.camel", + "artifactId": "camel-core-model", + "version": "4.7.0-SNAPSHOT" + } +} + diff --git a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/dev-console/bean-model b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/dev-console/bean-model new file mode 100644 index 00000000000..799dbd34f96 --- /dev/null +++ b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/dev-console/bean-model @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.model.BeanModelDevConsole diff --git a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties new file mode 100644 index 00000000000..a3834de6926 --- /dev/null +++ b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/dev-consoles.properties @@ -0,0 +1,7 @@ +# Generated by camel build tools - do NOT edit this file! +dev-consoles=bean-model +groupId=org.apache.camel +artifactId=camel-core-model +version=4.7.0-SNAPSHOT +projectName=Camel :: Core Model +projectDescription=Camel model diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/BeanModelDevConsole.java b/core/camel-core-model/src/main/java/org/apache/camel/model/BeanModelDevConsole.java new file mode 100644 index 00000000000..a74d2319213 --- /dev/null +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/BeanModelDevConsole.java @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.model; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.spi.BeanIntrospection; +import org.apache.camel.spi.annotations.DevConsole; +import org.apache.camel.support.PluginHelper; +import org.apache.camel.support.console.AbstractDevConsole; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; +import org.apache.camel.util.json.Jsoner; + +@DevConsole(name = "bean-model", description = "Displays beans from the DSL model") +public class BeanModelDevConsole extends AbstractDevConsole { + + public BeanModelDevConsole() { + super("camel", "bean-model", "Bean Model", "Displays beans from the DSL model"); + } + + @Override + protected String doCallText(Map<String, Object> options) { + StringBuilder sb = new StringBuilder(); + + BeanIntrospection bi = PluginHelper.getBeanIntrospection(getCamelContext()); + Model model = getCamelContext().getCamelContextExtension().getContextPlugin(Model.class); + if (model != null) { + for (BeanFactoryDefinition<?> b : model.getCustomBeans()) { + Map<String, Object> values = new HashMap<>(); + Object target = getCamelContext().getRegistry().lookupByName(b.getName()); + if (target != null) { + try { + bi.getProperties(target, values, null); + } catch (Exception e) { + // ignore + } + } + sb.append(String.format(" %s (%s)%n", b.getName(), b.getType())); + if (b.getProperties() != null) { + b.getProperties().forEach((k, v) -> { + Object rv = values.get(k); + String type; + if (rv == null) { + rv = "null"; + type = "null"; + } else { + type = rv.getClass().getName(); + } + sb.append(String.format(" %s = %s (type:%s)%n", k, rv, type)); + }); + } + sb.append("\n"); + } + } + + return sb.toString(); + } + + @Override + protected JsonObject doCallJson(Map<String, Object> options) { + JsonObject root = new JsonObject(); + + JsonObject jo = new JsonObject(); + root.put("beans", jo); + + BeanIntrospection bi = PluginHelper.getBeanIntrospection(getCamelContext()); + Model model = getCamelContext().getCamelContextExtension().getContextPlugin(Model.class); + if (model != null) { + for (BeanFactoryDefinition<?> b : model.getCustomBeans()) { + Map<String, Object> values = new HashMap<>(); + Object target = getCamelContext().getRegistry().lookupByName(b.getName()); + if (target != null) { + try { + bi.getProperties(target, values, null); + } catch (Exception e) { + // ignore + } + } + JsonObject jb = new JsonObject(); + jo.put(b.getName(), jb); + jb.put("name", b.getName()); + jb.put("type", b.getType()); + if (b.getInitMethod() != null) { + jb.put("initMethod", b.getInitMethod()); + } + if (b.getDestroyMethod() != null) { + jb.put("destroyMethod", b.getDestroyMethod()); + } + if (b.getBuilderClass() != null) { + jb.put("builderClass", b.getBuilderClass()); + } + if (b.getBuilderMethod() != null) { + jb.put("builderMethod", b.getBuilderMethod()); + } + if (b.getFactoryBean() != null) { + jb.put("factoryBean", b.getFactoryBean()); + } + if (b.getFactoryMethod() != null) { + jb.put("factoryMethod", b.getFactoryMethod()); + } + if (b.getProperties() != null) { + JsonArray arr = new JsonArray(); + b.getProperties().forEach((k, v) -> { + Object rv = values.get(k); + String type = rv != null ? rv.getClass().getName() : null; + JsonObject jp = new JsonObject(); + jp.put("name", k); + if (type != null) { + jp.put("type", type); + } + jp.put("value", v); + arr.add(jp); + }); + jb.put("modelProperties", arr); + JsonArray arr2 = new JsonArray(); + b.getProperties().forEach((k, v) -> { + Object rv = values.get(k); + Object value = rv; + String type = rv != null ? rv.getClass().getName() : null; + if (type != null) { + value = Jsoner.trySerialize(rv); + if (value == null) { + // cannot serialize so escape + value = Jsoner.escape(rv.toString()); + } else { + // okay so use the value as-s + value = rv; + } + } + JsonObject jp = new JsonObject(); + jp.put("name", k); + if (type != null) { + jp.put("type", type); + } + jp.put("value", value); + arr2.add(jp); + }); + jb.put("properties", arr2); + } + } + } + return root; + } + +} diff --git a/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java b/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java index bc4f3da3b6e..3227ce736e0 100644 --- a/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java +++ b/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java @@ -495,7 +495,7 @@ public final class ObjectHelper { return Object[].class; } else if ("java.lang.String[]".equals(name) || "String[]".equals(name)) { return String[].class; - // and these is common as well + // and these are common as well } else if ("java.lang.String".equals(name) || "String".equals(name)) { return String.class; } else if ("java.lang.Boolean".equals(name) || "Boolean".equals(name)) { diff --git a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java index f288cc1f174..2b13d7ab5e6 100644 --- a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java +++ b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java @@ -263,6 +263,8 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C doActionSendTask(root); } else if ("transform".equals(action)) { doActionTransformTask(root); + } else if ("bean".equals(action)) { + doActionBeanTask(); } // action done so delete file @@ -694,6 +696,24 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C } } + private void doActionBeanTask() throws IOException { + JsonObject root = new JsonObject(); + DevConsole dc1 = camelContext.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class) + .resolveById("bean"); + DevConsole dc2 = camelContext.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class) + .resolveById("bean-model"); + if (dc1 != null) { + JsonObject json = (JsonObject) dc1.call(DevConsole.MediaType.JSON); + root.put("beans", json.getCollection("beans")); + } + if (dc2 != null) { + JsonObject json = (JsonObject) dc2.call(DevConsole.MediaType.JSON); + root.put("bean-models", json.getCollection("beans")); + } + LOG.trace("Updating output file: {}", outputFile); + IOHelper.writeText(root.toJson(), outputFile); + } + private void doActionResetStatsTask() throws Exception { ManagedCamelContext mcc = camelContext.getCamelContextExtension().getContextPlugin(ManagedCamelContext.class); if (mcc != null) { diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVariable.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVariable.java index c5910e354aa..f19fa750447 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVariable.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListVariable.java @@ -89,7 +89,7 @@ public class ListVariable extends ProcessWatchCommand { JsonObject jo = (JsonObject) arr.get(i); row.id = id; row.key = jo.getString("key"); - row.className = jo.getString("className"); + row.type = jo.getString("type"); row.value = jo.get("value"); rows.add(row); } @@ -108,7 +108,7 @@ public class ListVariable extends ProcessWatchCommand { .with(r -> r.name), new Column().header("REPOSITORY").headerAlign(HorizontalAlign.CENTER).with(r -> r.id), new Column().header("TYPE").headerAlign(HorizontalAlign.CENTER) - .maxWidth(40, OverflowBehaviour.ELLIPSIS_LEFT).with(r -> r.className), + .maxWidth(40, OverflowBehaviour.ELLIPSIS_LEFT).with(r -> r.type), new Column().header("KEY").dataAlign(HorizontalAlign.LEFT).maxWidth(50, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.key), new Column().header("VALUE").headerAlign(HorizontalAlign.RIGHT).maxWidth(80, OverflowBehaviour.NEWLINE) @@ -154,7 +154,7 @@ public class ListVariable extends ProcessWatchCommand { String name; String id; String key; - String className; + String type; Object value; Row copy() {