You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pp...@apache.org on 2020/09/24 15:51:00 UTC
[camel-quarkus] 01/02: Generate partials instead of pages for the
individual Camel bits #1795
This is an automated email from the ASF dual-hosted git repository.
ppalaga pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 38625a9f2ff362dbe2e5304e281ecaf3ac6b6316
Author: Peter Palaga <pp...@redhat.com>
AuthorDate: Wed Sep 23 13:34:31 2020 +0200
Generate partials instead of pages for the individual Camel bits #1795
---
catalog/pom.xml | 1 +
docs/README.adoc | 14 ++
docs/antora-playbook-dev.yml | 47 +++++
docs/modules/ROOT/pages/reference/components.adoc | 12 +-
docs/modules/ROOT/pages/reference/dataformats.adoc | 12 +-
docs/modules/ROOT/pages/reference/languages.adoc | 12 +-
docs/modules/ROOT/pages/reference/others.adoc | 6 +
docs/package.json | 2 +-
.../quarkus/maven/AbstractDocGeneratorMojo.java | 2 +-
.../quarkus/maven/CheckExtensionPagesMojo.java | 196 +++++++++++++++++++++
.../org/apache/camel/quarkus/maven/CqCatalog.java | 120 ++++++++++++-
.../org/apache/camel/quarkus/maven/CqUtils.java | 50 ++++++
.../quarkus/maven/UpdateExtensionDocPageMojo.java | 36 +++-
.../doc-templates/extension-doc-page.adoc | 2 +-
.../doc-templates/extensions-camel-bits.adoc | 1 -
15 files changed, 494 insertions(+), 19 deletions(-)
diff --git a/catalog/pom.xml b/catalog/pom.xml
index ad96517..95f2f1d 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -4127,6 +4127,7 @@
<!-- prepare the catalog and update doc files, etc. -->
<goals>
<goal>prepare-catalog-quarkus</goal>
+ <goal>check-extension-pages</goal>
</goals>
<phase>process-resources</phase>
<configuration>
diff --git a/docs/README.adoc b/docs/README.adoc
index fd3b823..7d227a3 100644
--- a/docs/README.adoc
+++ b/docs/README.adoc
@@ -1,5 +1,19 @@
= Apache Camel extensions for Quarkus Documentation
+== Antora playbooks
+
+There are two Antora playbooks available in the project: link:antora-playbook.yml[antora-playbook.yml] and
+link:antora-playbook-dev.yml[antora-playbook-dev.yml].
+
+link:antora-playbook.yml[antora-playbook.yml] is optimized for fast `xref` verification on the CI - it is used under
+the hood by `exec-maven-plugin` when `mvn verify` is invoked. However, the site it produces is rather
+incomplete.
+
+link:antora-playbook-dev.yml[antora-playbook-dev.yml] aims at building a more complete site. It pulls Camel and Camel
+Spring Boot Antora docs so that the lists of Camel components (available under Camel Quarkus reference docs) are built
+too.
+
+
== Environment Setup
To setup the environment you need to execute the following command once (and every time you change yarn dependencies):
diff --git a/docs/antora-playbook-dev.yml b/docs/antora-playbook-dev.yml
new file mode 100644
index 0000000..fd2e4f4
--- /dev/null
+++ b/docs/antora-playbook-dev.yml
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+site:
+ title: Apache Camel extensions for Quarkus
+ url: https://camel.apache.org
+ start_page: camel-quarkus::index.adoc
+content:
+ sources:
+ - url: ./../
+ branches: HEAD
+ start_path: docs
+ - url: ./../../../camel/camel
+ branches: HEAD
+ start_path: docs/components
+ - url: git@github.com:apache/camel-spring-boot.git
+ branches: master
+ start_path: docs
+
+asciidoc:
+ extensions:
+ - "@djencks/asciidoctor-antora-indexer"
+ attributes:
+ eip-vc: latest@components
+
+ui:
+ bundle:
+ url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/master/raw/build/ui-bundle.zip?job=bundle-stable
+ snapshot: true
+output:
+ dir: ./target/site
+urls:
+ redirect_facility: httpd
diff --git a/docs/modules/ROOT/pages/reference/components.adoc b/docs/modules/ROOT/pages/reference/components.adoc
index c2cebf9..7242aab 100644
--- a/docs/modules/ROOT/pages/reference/components.adoc
+++ b/docs/modules/ROOT/pages/reference/components.adoc
@@ -1,13 +1,19 @@
= Camel components supported on Quarkus
+:indexer-version: latest
+:indexer-component: components
+:indexer-module: ROOT
+:indexer-rel-filter: *-component.adoc
+:indexer-human-readable-kind: Component
+:indexer-human-readable-kind-plural: components
-There are indexCount:[relative=reference/components/\*.adoc] components (indexCount:[relative=reference/components/\*.adoc,attributes='cq-deprecated=true'] deprecated, indexCount:[relative=reference/components/\*.adoc,attributes='cq-native-supported=false'] JVM only)
+There are indexCount:[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}",relative="{indexer-rel-filter}",attributes=cq-artifact-id] {indexer-human-readable-kind-plural} (indexCount:[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}",relative="{indexer-rel-filter}",attributes='cq-artifact-id,cq-deprecated=true'] deprecated, indexCount:[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}" [...]
[.counted-table,width="100%",cols="4,1,1,1,1,5",options="header"]
|===
-| Component | Artifact | JVM +
+| {indexer-human-readable-kind} | Artifact | JVM +
since | Native +
since | Support +
level | Description
|===
-indexTable::[relative='reference/components/*.adoc',cells="=`xref:reference/extensions/$\{cqArtifactIdBase}.adoc[$\{cqCamelPartTitle}]`,cq-artifact-id,cq-jvm-since,cq-native-since,cq-status,cq-camel-part-description"]
+indexTable::[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}",relative="{indexer-rel-filter}",attributes=cq-artifact-id,cells="=`xref:reference/extensions/$\{cqArtifactIdBase}.adoc[$\{cqCamelPartTitle}]`,cq-artifact-id,cq-jvm-since,cq-native-since,cq-status,cq-camel-part-description"]
diff --git a/docs/modules/ROOT/pages/reference/dataformats.adoc b/docs/modules/ROOT/pages/reference/dataformats.adoc
index 27db993..c47e163 100644
--- a/docs/modules/ROOT/pages/reference/dataformats.adoc
+++ b/docs/modules/ROOT/pages/reference/dataformats.adoc
@@ -1,13 +1,19 @@
= Camel data formats supported on Quarkus
+:indexer-version: latest
+:indexer-component: components
+:indexer-module: dataformats
+:indexer-rel-filter: *-dataformat.adoc
+:indexer-human-readable-kind: Data format
+:indexer-human-readable-kind-plural: data formats
-There are indexCount:[relative=reference/dataformats/\*.adoc] data formats (indexCount:[relative=reference/dataformats/\*.adoc,attributes='cq-deprecated=true'] deprecated, indexCount:[relative=reference/dataformats/\*.adoc,attributes='cq-native-supported=false'] JVM only)
+There are indexCount:[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}",relative="{indexer-rel-filter}",attributes=cq-artifact-id] {indexer-human-readable-kind-plural} (indexCount:[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}",relative="{indexer-rel-filter}",attributes='cq-artifact-id,cq-deprecated=true'] deprecated, indexCount:[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}" [...]
[.counted-table,width="100%",cols="4,1,1,1,1,5",options="header"]
|===
-| Data format | Artifact | JVM +
+| {indexer-human-readable-kind} | Artifact | JVM +
since | Native +
since | Support +
level | Description
|===
-indexTable::[relative='reference/dataformats/*.adoc',cells="=`xref:reference/extensions/$\{cqArtifactIdBase}.adoc[$\{cqCamelPartTitle}]`,cq-artifact-id,cq-jvm-since,cq-native-since,cq-status,cq-camel-part-description"]
+indexTable::[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}",relative="{indexer-rel-filter}",attributes=cq-artifact-id,cells="=`xref:reference/extensions/$\{cqArtifactIdBase}.adoc[$\{cqCamelPartTitle}]`,cq-artifact-id,cq-jvm-since,cq-native-since,cq-status,cq-camel-part-description"]
diff --git a/docs/modules/ROOT/pages/reference/languages.adoc b/docs/modules/ROOT/pages/reference/languages.adoc
index 89dd794..82eface 100644
--- a/docs/modules/ROOT/pages/reference/languages.adoc
+++ b/docs/modules/ROOT/pages/reference/languages.adoc
@@ -1,13 +1,19 @@
= Camel languages supported on Quarkus
+:indexer-version: latest
+:indexer-component: components
+:indexer-module: languages
+:indexer-rel-filter: *-language.adoc
+:indexer-human-readable-kind: Language
+:indexer-human-readable-kind-plural: languages
-There are indexCount:[relative=reference/languages/\*.adoc] languages (indexCount:[relative=reference/languages/\*.adoc,attributes='cq-deprecated=true'] deprecated, indexCount:[relative=reference/languages/\*.adoc,attributes='cq-native-supported=false'] JVM only)
+There are indexCount:[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}",relative="{indexer-rel-filter}",attributes=cq-artifact-id] {indexer-human-readable-kind-plural} (indexCount:[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}",relative="{indexer-rel-filter}",attributes='cq-artifact-id,cq-deprecated=true'] deprecated, indexCount:[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}" [...]
[.counted-table,width="100%",cols="4,1,1,1,1,5",options="header"]
|===
-| Language | Artifact | JVM +
+| {indexer-human-readable-kind} | Artifact | JVM +
since | Native +
since | Support +
level | Description
|===
-indexTable::[relative='reference/languages/*.adoc',cells="=`xref:reference/extensions/$\{cqArtifactIdBase}.adoc[$\{cqCamelPartTitle}]`,cq-artifact-id,cq-jvm-since,cq-native-since,cq-status,cq-camel-part-description"]
+indexTable::[version="{indexer-version}",component="{indexer-component}",module="{indexer-module}",relative="{indexer-rel-filter}",attributes=cq-artifact-id,cells="=`xref:reference/extensions/$\{cqArtifactIdBase}.adoc[$\{cqCamelPartTitle}]`,cq-artifact-id,cq-jvm-since,cq-native-since,cq-status,cq-camel-part-description"]
diff --git a/docs/modules/ROOT/pages/reference/others.adoc b/docs/modules/ROOT/pages/reference/others.adoc
index 60208fe..89a259a 100644
--- a/docs/modules/ROOT/pages/reference/others.adoc
+++ b/docs/modules/ROOT/pages/reference/others.adoc
@@ -1,4 +1,10 @@
= Camel misc. components supported on Quarkus
+:indexer-version: latest
+:indexer-component: components
+:indexer-module: others
+:indexer-rel-filter: *.adoc
+:indexer-human-readable-kind: Misc. component
+:indexer-human-readable-kind-plural: misc. components
There are indexCount:[relative=reference/others/\*.adoc] misc. components (indexCount:[relative=reference/others/\*.adoc,attributes='cq-deprecated=true'] deprecated, indexCount:[relative=reference/others/\*.adoc,attributes='cq-native-supported=false'] JVM only)
diff --git a/docs/package.json b/docs/package.json
index a11c4d7..133662a 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -17,7 +17,7 @@
},
"scripts": {
"preview": "cd target/site && lite-server",
- "build": "node_modules/.bin/antora antora-playbook.yml --stacktrace",
+ "build": "node_modules/.bin/antora antora-playbook-dev.yml --stacktrace",
"dev": "yarn build && yarn preview",
"checks": "yarn antora --generator @antora/xref-validator antora-playbook.yml"
}
diff --git a/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/AbstractDocGeneratorMojo.java b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/AbstractDocGeneratorMojo.java
index 2a92aa8..7407509 100644
--- a/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/AbstractDocGeneratorMojo.java
+++ b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/AbstractDocGeneratorMojo.java
@@ -28,7 +28,7 @@ import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Parameter;
/**
- * Base for {@link UpdateDocExtensionsListMojo} and {@link UpdateExtensionDocPageMojo}.
+ * Base for {@link CheckExtensionPagesMojo} and {@link UpdateExtensionDocPageMojo}.
*/
abstract class AbstractDocGeneratorMojo extends AbstractMojo {
public static final String DEFAULT_TEMPLATES_URI_BASE = "classpath:/doc-templates";
diff --git a/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CheckExtensionPagesMojo.java b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CheckExtensionPagesMojo.java
new file mode 100644
index 0000000..dd75fa7
--- /dev/null
+++ b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CheckExtensionPagesMojo.java
@@ -0,0 +1,196 @@
+/*
+ * 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.quarkus.maven;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.camel.quarkus.maven.CqCatalog.Flavor;
+import org.apache.camel.quarkus.maven.CqCatalog.GavCqCatalog;
+import org.apache.camel.tooling.model.ArtifactModel;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+
+/**
+ * Performs the following tasks:
+ * <ul>
+ * <li>Deletes extension pages whose extensions do not exist anymore
+ * <li>Creates dummy partials for Camel bits that Camel Quarkus does not support, so that there are no warnings when
+ * they are included from the Camel component pages
+ * <li>Deletes Camel bit partials that do not exist anymore.
+ * <ul>
+ */
+@Mojo(name = "check-extension-pages", threadSafe = true)
+public class CheckExtensionPagesMojo extends AbstractDocGeneratorMojo {
+
+ private static final Pattern ADOC_ENDING_PATTERN = Pattern.compile("\\.adoc$");
+ private static final byte[] DUMMY_COMPONENT_FILE_COMMENT = "// Empty partial for a Camel bit unsupported by Camel Quarkus to avoid warnings when this file is included from a Camel page\n"
+ .getBytes(StandardCharsets.UTF_8);
+
+ /**
+ * The directory relative to which the catalog data is read.
+ */
+ @Parameter(defaultValue = "${project.build.directory}/classes", property = "camel-quarkus.catalogBaseDir")
+ File catalogBaseDir;
+
+ /**
+ * The path to the docs module base directory
+ */
+ @Parameter(defaultValue = "${maven.multiModuleProjectDirectory}/docs")
+ File docsBaseDir;
+
+ /**
+ * List of directories that contain extensions
+ */
+ @Parameter(property = "cq.extensionDirectories", required = true)
+ List<File> extensionDirectories;
+
+ /**
+ * A set of artifactIdBases that are not extensions and should be excluded from the catalog
+ */
+ @Parameter(property = "cq.skipArtifactIdBases")
+ Set<String> skipArtifactIdBases;
+
+ /**
+ * The version of Camel we depend on
+ */
+ @Parameter(property = "camel.version")
+ String camelVersion;
+
+ @Parameter(defaultValue = "${settings.localRepository}", readonly = true)
+ String localRepository;
+
+ /**
+ * Execute goal.
+ *
+ * @throws MojoExecutionException execution of the main class or one of the
+ * threads it generated failed.
+ * @throws MojoFailureException something bad happened...
+ */
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ final Path docsBasePath = docsBaseDir.toPath();
+ if (skipArtifactIdBases == null) {
+ skipArtifactIdBases = Collections.emptySet();
+ }
+
+ camelBits(docsBasePath);
+ extensions(docsBasePath);
+ }
+
+ void camelBits(Path docsBasePath) {
+ final CqCatalog cqCatalog = new CqCatalog(catalogBaseDir.toPath(), Flavor.camelQuarkus);
+
+ final Path referenceDir = docsBasePath.resolve("modules/ROOT/partials/reference");
+ try (GavCqCatalog camelCatalog = GavCqCatalog.open(Paths.get(localRepository), Flavor.camel, camelVersion)) {
+
+ CqCatalog.kinds().forEach(kind -> {
+ final Set<String> cqNames = cqCatalog.models(kind)
+ .filter(CqCatalog::isFirstScheme)
+ .map(CqCatalog::toCamelDocsModel)
+ .map(ArtifactModel::getName)
+ .collect(Collectors.toSet());
+ final Set<String> camelNames = camelCatalog.models(kind)
+ .filter(CqCatalog::isFirstScheme)
+ .map(CqCatalog::toCamelDocsModel)
+ .map(ArtifactModel::getName)
+ .collect(Collectors.toSet());
+
+ final Path kindDir = referenceDir.resolve(CqUtils.kindPlural(kind));
+ try {
+ Files.createDirectories(kindDir);
+ } catch (IOException e) {
+ throw new RuntimeException("Could not create " + kindDir, e);
+ }
+ try (Stream<Path> kindFiles = Files.list(kindDir)) {
+ kindFiles.forEach(kindFile -> {
+ final String artifactIdBase = ADOC_ENDING_PATTERN.matcher(kindFile.getFileName().toString())
+ .replaceAll("");
+ if (cqNames.contains(artifactIdBase)) {
+ /* Nothing to do, this should have been done by UpdateExtensionDocPageMojo */
+ } else if (camelNames.contains(artifactIdBase)) {
+ try {
+ if (!Arrays.equals(DUMMY_COMPONENT_FILE_COMMENT, Files.readAllBytes(kindFile))) {
+ Files.write(kindFile, DUMMY_COMPONENT_FILE_COMMENT);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Could not read or write " + kindFile, e);
+ }
+ } else {
+ try {
+ Files.delete(kindFile);
+ } catch (IOException e) {
+ throw new RuntimeException("Could not delete " + kindFile, e);
+ }
+ }
+ });
+ } catch (IOException e) {
+ throw new RuntimeException("Could not list " + kindDir, e);
+ }
+
+ for (String name : camelNames) {
+ final Path kindFile = kindDir.resolve(name + ".adoc");
+ if (!Files.isRegularFile(kindFile)) {
+ try {
+ Files.write(kindFile, DUMMY_COMPONENT_FILE_COMMENT);
+ } catch (IOException e) {
+ throw new RuntimeException("Could not write " + kindFile, e);
+ }
+ }
+ }
+ });
+ }
+
+ }
+
+ void extensions(Path docsBasePath) {
+ final Set<String> artifactIdBases = extensionDirectories.stream()
+ .map(File::toPath)
+ .flatMap(CqUtils::findExtensionArtifactIdBases)
+ .collect(Collectors.toSet());
+
+ final Path docsExtensionsDir = docsBasePath.resolve("modules/ROOT/pages/reference/extensions");
+ try (Stream<Path> docPages = Files.list(docsExtensionsDir)) {
+ docPages
+ .filter(docPagePath -> !artifactIdBases
+ .contains(ADOC_ENDING_PATTERN.matcher(docPagePath.getFileName().toString()).replaceAll("")))
+ .forEach(docPagePath -> {
+ try {
+ Files.delete(docPagePath);
+ } catch (IOException e) {
+ throw new RuntimeException("Could not delete " + docPagePath, e);
+ }
+ });
+ } catch (IOException e) {
+ throw new RuntimeException("Could not list " + docsExtensionsDir, e);
+ }
+ }
+
+}
diff --git a/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CqCatalog.java b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CqCatalog.java
index de18bc2..ecc1ebb 100644
--- a/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CqCatalog.java
+++ b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CqCatalog.java
@@ -18,6 +18,8 @@ package org.apache.camel.quarkus.maven;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -29,15 +31,50 @@ import java.util.stream.Stream;
import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.catalog.DefaultRuntimeProvider;
import org.apache.camel.catalog.DefaultVersionManager;
import org.apache.camel.catalog.Kind;
import org.apache.camel.catalog.RuntimeProvider;
import org.apache.camel.catalog.impl.CatalogHelper;
import org.apache.camel.tooling.model.ArtifactModel;
import org.apache.camel.tooling.model.ComponentModel;
+import org.apache.camel.tooling.model.DataFormatModel;
public class CqCatalog {
+ public enum Flavor {
+ camel("org.apache.camel", "camel-catalog") {
+ @Override
+ public RuntimeProvider createRuntimeProvider(DefaultCamelCatalog c) {
+ return new DefaultRuntimeProvider(c);
+ }
+ },
+ camelQuarkus("org.apache.camel.quarkus", "camel-quarkus-catalog") {
+ @Override
+ public RuntimeProvider createRuntimeProvider(DefaultCamelCatalog c) {
+ return new CqRuntimeProvider(c);
+ }
+ };
+
+ private final String groupId;
+ private final String artifactId;
+
+ private Flavor(String groupId, String artifactId) {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ }
+
+ public abstract RuntimeProvider createRuntimeProvider(DefaultCamelCatalog c);
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+ }
+
private final DefaultCamelCatalog catalog;
private static final ThreadLocal<CqCatalog> threadLocalCamelCatalog = ThreadLocal.withInitial(CqCatalog::new);
@@ -46,10 +83,10 @@ public class CqCatalog {
return threadLocalCamelCatalog.get();
}
- public CqCatalog(Path baseDir) {
+ public CqCatalog(Path baseDir, Flavor flavor) {
super();
final DefaultCamelCatalog c = new DefaultCamelCatalog(true);
- c.setRuntimeProvider(new CqRuntimeProvider(c));
+ c.setRuntimeProvider(flavor.createRuntimeProvider(c));
c.setVersionManager(new CqVersionManager(c, baseDir));
this.catalog = c;
}
@@ -113,6 +150,41 @@ public class CqCatalog {
}
}
+ public static boolean hasAlternativeScheme(ArtifactModel<?> model, String scheme) {
+ if (scheme.equals(model.getName())) {
+ return true;
+ } else if (model.getKind().equals("component")) {
+ final String altSchemes = ((ComponentModel) model).getAlternativeSchemes();
+ if (altSchemes == null || altSchemes.isEmpty()) {
+ return false;
+ } else {
+ return altSchemes.endsWith("," + scheme) || altSchemes.indexOf("," + scheme + ",") > 0;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public static ArtifactModel<?> findFirstSchemeModel(ArtifactModel<?> model, List<ArtifactModel<?>> models) {
+ if (model.getKind().equals("component")) {
+ final String altSchemes = ((ComponentModel) model).getAlternativeSchemes();
+ if (altSchemes == null || altSchemes.isEmpty()) {
+ return model;
+ } else {
+ final String scheme = model.getName();
+ return models.stream()
+ .filter(m -> "component".equals(m.getKind()))
+ .filter(CqCatalog::isFirstScheme)
+ .filter(m -> CqCatalog.hasAlternativeScheme(m, scheme))
+ .findFirst()
+ .orElseThrow(() -> new IllegalStateException(
+ "Could not find first scheme model for scheme " + scheme + " in " + models));
+ }
+ } else {
+ return model;
+ }
+ }
+
public static List<ArtifactModel<?>> primaryModel(Stream<ArtifactModel<?>> input) {
final List<ArtifactModel<?>> models = input
.filter(CqCatalog::isFirstScheme)
@@ -130,6 +202,21 @@ public class CqCatalog {
return models;
}
+ public static ArtifactModel<?> toCamelDocsModel(ArtifactModel<?> m) {
+ if ("imap".equals(m.getName())) {
+ final ComponentModel clone = (ComponentModel) CqUtils.cloneArtifactModel(m);
+ clone.setName("mail");
+ clone.setTitle("Mail");
+ return clone;
+ }
+ if (m.getName().startsWith("bindy")) {
+ final DataFormatModel clone = (DataFormatModel) CqUtils.cloneArtifactModel(m);
+ clone.setName("bindy");
+ return clone;
+ }
+ return m;
+ }
+
static class CqVersionManager extends DefaultVersionManager {
private final Path baseDir;
@@ -284,4 +371,33 @@ public class CqCatalog {
}
}
+ public static class GavCqCatalog extends CqCatalog implements AutoCloseable {
+
+ private final FileSystem jarFileSystem;
+
+ public static GavCqCatalog open(Path localRepository, Flavor flavor, String version) {
+ final Path jarPath = CqUtils.copyJar(localRepository, flavor.getGroupId(), flavor.getArtifactId(), version);
+ try {
+ final FileSystem fs = FileSystems.newFileSystem(jarPath, (ClassLoader) null);
+ return new GavCqCatalog(fs, flavor);
+ } catch (IOException e) {
+ throw new RuntimeException("Could not open file system " + jarPath, e);
+ }
+ }
+
+ GavCqCatalog(FileSystem jarFileSystem, Flavor flavor) {
+ super(jarFileSystem.getRootDirectories().iterator().next(), flavor);
+ this.jarFileSystem = jarFileSystem;
+ }
+
+ @Override
+ public void close() {
+ try {
+ jarFileSystem.close();
+ } catch (IOException e) {
+ throw new RuntimeException("Could not close catalog " + jarFileSystem, e);
+ }
+ }
+ }
+
}
diff --git a/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CqUtils.java b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CqUtils.java
index fa86f51..d744903 100644
--- a/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CqUtils.java
+++ b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/CqUtils.java
@@ -17,6 +17,9 @@
package org.apache.camel.quarkus.maven;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
@@ -34,6 +37,11 @@ import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;
import org.apache.camel.catalog.Kind;
import org.apache.camel.tooling.model.ArtifactModel;
+import org.apache.camel.tooling.model.ComponentModel;
+import org.apache.camel.tooling.model.DataFormatModel;
+import org.apache.camel.tooling.model.JsonMapper;
+import org.apache.camel.tooling.model.LanguageModel;
+import org.apache.camel.tooling.model.OtherModel;
import org.apache.maven.model.Model;
import org.apache.maven.plugin.logging.Log;
@@ -196,4 +204,46 @@ public class CqUtils {
return title.contains("(deprecated)") || models.stream().anyMatch(m -> m.isDeprecated());
}
+ static Path copyJar(Path localRepository, String groupId, String artifactId, String version) {
+ final String relativeJarPath = groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-"
+ + version + ".jar";
+ final Path localPath = localRepository.resolve(relativeJarPath);
+ final boolean localExists = Files.exists(localPath);
+ final String remoteUri = "https://repository.apache.org/content/groups/public/" + relativeJarPath;
+ Path result;
+ try {
+ result = Files.createTempFile(null, localPath.getFileName().toString());
+ try (InputStream in = (localExists ? Files.newInputStream(localPath) : new URL(remoteUri).openStream());
+ OutputStream out = Files.newOutputStream(result)) {
+ final byte[] buf = new byte[4096];
+ int len;
+ while ((len = in.read(buf)) >= 0) {
+ out.write(buf, 0, len);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Could not copy " + (localExists ? localPath : remoteUri) + " to " + result, e);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Could not create temp file", e);
+ }
+ return result;
+ }
+
+ public static ArtifactModel<?> cloneArtifactModel(ArtifactModel<?> model) {
+ final Kind kind = Kind.valueOf(model.getKind());
+ switch (kind) {
+ case component:
+ return JsonMapper.generateComponentModel(JsonMapper.asJsonObject((ComponentModel) model));
+ case dataformat:
+ return JsonMapper.generateDataFormatModel(JsonMapper.asJsonObject((DataFormatModel) model));
+ case language:
+ return JsonMapper.generateLanguageModel(JsonMapper.asJsonObject((LanguageModel) model));
+ case other:
+ return JsonMapper.generateOtherModel(JsonMapper.asJsonObject((OtherModel) model));
+ default:
+ throw new IllegalArgumentException("Unexpected kind " + kind);
+ }
+
+ }
+
}
diff --git a/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/UpdateExtensionDocPageMojo.java b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/UpdateExtensionDocPageMojo.java
index 1c25b69..ad42b10 100644
--- a/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/UpdateExtensionDocPageMojo.java
+++ b/tooling/maven-plugin/src/main/java/org/apache/camel/quarkus/maven/UpdateExtensionDocPageMojo.java
@@ -36,7 +36,9 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import freemarker.template.Configuration;
import freemarker.template.TemplateMethodModelEx;
+import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
+import freemarker.template.utility.DeepUnwrap;
import io.quarkus.annotation.processor.Constants;
import io.quarkus.annotation.processor.generate_doc.ConfigDocItem;
import io.quarkus.annotation.processor.generate_doc.DocGeneratorUtil;
@@ -128,11 +130,36 @@ public class UpdateExtensionDocPageMojo extends AbstractDocGeneratorMojo {
return CqUtils.humanReadableKind(Kind.valueOf(String.valueOf(arguments.get(0))));
}
});
+ model.put("camelBitLink", new TemplateMethodModelEx() {
+ @Override
+ public Object exec(List arguments) throws TemplateModelException {
+ if (arguments.size() != 2) {
+ throw new TemplateModelException("Wrong argument count in camelBitLink()");
+ }
+ final ArtifactModel<?> model = (ArtifactModel<?>) DeepUnwrap.unwrap((TemplateModel) arguments.get(0));
+ final String kind = model.getKind();
+ if (CqCatalog.isFirstScheme(model)) {
+ return camelBitLink(model);
+ } else {
+ final List<ArtifactModel<?>> models = (List<ArtifactModel<?>>) DeepUnwrap
+ .unwrap((TemplateModel) arguments.get(1));
+ final ArtifactModel<?> firstModel = CqCatalog.findFirstSchemeModel(model, models);
+ return camelBitLink(firstModel);
+ }
+ }
+
+ private String camelBitLink(ArtifactModel<?> model) {
+ model = CqCatalog.toCamelDocsModel(model);
+ final String kind = model.getKind();
+ return "https://camel.apache.org/components/latest/" + (!"component".equals(kind) ? kind + "s/" : "")
+ + model.getName() + (!"other".equals(kind) ? "-" + kind : "") + ".html";
+ }
+ });
model.put("toAnchor", new TemplateMethodModelEx() {
@Override
public Object exec(List arguments) throws TemplateModelException {
if (arguments.size() != 1) {
- throw new TemplateModelException("Wrong argument count in toCamelCase()");
+ throw new TemplateModelException("Wrong argument count in toAnchor()");
}
String string = String.valueOf(arguments.get(0));
string = Normalizer.normalize(string, Normalizer.Form.NFKC)
@@ -203,7 +230,7 @@ public class UpdateExtensionDocPageMojo extends AbstractDocGeneratorMojo {
} catch (IOException e) {
throw new RuntimeException("Could not create directories " + docPagePath.getParent(), e);
}
- String pageText = "// Do not edit directly!\n// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page\n\n"
+ String pageText = "// Do not edit directly!\n// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page\n"
+ evalTemplate(cfg, template, model, new StringWriter()).toString();
try {
Files.write(docPagePath, pageText.getBytes(charset));
@@ -223,9 +250,10 @@ public class UpdateExtensionDocPageMojo extends AbstractDocGeneratorMojo {
modelClone.put("camelPartTitle", m.getTitle());
modelClone.put("camelPartDescription", m.getDescription());
+ final ArtifactModel<?> camelDocModel = CqCatalog.toCamelDocsModel(m);
final Path docPagePath = multiModuleProjectDirectoryPath
- .resolve("docs/modules/ROOT/pages/reference/" + CqUtils.kindPlural(kind) + "/"
- + ext.getRuntimeArtifactIdBase() + ".adoc");
+ .resolve("docs/modules/ROOT/partials/reference/" + CqUtils.kindPlural(kind) + "/"
+ + camelDocModel.getName() + ".adoc");
evalTemplate(charset, docPagePath, cfg, modelClone, "extensions-camel-bits.adoc");
diff --git a/tooling/maven-plugin/src/main/resources/doc-templates/extension-doc-page.adoc b/tooling/maven-plugin/src/main/resources/doc-templates/extension-doc-page.adoc
index 0ac63d9..9097d76 100644
--- a/tooling/maven-plugin/src/main/resources/doc-templates/extension-doc-page.adoc
+++ b/tooling/maven-plugin/src/main/resources/doc-templates/extension-doc-page.adoc
@@ -18,7 +18,7 @@
== What's inside
[#list models as model]
-* https://camel.apache.org/components/latest/[#if model.kind != "component" ][=model.kind]s/[/#if][=model.name][#if model.kind != "other" ]-[=model.kind][/#if].html[[=model.title][#if model.kind != "other" ] [=humanReadableKind(model.kind)][/#if]][#if model.kind == "component" ], URI syntax: `[=model.syntax]`[/#if]
+* [=camelBitLink(model, models)][[=model.title][#if model.kind != "other" ] [=humanReadableKind(model.kind)][/#if]][#if model.kind == "component" ], URI syntax: `[=model.syntax]`[/#if]
[/#list]
Please refer to the above link[#if models?size != 1]s[/#if] for usage and configuration details.
diff --git a/tooling/maven-plugin/src/main/resources/doc-templates/extensions-camel-bits.adoc b/tooling/maven-plugin/src/main/resources/doc-templates/extensions-camel-bits.adoc
index 5312efd..109fa96 100644
--- a/tooling/maven-plugin/src/main/resources/doc-templates/extensions-camel-bits.adoc
+++ b/tooling/maven-plugin/src/main/resources/doc-templates/extensions-camel-bits.adoc
@@ -1,4 +1,3 @@
-= [=camelPartTitle]
:cq-artifact-id: camel-quarkus-[=artifactIdBase]
:cq-artifact-id-base: [=artifactIdBase]
:cq-native-supported: [=nativeSupported?then('true', 'false')]