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

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


The following commit(s) were added to refs/heads/main by this push:
     new 4855c5e2476 CAMEL-18515: camel-jbang - Command to list kamelets from 
the catalog.
4855c5e2476 is described below

commit 4855c5e2476d5ea4bd0d70e4e98b5539c9653378
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Fri Sep 16 23:47:22 2022 +0200

    CAMEL-18515: camel-jbang - Command to list kamelets from the catalog.
---
 .../dsl/jbang/core/commands/CamelJBangMain.java    |   4 +
 .../core/commands/kamelet/CatalogCommand.java      |  35 ++++
 .../core/commands/kamelet/CatalogKamelet.java      | 206 +++++++++++++++++++++
 3 files changed, 245 insertions(+)

diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
index 14b56996dd5..05fa2aa7921 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
@@ -28,6 +28,8 @@ import 
org.apache.camel.dsl.jbang.core.commands.action.CamelRouteStartAction;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelRouteStopAction;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelSourceTop;
 import org.apache.camel.dsl.jbang.core.commands.action.CamelThreadDump;
+import org.apache.camel.dsl.jbang.core.commands.kamelet.CatalogCommand;
+import org.apache.camel.dsl.jbang.core.commands.kamelet.CatalogKamelet;
 import org.apache.camel.dsl.jbang.core.commands.process.CamelContextStatus;
 import org.apache.camel.dsl.jbang.core.commands.process.CamelContextTop;
 import org.apache.camel.dsl.jbang.core.commands.process.CamelProcessorStatus;
