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 0940f345ab6 CAMEL-18204: camel-jbang - Export to quarkus should use 
quarkus catalog to know if the JARs are an extension or not to generate correct 
pom.xml
0940f345ab6 is described below

commit 0940f345ab67cd4a2a93a4abb652f17f37632af4
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Tue Jun 21 12:31:18 2022 +0200

    CAMEL-18204: camel-jbang - Export to quarkus should use quarkus catalog to 
know if the JARs are an extension or not to generate correct pom.xml
---
 .../dsl/jbang/core/commands/ExportQuarkus.java     | 110 ++++++++++++++++++++-
 .../camel/dsl/jbang/core/common/XmlHelper.java     |  58 +++++++++++
 .../camel/main/download/DependencyDownloader.java  |  22 ++++-
 .../main/download/MavenDependencyDownloader.java   |  36 ++++++-
 4 files changed, 221 insertions(+), 5 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
index 8146be4ebb1..e9badb96529 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
@@ -22,7 +22,22 @@ import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.util.Set;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.catalog.RuntimeProvider;
+import org.apache.camel.dsl.jbang.core.common.XmlHelper;
+import org.apache.camel.main.KameletMain;
+import org.apache.camel.main.download.MavenArtifact;
+import org.apache.camel.main.download.MavenDependencyDownloader;
 import org.apache.camel.main.download.MavenGav;