@@ -74,6 +76,8 @@ public class CamelJBangMain implements Callable<Integer> {
                         .addSubcommand("gc", new CommandLine(new 
CamelGCAction(main))))
                 .addSubcommand("generate", new CommandLine(new 
CodeGenerator(main))
                         .addSubcommand("rest", new CommandLine(new 
CodeRestGenerator(main))))
+                .addSubcommand("catalog", new CommandLine(new 
CatalogCommand(main))
+                        .addSubcommand("kamelet", new CommandLine(new 
CatalogKamelet(main))))
                 .addSubcommand("jolokia", new CommandLine(new Jolokia(main)))
                 .addSubcommand("hawtio", new CommandLine(new Hawtio(main)))
                 .addSubcommand("bind", new CommandLine(new Bind(main)))
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/kamelet/CatalogCommand.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/kamelet/CatalogCommand.java
new file mode 100644
index 00000000000..da9d41dfe32
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/kamelet/CatalogCommand.java
@@ -0,0 +1,35 @@
+/*
+ * 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.dsl.jbang.core.commands.kamelet;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import picocli.CommandLine;
+
+@CommandLine.Command(name = "catalog", description = "List artifacts from 
Camel Catalog (use --help to see sub commands)")
+public class CatalogCommand extends CamelCommand {
+
+    public CatalogCommand(CamelJBangMain main) {
+        super(main);
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        new CommandLine(this).execute("--help");
+        return 0;
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/kamelet/CatalogKamelet.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/kamelet/CatalogKamelet.java
new file mode 100644
index 00000000000..9598fa74741
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/kamelet/CatalogKamelet.java
@@ -0,0 +1,206 @@
+/*
+ * 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.dsl.jbang.core.commands.kamelet;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.github.freva.asciitable.AsciiTable;
+import com.github.freva.asciitable.Column;
+import com.github.freva.asciitable.HorizontalAlign;
+import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.main.download.DependencyDownloaderClassLoader;
+import org.apache.camel.main.download.MavenDependencyDownloader;
+import org.apache.camel.support.ObjectHelper;
+import org.apache.camel.util.StringHelper;
+import picocli.CommandLine;
+
+@CommandLine.Command(name = "kamelet", aliases = { "kamelet", "kamelets" },
+                     description = "List Kamelets from the Kamelet Catalog")
+public class CatalogKamelet extends CamelCommand {
+
+    @CommandLine.Option(names = { "--sort" },
+                        description = "Sort by name, type, level, or 
description", defaultValue = "name")
+    String sort;
+
+    @CommandLine.Option(names = { "--type", "--filter-type" },
+                        description = "Filter by type: source, sink, or 
action")
+    String filterType;
+
+    @CommandLine.Option(names = { "--filter" },
+                        description = "Filter by name or description")
+    String filterName;
+
+    @CommandLine.Option(names = {
+            "--kamelets-version" }, description = "Apache Camel Kamelets 
version", defaultValue = "0.9.0")
+    String kameletsVersion;
+
+    public CatalogKamelet(CamelJBangMain main) {
+        super(main);
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        List<Row> rows = new ArrayList<>();
+
+        Map<String, Object> kamelets;
+        try {
+            ClassLoader cl = createClassLoader();
+            MavenDependencyDownloader downloader = new 
MavenDependencyDownloader();
+            downloader.setClassLoader(cl);
+            downloader.start();
+            downloader.downloadDependency("org.apache.camel.kamelets", 
"camel-kamelets-catalog", kameletsVersion);
+
+            Thread.currentThread().setContextClassLoader(cl);
+            Class<?> clazz = 
cl.loadClass("org.apache.camel.kamelets.catalog.KameletsCatalog");
+            Object catalog = clazz.getDeclaredConstructor().newInstance();
+            Method m = clazz.getMethod("getKamelets");
+            kamelets = (Map<String, Object>) ObjectHelper.invokeMethod(m, 
catalog);
+        } catch (Exception e) {
+            System.err.println("Cannot download camel-kamelets-catalog due to 
" + e.getMessage());
+            return 1;
+        }
+
+        for (Object o : kamelets.values()) {
+            Row row = new Row();
+            row.name = getName(o);
+            row.type = getType(o);
+            row.level = getLevel(o);
+            row.description = getDescription(o);
+            rows.add(row);
+        }
+
+        if (filterType != null) {
+            rows = rows.stream().filter(r -> 
r.type.equalsIgnoreCase(filterType)).collect(Collectors.toList());
+        }
+        if (filterName != null) {
+            filterName = filterName.toLowerCase(Locale.ROOT);
+            rows = rows.stream().filter(
+                    r -> r.name.equalsIgnoreCase(filterName) || 
r.description.toLowerCase(Locale.ROOT).contains(filterName))
+                    .collect(Collectors.toList());
+        }
+
+        // sort rows
+        rows.sort(this::sortRow);
+
+        if (!rows.isEmpty()) {
+            System.out.println(AsciiTable.getTable(AsciiTable.NO_BORDERS, 
rows, Arrays.asList(
+                    new 
Column().header("NAME").dataAlign(HorizontalAlign.LEFT).with(r -> r.name),
+                    new 
Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).with(r -> r.type),
+                    new 
Column().header("LEVEL").dataAlign(HorizontalAlign.LEFT).with(r -> r.level),
+                    new 
Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).with(this::getDescription))));
+        }
+
+        return 0;
+    }
+
+    protected int sortRow(Row o1, Row o2) {
+        String s = sort;
+        int negate = 1;
+        if (s.startsWith("-")) {
+            s = s.substring(1);
+            negate = -1;
+        }
+        switch (s) {
+            case "name":
+                return o1.name.compareToIgnoreCase(o2.name) * negate;
+            case "type":
+                return o1.type.compareToIgnoreCase(o2.type) * negate;
+            case "level":
+                return o1.level.compareToIgnoreCase(o2.level) * negate;
+            case "description":
+                return o1.description.compareToIgnoreCase(o2.description) * 
negate;
+            default:
+                return 0;
+        }
+    }
+
+    private ClassLoader createClassLoader() {
+        ClassLoader parentCL = CatalogKamelet.class.getClassLoader();
+        return new DependencyDownloaderClassLoader(parentCL);
+    }
+
+    private String getName(Object kamelet) throws Exception {
+        Method m = kamelet.getClass().getMethod("getMetadata");
+        Object meta = ObjectHelper.invokeMethod(m, kamelet);
+        m = meta.getClass().getMethod("getName");
+        return (String) ObjectHelper.invokeMethod(m, meta);
+    }
+
+    private String getType(Object kamelet) throws Exception {
+        Method m = kamelet.getClass().getMethod("getMetadata");
+        Object meta = ObjectHelper.invokeMethod(m, kamelet);
+        m = meta.getClass().getMethod("getLabels");
+        Map labels = (Map) ObjectHelper.invokeMethod(m, meta);
+        if (labels != null) {
+            return (String) labels.get("camel.apache.org/kamelet.type");
+        }
+        return null;
+    }
+
+    private String getLevel(Object kamelet) throws Exception {
+        Method m = kamelet.getClass().getMethod("getMetadata");
+        Object meta = ObjectHelper.invokeMethod(m, kamelet);
+        m = meta.getClass().getMethod("getAnnotations");
+        Map anns = (Map) ObjectHelper.invokeMethod(m, meta);
+        if (anns != null) {
+            return (String) anns.get("camel.apache.org/kamelet.support.level");
+        }
+        return null;
+    }
+
+    private String getDescription(Object kamelet) throws Exception {
+        Method m = kamelet.getClass().getMethod("getSpec");
+        Object spec = ObjectHelper.invokeMethod(m, kamelet);
+        m = spec.getClass().getMethod("getDefinition");
+        Object def = ObjectHelper.invokeMethod(m, spec);
+        m = def.getClass().getMethod("getDescription");
+        return (String) ObjectHelper.invokeMethod(m, def);
+    }
+
+    private static class Row {
+        private String name;
+        private String type;
+        private String level;
+        private String description;
+    }
+
+    private String getDescription(Row r) {
+        String d = r.description;
+        if (d != null && d.contains(".")) {
+            // grab first sentence
+            d = StringHelper.before(d, ".");
+            d = d.trim();
+        }
+        if (d != null && d.contains("\n")) {
+            // grab first sentence
+            d = StringHelper.before(d, "\n");
+            d = d.trim();
+        }
+        if (d == null) {
+            d = "";
+        }
+        return d;
+    }
+
+}

Reply via email to