+import org.apache.camel.tooling.model.ArtifactModel;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.OrderedProperties;
@@ -30,6 +45,12 @@ import org.apache.commons.io.FileUtils;
 
 class ExportQuarkus extends Export {
 
+    private static final String DEFAULT_CAMEL_CATALOG = 
"org.apache.camel.catalog.DefaultCamelCatalog";
+    private static final String QUARKUS_CATALOG_PROVIDER = 
"org.apache.camel.catalog.quarkus.QuarkusRuntimeProvider";
+
+    private String camelVersion = null;
+    private String camelQuarkusVersion = null;
+
     public ExportQuarkus(CamelJBangMain main) {
         super(main);
     }
@@ -129,11 +150,17 @@ class ExportQuarkus extends Export {
         String context = IOHelper.loadText(is);
         IOHelper.close(is);
 
+        CamelCatalog catalog = loadQuarkusCatalog();
+        if (camelVersion == null) {
+            camelVersion = catalog.getCatalogVersion();
+        }
+
         context = context.replaceFirst("\\{\\{ \\.GroupId }}", ids[0]);
         context = context.replaceFirst("\\{\\{ \\.ArtifactId }}", ids[1]);
         context = context.replaceFirst("\\{\\{ \\.Version }}", ids[2]);
         context = context.replaceAll("\\{\\{ \\.QuarkusVersion }}", 
quarkusVersion);
         context = context.replaceFirst("\\{\\{ \\.JavaVersion }}", 
javaVersion);
+        context = context.replaceFirst("\\{\\{ \\.CamelVersion }}", 
camelVersion);
 
         OrderedProperties prop = new OrderedProperties();
         prop.load(new FileInputStream(settings));
@@ -162,9 +189,17 @@ class ExportQuarkus extends Export {
             String v = gav.getVersion();
             // transform to camel-quarkus extension GAV
             if ("org.apache.camel".equals(gid)) {
-                gid = "org.apache.camel.quarkus";
-                aid = aid.replace("camel-", "camel-quarkus-");
-                v = null;
+                String qaid = aid.replace("camel-", "camel-quarkus-");
+                ArtifactModel<?> am = 
catalog.modelFromMavenGAV("org.apache.camel.quarkus", qaid, null);
+                if (am != null) {
+                    // use quarkus extension
+                    gid = am.getGroupId();
+                    aid = am.getArtifactId();
+                    v = null; // uses BOM so version should not be included
+                } else {
+                    // there is no quarkus extension so use plain camel
+                    v = camelVersion;
+                }
             }
             sb.append("        <dependency>\n");
             sb.append("            
<groupId>").append(gid).append("</groupId>\n");
@@ -191,4 +226,73 @@ class ExportQuarkus extends Export {
         return answer;
     }
 
+    private CamelCatalog loadQuarkusCatalog() {
+        CamelCatalog answer = new DefaultCamelCatalog(true);
+
+        // use kamelet-main to dynamic download dependency via maven
+        KameletMain main = new KameletMain();
+        try {
+            main.start();
+
+            // shrinkwrap does not return POM file as result (they are 
hardcoded to be filtered out)
+            // so after this we download a JAR and then use its File location 
to compute the file for the downloaded POM
+            MavenDependencyDownloader downloader = 
main.getCamelContext().hasService(MavenDependencyDownloader.class);
+            downloader.downloadArtifact("io.quarkus.platform", 
"quarkus-camel-bom:pom", quarkusVersion);
+            MavenArtifact ma = downloader.downloadArtifact("io.quarkus", 
"quarkus-core", quarkusVersion);
+            if (ma != null && ma.getFile() != null) {
+                String name = ma.getFile().getAbsolutePath();
+                name = name.replace("io/quarkus/quarkus-core", 
"io/quarkus/platform/quarkus-camel-bom");
+                name = name.replace("quarkus-core", "quarkus-camel-bom");
+                name = name.replace(".jar", ".pom");
+                File file = new File(name);
+                if (file.exists()) {
+                    DocumentBuilderFactory dbf = 
XmlHelper.createDocumentBuilderFactory();
+                    DocumentBuilder db = dbf.newDocumentBuilder();
+                    Document dom = db.parse(file);
+
+                    // grab what exact camelVersion and camelQuarkusVersion we 
are using
+                    NodeList nl = dom.getElementsByTagName("dependency");
+                    for (int i = 0; i < nl.getLength(); i++) {
+                        Element node = (Element) nl.item(i);
+                        String g = 
node.getElementsByTagName("groupId").item(0).getTextContent();
+                        String a = 
node.getElementsByTagName("artifactId").item(0).getTextContent();
+                        if ("org.apache.camel".equals(g) && 
"camel-core-engine".equals(a)) {
+                            camelVersion = 
node.getElementsByTagName("version").item(0).getTextContent();
+                        } else if ("org.apache.camel.quarkus".equals(g) && 
"camel-quarkus-catalog".equals(a)) {
+                            camelQuarkusVersion = 
node.getElementsByTagName("version").item(0).getTextContent();
+                        }
+                    }
+                }
+            }
+
+            if (camelQuarkusVersion != null) {
+                // download camel-quarkus-catalog we use to know if we have an 
extension or not
+                downloader.downloadDependency("org.apache.camel.quarkus", 
"camel-quarkus-catalog", camelQuarkusVersion);
+
+                Class<RuntimeProvider> clazz = 
main.getCamelContext().getClassResolver().resolveClass(QUARKUS_CATALOG_PROVIDER,
+                        RuntimeProvider.class);
+                if (clazz != null) {
+                    RuntimeProvider provider = 
main.getCamelContext().getInjector().newInstance(clazz);
+                    if (provider != null) {
+                        // re-create answer with the classloader that loaded 
spring-boot to be able to load resources in this catalog
+                        Class<CamelCatalog> clazz2
+                                = 
main.getCamelContext().getClassResolver().resolveClass(DEFAULT_CAMEL_CATALOG,
+                                        CamelCatalog.class);
+                        answer = 
main.getCamelContext().getInjector().newInstance(clazz2);
+                        answer.setRuntimeProvider(provider);
+                        // use classloader that loaded spring-boot provider to 
ensure we can load its resources
+                        
answer.getVersionManager().setClassLoader(main.getCamelContext().getApplicationContextClassLoader());
+                        answer.enableCache();
+                    }
+                }
+            }
+        } catch (Exception e) {
+            // ignore
+        } finally {
+            main.stop();
+        }
+
+        return answer;
+    }
+
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java
new file mode 100644
index 00000000000..afc58f99cd9
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/XmlHelper.java
@@ -0,0 +1,58 @@
+/*
+ * 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.common;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.camel.util.ObjectHelper;
+
+public final class XmlHelper {
+
+    private XmlHelper() {
+    }
+
+    public static DocumentBuilderFactory createDocumentBuilderFactory() {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        factory.setIgnoringElementContentWhitespace(true);
+        factory.setIgnoringComments(true);
+        try {
+            // Set secure processing
+            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, 
Boolean.TRUE);
+        } catch (ParserConfigurationException e) {
+        }
+        try {
+            // Disable the external-general-entities by default
+            
factory.setFeature("http://xml.org/sax/features/external-general-entities";, 
false);
+        } catch (ParserConfigurationException e) {
+        }
+        // setup the SecurityManager by default if it's apache xerces
+        try {
+            Class<?> smClass = 
ObjectHelper.loadClass("org.apache.xerces.util.SecurityManager");
+            if (smClass != null) {
+                Object sm = smClass.getDeclaredConstructor().newInstance();
+                // Here we just use the default setting of the SeurityManager
+                
factory.setAttribute("http://apache.org/xml/properties/security-manager";, sm);
+            }
+        } catch (Exception e) {
+        }
+        return factory;
+    }
+
+}
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java
index 5823a85dbf0..153ac0d3050 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java
@@ -46,7 +46,7 @@ public interface DependencyDownloader extends 
CamelContextAware, StaticService {
     void setFresh(boolean fresh);
 
     /**
-     * Downloads the dependency
+     * Downloads the dependency incl transitive dependencies
      *
      * @param groupId    maven group id
      * @param artifactId maven artifact id
@@ -54,6 +54,26 @@ public interface DependencyDownloader extends 
CamelContextAware, StaticService {
      */
     void downloadDependency(String groupId, String artifactId, String version);
 
+    /**
+     * Downloads the dependency
+     *
+     * @param groupId      maven group id
+     * @param artifactId   maven artifact id
+     * @param version      maven version
+     * @param transitively whether to include transitive dependencies
+     */
+    void downloadDependency(String groupId, String artifactId, String version, 
boolean transitively);
+
+    /**
+     * Downloads a single maven artifact (no transitive dependencies)
+     *
+     * @param  groupId    maven group id
+     * @param  artifactId maven artifact id
+     * @param  version    maven version
+     * @return            the artifact, or null if none found
+     */
+    MavenArtifact downloadArtifact(String groupId, String artifactId, String 
version);
+
     /**
      * Checks whether the dependency is already on the classpath
      *
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java
index 1e11eae6ddb..cb1c5261743 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java
@@ -89,6 +89,11 @@ public class MavenDependencyDownloader extends 
ServiceSupport implements Depende
 
     @Override
     public void downloadDependency(String groupId, String artifactId, String 
version) {
+        downloadDependency(groupId, artifactId, version, true);
+    }
+
+    @Override
+    public void downloadDependency(String groupId, String artifactId, String 
version, boolean transitively) {
         // trigger listener
         if (downloadListener != null) {
             downloadListener.onDownloadDependency(groupId, artifactId, 
version);
@@ -132,7 +137,7 @@ public class MavenDependencyDownloader extends 
ServiceSupport implements Depende
             }
 
             List<MavenArtifact> artifacts
-                    = 
MavenDependencyResolver.resolveDependenciesViaAether(deps, mavenRepos, false, 
fresh, true);
+                    = 
MavenDependencyResolver.resolveDependenciesViaAether(deps, mavenRepos, false, 
fresh, transitively);
             LOG.debug("Resolved {} -> [{}]", gav, artifacts);
 
             DependencyDownloaderClassLoader classLoader
@@ -149,6 +154,35 @@ public class MavenDependencyDownloader extends 
ServiceSupport implements Depende
         }, gav);
     }
 
+    @Override
+    public MavenArtifact downloadArtifact(String groupId, String artifactId, 
String version) {
+        String gav = groupId + ":" + artifactId + ":" + version;
+        LOG.debug("DownloadingArtifact: {}", gav);
+        List<String> deps = List.of(gav);
+        List<String> mavenRepos = new ArrayList<>();
+
+        // add maven central first
+        mavenRepos.add(MAVEN_CENTRAL_REPO);
+        // and custom repos
+        if (repos != null) {
+            
mavenRepos.addAll(Arrays.stream(repos.split(",")).collect(Collectors.toList()));
+        }
+        // include Apache snapshot to make it easy to use upcoming releases
+        if ("org.apache.camel".equals(groupId) && 
version.contains("SNAPSHOT")) {
+            mavenRepos.add(APACHE_SNAPSHOT_REPO);
+        }
+
+        List<MavenArtifact> artifacts
+                = MavenDependencyResolver.resolveDependenciesViaAether(deps, 
mavenRepos, false, fresh, false);
+        LOG.debug("Resolved {} -> [{}]", gav, artifacts);
+
+        if (artifacts.size() == 1) {
+            return artifacts.get(0);
+        }
+
+        return null;
+    }
+
     public boolean alreadyOnClasspath(String groupId, String artifactId, 
String version) {
         return alreadyOnClasspath(groupId, artifactId, version, true);
     }

Reply via email to